[User Interface] IDEA-75238 Microsoft Windows Jump Lists support: WinJumpListBridge project big refactoring.

GitOrigin-RevId: fab9eda6457d2934d1e241c33fe16e3a1aa59831
This commit is contained in:
Nikita Provotorov
2020-11-01 21:02:01 +07:00
committed by intellij-monorepo-bot
parent 20b41882b8
commit 685b62e435
31 changed files with 258 additions and 613 deletions

View File

@@ -1,86 +0,0 @@
# Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
# TODO: split to a separate JumpList static library and the jumplistbridge DLL.
add_library(jumplistbridge SHARED
"winapi.h"
"wide_string.h"
"COM_errors.h"
"COM_errors.cpp"
"COM_guard.h"
"COM_guard.cpp"
"COM_is_initialized.h"
"jump_task.h"
"jump_task.cpp"
"jump_item.h"
"jump_item.cpp"
"jump_list.h"
"jump_list.cpp"
"app_user_model_id.h"
"application.h"
"application.cpp"
"com_intellij_ui_win_RecentTasks.h"
"com_intellij_ui_win_RecentTasks.cpp"
"dllmain.cpp"
)
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set_target_properties(jumplistbridge PROPERTIES
OUTPUT_NAME "jumplistbridge64"
)
else()
set_target_properties(jumplistbridge PROPERTIES
OUTPUT_NAME "jumplistbridge"
)
endif()
include("${PROJECT_SOURCE_DIR}/src/build/EnableCompilerExtraWarnings.cmake")
enable_target_compile_extra_warnings(jumplistbridge)
target_include_directories(jumplistbridge
PRIVATE "${JDK_PATH}/include"
PRIVATE "${JDK_PATH}/include/win32"
)
target_link_libraries(jumplistbridge
Shell32.lib
)
# TODO: insert copyrights to DLL->Properties->Details
# jumplisttests
# TODO: remove this target
add_executable(jumplisttests
"winapi.h"
"wide_string.h"
"COM_errors.h"
"COM_errors.cpp"
"COM_guard.h"
"COM_guard.cpp"
"COM_is_initialized.h"
"jump_task.h"
"jump_task.cpp"
"jump_item.h"
"jump_item.cpp"
"jump_list.h"
"jump_list.cpp"
"app_user_model_id.h"
"application.h"
"application.cpp"
"testsmain.cpp"
)
enable_target_compile_extra_warnings(jumplisttests)
target_link_libraries(jumplisttests
Shell32.lib
)
# TODO: remove the registry entries:
# 1. Computer\HKEY_CLASSES_ROOT\Applications\jumplisttests.exe

View File

@@ -1,401 +0,0 @@
#include "COM_guard.h" // COMGuard
#include "COM_errors.h"
#include "jump_task.h"
#include "jump_item.h"
#include "jump_list.h"
#include "application.h"
#include <iostream> // std::clog
#include <cassert> // assert
namespace ui = intellij::ui::win;
int main(/*int argc, char* argv[]*/)
{
std::string s;
try
{
const ui::COMGuard comInitializer{
COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY // NOLINT
};
std::cout << "Press Enter to initialize an Application:" << std::flush;
std::getline(std::cin, s);
std::clog << "Initializing an Application..." << std::endl;
ui::Application::getInstance();
std::wclog << L"Application has been initialized successfully. Id: \""
<< ui::Application::getInstance().obtainAppUserModelId().value_or(L"nullopt")
<< L"\"\n" << std::endl;
std::cout << "Press Enter to remove the Jump List:" << std::flush;
std::getline(std::cin, s);
std::clog << "Removing the Jump List..." << std::endl;
ui::Application::getInstance().deleteJumpList(ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
std::clog << "The Jump List has been removed successfully.\n" << std::endl;
std::cout << "Press Enter to clear the Recents:" << std::flush;
std::getline(std::cin, s);
std::clog << "Clearing the Recents..." << std::endl;
ui::Application::getInstance().clearRecentsAndFrequents(ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
std::clog << "The Recents category has been cleared successfully.\n" << std::endl;
std::cout << "Press Enter to create User's \"Tasks\":" << std::flush;
std::getline(std::cin, s);
std::clog << "Creating User's \"Tasks\"..." << std::endl;
auto userJumpTask1 =
ui::JumpTask::startBuilding(L"C:\\Separated\\Soft\\JetBrains\\IntellijIDEA203.4449.2\\bin\\idea64.exe",
L"Open Intellij IDEA")
//.setApplicationArguments(L"")
.setDescription(L"Run IDEA 64-bit launcher")
.buildTask(ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
auto userJumpTask2 =
ui::JumpTask::startBuilding(L"notepad.exe",
L"Open MyDocument.txt")
.setApplicationWorkingDirectory(L"C:\\Separated")
.setApplicationArguments(L"MyDocument.txt")
.setDescription(L"Open MyDocument.txt via notepad.exe")
.buildTask(ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
std::clog << "User's \"Tasks\" have been created successfully.\n" << std::endl;
std::cout << "Press Enter to create tasks for custom categories:" << std::flush;
std::getline(std::cin, s);
std::clog << "Creating tasks for Custom Category 1..." << std::endl;
auto cc1task1 =
ui::JumpTask::startBuilding(L"explorer.exe",
L"Program Files x86")
.setApplicationArguments(L"\"C:\\Program Files (x86)\"")
.setDescription(L"Open Program Files x86")
.buildTask(ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
auto cc1task2 =
ui::JumpTask::startBuilding(L"explorer.exe",
L"Program Files")
.setApplicationArguments(L"\"C:\\Program Files\"")
.setDescription(L"Open Program Files")
.buildTask(ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
std::clog << "The tasks for Custom Category 1 have been created successfully.\n" << std::endl;
std::clog << "Creating tasks for Custom Category 2..." << std::endl;
auto cc2task1 =
ui::JumpTask::startBuilding(L"explorer.exe",
L"Windows")
.setApplicationArguments(L"\"C:\\Windows\\\"")
.setDescription(L"Open Windows")
.buildTask(ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
auto cc2task2 =
ui::JumpTask::startBuilding(L"explorer.exe",
L"Users")
.setApplicationArguments(L"\"C:\\Users\"")
.setDescription(L"Open Users")
.buildTask(ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
std::clog << "The tasks for Custom Category 2 have been created successfully.\n" << std::endl;
std::cout << "Press Enter to create a JumpList:" << std::flush;
std::getline(std::cin, s);
std::clog << "Creating a JumpList..." << std::endl;
ui::JumpList jumpList;
jumpList.setRecentCategoryVisible(true);
jumpList.setFrequentCategoryVisible(false);
jumpList.appendToUserTasks(std::move(userJumpTask1), ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
jumpList.appendToUserTasks(std::move(userJumpTask2), ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
jumpList.appendToCustomCategory(L"Custom Category 1", std::move(cc1task1), ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
jumpList.appendToCustomCategory(L"Custom Category 1", std::move(cc1task2), ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
jumpList.appendToCustomCategory(L"Custom Category 2", std::move(cc2task1), ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
jumpList.appendToCustomCategory(L"Custom Category 2", std::move(cc2task2), ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
std::clog << "JumpList has been created successfully.\n" << std::endl;
std::cout << "Press Enter to set the JumpList to the Application:" << std::flush;
std::getline(std::cin, s);
std::clog << "Setting the JumpList to the Application..." << std::endl;
ui::Application::getInstance().setJumpList(jumpList, ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
std::clog << "The JumpList has been set to the Application successfully.\n" << std::endl;
std::cout << "Press Enter to set Recent documents:" << std::flush;
std::getline(std::cin, s);
std::clog << "Setting Recent documents..." << std::endl;
ui::Application::getInstance().registerRecentlyUsed(L"C:\\Separated\\MyDocument3.txt");
ui::Application::getInstance().registerRecentlyUsed(L"C:\\Separated\\MyDocument4.txt");
ui::Application::getInstance().registerRecentlyUsed(L"C:\\Separated\\MyDocument5.txt");
std::clog << "Recent documents have been set successfully.\n" << std::endl;
std::cout << "Press Enter to remove the Jump List:" << std::flush;
std::getline(std::cin, s);
std::clog << "Removing the Jump List..." << std::endl;
ui::Application::getInstance().deleteJumpList(ui::COM_IS_INITIALIZED_IN_THIS_THREAD);
std::clog << "The Jump List has been removed successfully.\n" << std::endl;
}
catch(const std::system_error& err)
{
std::cerr << "Caught std::system_error with code " << err.code()
<< " meaning \"" << err.what() << "\"\n" << std::endl;
}
catch (const std::exception& err)
{
std::cerr << err.what() << "\n" << std::endl;
}
std::cout << "Press Enter to exit:" << std::flush;
std::getline(std::cin, s);
return 0;
}
#if 0
// HelloWindowsDesktop.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c
#include <windows.h>
#include <cstdlib>
#include <cstring>
#include <tchar.h>
// Global variables
// The main window class name.
static TCHAR szWindowClass[] = _T("DesktopApp");
// The string that appears in the application's title bar.
static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application");
HINSTANCE hInst;
// Forward declarations of functions included in this code module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int CALLBACK WinMain(
[[maybe_unused]] _In_ HINSTANCE hInstance,
[[maybe_unused]] _In_opt_ HINSTANCE hPrevInstance,
[[maybe_unused]] _In_ LPSTR lpCmdLine,
[[maybe_unused]] _In_ int nCmdShow)
{
try
{
const auto comInitializer = ui::COMGuard(
COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY // NOLINT
);
std::clog << "Initializing an Application..." << std::endl;
ui::Application::getInstance();
std::wclog << L"Application has been initialized successfully. Id: \""
<< ui::Application::getInstance().obtainAppUserModelId().value_or(L"nullopt")
<< L"\"\n" << std::endl;
std::clog << "Removing the Jump List..." << std::endl;
ui::Application::getInstance().deleteJumpList();
std::clog << "The Jump List has been removed successfully.\n" << std::endl;
std::clog << "Clearing the Recents..." << std::endl;
ui::Application::getInstance().clearRecentsAndFrequents();
std::clog << "The Recents category has been cleared successfully.\n" << std::endl;
std::clog << "Creating User's \"Tasks\"..." << std::endl;
auto userJumpTask1 = ui::JumpTask::Builder{
comInitializer,
L"C:\\Separated\\Soft\\JetBrains\\IntellijIDEA203.4449.2\\bin\\idea64.exe",
L"Open Intellij IDEA"
}
//.setTasksApplicationArguments(L"")
.setTasksDescription(L"Run IDEA 64-bit launcher")
.buildTask();
auto userJumpTask2 = ui::JumpTask::Builder{
comInitializer,
L"notepad.exe",
L"Open MyDocument.txt"
}
.setTasksApplicationWorkingDirectory(L"C:\\Separated")
.setTasksApplicationArguments(L"MyDocument.txt")
.setTasksDescription(L"Open MyDocument.txt via notepad.exe")
.buildTask();
std::clog << "User's \"Tasks\" have been created successfully.\n" << std::endl;
std::clog << "Creating a JumpList..." << std::endl;
ui::JumpList jumpList;
jumpList.setRecentCategoryVisible(false);
jumpList.appendToUserTasks(std::move(userJumpTask1));
jumpList.appendToUserTasks(std::move(userJumpTask2));
std::clog << "JumpList has been created successfully.\n" << std::endl;
std::clog << "Setting the JumpList to the Application..." << std::endl;
ui::Application::getInstance().setJumpList(jumpList);
std::clog << "The JumpList has been set to the Application successfully.\n" << std::endl;
std::clog << "Setting Recents documents..." << std::endl;
ui::Application::getInstance().registerRecentlyUsed(L"C:\\Separated\\MyDocument3.txt");
ui::Application::getInstance().registerRecentlyUsed(L"C:\\Separated\\MyDocument4.txt");
ui::Application::getInstance().registerRecentlyUsed(L"C:\\Separated\\MyDocument5.txt");
std::clog << "Recents documents have been set successfully.\n" << std::endl;
// std::clog << "Removing the Jump List..." << std::endl;
// ui::Application::getInstance().deleteJumpList();
// std::clog << "The Jump List has been removed successfully.\n" << std::endl;
// std::cout << "Press Enter to create Recents JumpItems:" << std::flush;
// std::getline(std::cin, s);
//
// std::clog << "Creating Recents JumpItems..." << std::endl;
// ui::JumpItem recentJumpItem1("C:\\Separated\\MyDocument2.txt");
// std::clog << "Recent JumpItems have been created successfully.\n" << std::endl;
//
//
// std::cout << "Press Enter to set Recents JumpItems:" << std::flush;
// std::getline(std::cin, s);
//
// std::clog << "Setting Recents JumpItems..." << std::endl;
// ui::Application::getInstance().registerRecentlyUsed(recentJumpItem1);
// std::clog << "Recents JumpItems have been set successfully.\n" << std::endl;
}
catch(const std::system_error& err)
{
std::cerr << "Caught std::system_error with code " << err.code()
<< " meaning \"" << err.what() << "\"\n" << std::endl;
}
catch (const std::exception& err)
{
std::cerr << err.what() << "\n" << std::endl;
}
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,
_T("Call to RegisterClassEx failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
// Store instance handle in our global variable
hInst = hInstance;
// The parameters to CreateWindow explained:
// szWindowClass: the name of the application
// szTitle: the text that appears in the title bar
// WS_OVERLAPPEDWINDOW: the type of window to create
// CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
// 500, 100: initial size (width, length)
// NULL: the parent of this window
// NULL: this application does not have a menu bar
// hInstance: the first parameter from WinMain
// NULL: not used in this application
HWND hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
500, 100,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd)
{
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
// The parameters to ShowWindow explained:
// hWnd: the value returned from CreateWindow
// nCmdShow: the fourth parameter from WinMain
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Main message loop:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello, Windows desktop!");
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// Here your application is laid out.
// For this introduction, we just print out "Hello, Windows desktop!"
// in the top left corner.
TextOut(hdc,
5, 5,
greeting, static_cast<int>(_tcslen(greeting)));
// End application-specific layout section.
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
#endif // 0

View File

@@ -1,46 +0,0 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/**
* Encapsulation of all WinAPI headers used by the project.
*
* @author Nikita Provotorov
*/
// TODO: make all defines in CMake
#ifndef WINJUMPLISTBRIDGE_WINAPI_H
#define WINJUMPLISTBRIDGE_WINAPI_H
// Force Unicode version of WinAPI.
// It is necessary for:
// * fixing of WinAPI SHARDAPPIDINFOLINK structure.
#ifndef UNICODE
#define UNICODE
#endif // ndef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif // ndef _UNICODE
// Exclude rarely-used stuff from Windows headers
#define WIN32_LEAN_AND_MEAN
// Make the project supports Windows 8 and later.
// See https://docs.microsoft.com/ru-ru/cpp/porting/modifying-winver-and-win32-winnt for more info.
#include <WinSDKVer.h>
#undef WINVER
#define WINVER 0x0602 // 0x0602 is Windows 8
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0602 // 0x0602 is Windows 8
#include <sdkddkver.h>
// Used WinAPI headers
#include <Windows.h>
#include <Shobjidl.h> // COM
#include <Shlobj.h> // SHAddToRecentDocs, SHCreateItemFromParsingName ; to link with Shell32.lib
#include <propsys.h> // IPropertyStore
#include <Propidl.h> // PROPVARIANT
#include <propkey.h> // PKEY_Title
#include <propvarutil.h> // InitPropVariantFromString
#include <atlbase.h> // CComPtr
#endif // ndef WINJUMPLISTBRIDGE_WINAPI_H

View File

@@ -4,21 +4,16 @@ if (NOT WIN32)
message(FATAL_ERROR "This project is intended for Windows only.")
endif()
if (NOT JDK_PATH)
message(FATAL_ERROR "Path to the JDK is not specified.")
endif()
cmake_minimum_required(VERSION 3.15) # 3.15 is required for the CMP0092 policy
project(WinJumpListBridge CXX)
project(WinShellIntegration CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
#include_directories("include")
add_subdirectory("src/jumplistbridge")
add_subdirectory("src/winshellintegration")
add_subdirectory("src/winshellintegrationbridge")
#enable_testing()
#add_subdirectory("tests")

View File

@@ -1,4 +1,4 @@
# WinJumpListBridge
# WinShellIntegration
This project based on the [origin jumplistbridge project](https://github.com/JetBrains/intellij-community/tree/4635352640ed54ef9379082171f33837d099ebb8/native/jumplistbridge)
by Denis Fokin.
@@ -8,13 +8,16 @@ TODO: description
## Build dependencies
* C++17-compatible compiler
* [CMake](https://cmake.org/download/) >= `v3.15` (Note: it is already shipped with CLion)
* An implementation of Java SE 11 or newer. It's highly recommended to use the JDK you are using to build IDEA;
* [Optional for building [winshellintegrationbridge](src/winshellintegrationbridge) target]:
An implementation of Java SE 11 or newer. It's highly recommended to use the JDK you are using to build IDEA;
## Build
1. You have to set the variable `JDK_PATH` to the path of JDK which will be used for build.
Just use CMake normally.
If you want to build [winshellintegrationbridge](src/winshellintegrationbridge) target too
you have to set the variable `JDK_PATH` to the path of JDK which will be used for build.
For example if your `javac.exe` is located at `C:\Soft\jdk\bin\javac.exe` you should set the variable like
`-DJDK_PATH="C:\Soft\jdk"`
2.
`-DJDK_PATH="C:\Soft\jdk"`.
## Integration with CLion
TODO: description

View File

@@ -0,0 +1,57 @@
# Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
add_library(winshellintegration STATIC
"include/winshellintegration.h"
"include/winshellintegration/winapi.h"
"include/winshellintegration/wide_string.h"
"include/winshellintegration/COM_errors.h"
"src/COM_errors.cpp"
"include/winshellintegration/COM_is_initialized.h"
"include/winshellintegration/jump_task.h"
"src/jump_task.cpp"
"include/winshellintegration/jump_item.h"
"src/jump_item.cpp"
"include/winshellintegration/jump_list.h"
"src/jump_list.cpp"
"include/winshellintegration/app_user_model_id.h"
"include/winshellintegration/application.h"
"src/application.cpp"
)
target_include_directories(winshellintegration
PUBLIC "include"
)
target_link_libraries(winshellintegration
PUBLIC "shell32.lib"
)
target_compile_definitions(winshellintegration
# Force Unicode version of WinAPI.
# It is necessary for:
# * fixing of WinAPI SHARDAPPIDINFOLINK structure.
PUBLIC UNICODE
PUBLIC _UNICODE
# Exclude rarely-used stuff from Windows headers
PRIVATE WIN32_LEAN_AND_MEAN
# Make the project supports Windows 8 and later.
# See https://docs.microsoft.com/ru-ru/cpp/porting/modifying-winver-and-win32-winnt for more info.
# 0x0602 is the identifier of Windows 8
PUBLIC WINSHELLINTEGRATION_WINVER=0x0602
PUBLIC WINVER=WINSHELLINTEGRATION_WINVER
PUBLIC _WIN32_WINNT=WINSHELLINTEGRATION_WINVER
)
include("${PROJECT_SOURCE_DIR}/src/build/EnableCompilerExtraWarnings.cmake")
enable_target_compile_extra_warnings(winshellintegration)

View File

@@ -0,0 +1,16 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#ifndef WINSHELLINTEGRATION_WINSHELLINTEGRATION_H
#define WINSHELLINTEGRATION_WINSHELLINTEGRATION_H
#include "winshellintegration/winapi.h"
#include "winshellintegration/wide_string.h"
#include "winshellintegration/COM_errors.h"
#include "winshellintegration/COM_is_initialized.h"
#include "winshellintegration/jump_task.h"
#include "winshellintegration/jump_item.h"
#include "winshellintegration/jump_list.h"
#include "winshellintegration/app_user_model_id.h"
#include "winshellintegration/application.h"
#endif // ndef WINSHELLINTEGRATION_WINSHELLINTEGRATION_H

View File

@@ -16,8 +16,8 @@
* @author Nikita Provotorov
*/
#ifndef WINJUMPLISTBRIDGE_COM_ERRORS_H
#define WINJUMPLISTBRIDGE_COM_ERRORS_H
#ifndef WINSHELLINTEGRATION_COM_ERRORS_H
#define WINSHELLINTEGRATION_COM_ERRORS_H
#include "winapi.h" // HRESULT
#include <system_error> // std::error_code, std::error_category, std::is_error_code_enum
@@ -79,4 +79,4 @@ template<>
struct std::is_error_code_enum<intellij::ui::win::errors::COMResultHandle> : std::true_type {};
#endif // ndef WINJUMPLISTBRIDGE_COM_ERRORS_H
#endif // ndef WINSHELLINTEGRATION_COM_ERRORS_H

View File

@@ -9,8 +9,8 @@
* @author Nikita Provotorov
*/
#ifndef WINJUMPLISTBRIDGE_COM_IS_INITIALIZED_H
#define WINJUMPLISTBRIDGE_COM_IS_INITIALIZED_H
#ifndef WINSHELLINTEGRATION_COM_IS_INITIALIZED_H
#define WINSHELLINTEGRATION_COM_IS_INITIALIZED_H
namespace intellij::ui::win
@@ -26,4 +26,4 @@ namespace intellij::ui::win
} // namespace intellij::ui::win
#endif // ndef WINJUMPLISTBRIDGE_COM_IS_INITIALIZED_H
#endif // ndef WINSHELLINTEGRATION_COM_IS_INITIALIZED_H

View File

@@ -1,7 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#ifndef WINJUMPLISTBRIDGE_APP_USER_MODEL_ID_H
#define WINJUMPLISTBRIDGE_APP_USER_MODEL_ID_H
#ifndef WINSHELLINTEGRATION_APP_USER_MODEL_ID_H
#define WINSHELLINTEGRATION_APP_USER_MODEL_ID_H
#include "wide_string.h"
@@ -13,4 +13,4 @@ namespace intellij::ui::win
} // namespace intellij::ui::win
#endif // ndef WINJUMPLISTBRIDGE_APP_USER_MODEL_ID_H
#endif // ndef WINSHELLINTEGRATION_APP_USER_MODEL_ID_H

View File

@@ -8,8 +8,8 @@
* @author Nikita Provotorov
*/
#ifndef WINJUMPLISTBRIDGE_APPLICATION_H
#define WINJUMPLISTBRIDGE_APPLICATION_H
#ifndef WINSHELLINTEGRATION_APPLICATION_H
#define WINSHELLINTEGRATION_APPLICATION_H
#include "app_user_model_id.h" // AppUserModelId
#include "COM_is_initialized.h" // COMIsInitializedInThisThreadTag
@@ -149,4 +149,4 @@ namespace intellij::ui::win
} // namespace intellij::ui::win
#endif // ndef WINJUMPLISTBRIDGE_APPLICATION_H
#endif // ndef WINSHELLINTEGRATION_APPLICATION_H

View File

@@ -8,8 +8,8 @@
* @author Nikita Provotorov
*/
#ifndef WINJUMPLISTBRIDGE_JUMPITEM_H
#define WINJUMPLISTBRIDGE_JUMPITEM_H
#ifndef WINSHELLINTEGRATION_JUMPITEM_H
#define WINSHELLINTEGRATION_JUMPITEM_H
#include "winapi.h" // IShellItemW, CComPtr
#include "COM_is_initialized.h" // COMIsInitializedInThisThreadTag
@@ -55,4 +55,4 @@ namespace intellij::ui::win
} // namespace intellij::ui::win
#endif // ndef WINJUMPLISTBRIDGE_JUMPITEM_H
#endif // ndef WINSHELLINTEGRATION_JUMPITEM_H

View File

@@ -8,8 +8,8 @@
* @author Nikita Provotorov
*/
#ifndef WINJUMPLISTBRIDGE_JUMPLIST_H
#define WINJUMPLISTBRIDGE_JUMPLIST_H
#ifndef WINSHELLINTEGRATION_JUMPLIST_H
#define WINSHELLINTEGRATION_JUMPLIST_H
#include "jump_task.h" // JumpTask
#include "jump_item.h" // JumpItem
@@ -122,4 +122,4 @@ namespace intellij::ui::win
} // namespace intellij::ui::win
#endif // ndef WINJUMPLISTBRIDGE_JUMPLIST_H
#endif // ndef WINSHELLINTEGRATION_JUMPLIST_H

View File

@@ -8,8 +8,8 @@
* @author Nikita Provotorov
*/
#ifndef WINJUMPLISTBRIDGE_JUMPTASK_H
#define WINJUMPLISTBRIDGE_JUMPTASK_H
#ifndef WINSHELLINTEGRATION_JUMPTASK_H
#define WINSHELLINTEGRATION_JUMPTASK_H
#include "winapi.h" // IShellLinkW, CComPtr
#include "COM_is_initialized.h" // COMIsInitializedInThisThreadTag
@@ -170,4 +170,4 @@ namespace intellij::ui::win
} // namespace intellij::ui::win
#endif // ndef WINJUMPLISTBRIDGE_JUMPTASK_H
#endif // ndef WINSHELLINTEGRATION_JUMPTASK_H

View File

@@ -1,7 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#ifndef WINJUMPLISTBRIDGE_WIDE_STRING_H
#define WINJUMPLISTBRIDGE_WIDE_STRING_H
#ifndef WINSHELLINTEGRATION_WIDE_STRING_H
#define WINSHELLINTEGRATION_WIDE_STRING_H
#include "winapi.h" // WCHAR
#include <string> // std::basic_string
@@ -17,4 +17,4 @@ namespace intellij::ui::win
} // namespace intellij::ui::win
#endif // ndef WINJUMPLISTBRIDGE_WIDE_STRING_H
#endif // ndef WINSHELLINTEGRATION_WIDE_STRING_H

View File

@@ -0,0 +1,64 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
/**
* All WinAPI headers used by the project.
*
* @author Nikita Provotorov
*/
// TODO: make all defines in CMake
#ifndef WINSHELLINTEGRATION_WINAPI_H
#define WINSHELLINTEGRATION_WINAPI_H
// Force Unicode version of WinAPI.
// It is necessary for:
// * fix WinAPI SHARDAPPIDINFOLINK structure.
#ifndef UNICODE
#define UNICODE
#endif // ndef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif // ndef _UNICODE
// Exclude rarely-used stuff from Windows headers
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // ndef WIN32_LEAN_AND_MEAN
// Make the project supports Windows 8 and later.
// See https://docs.microsoft.com/ru-ru/cpp/porting/modifying-winver-and-win32-winnt for more info.
#ifndef WINSHELLINTEGRATION_WINVER
#define WINSHELLINTEGRATION_WINVER 0x0602 // 0x0602 is the identifier of Windows 8
#endif // ndef WINSHELLINTEGRATION_WINVER
#include <WinSDKVer.h>
#ifndef WINVER
#define WINVER WINSHELLINTEGRATION_WINVER
#endif // ndef WINVER
#if (WINVER < WINSHELLINTEGRATION_WINVER)
#error "WINVER define is too small. Only 0x0602 (Windows 8) or greater are supported"
#endif // (WINVER < WINSHELLINTEGRATION_WINVER)
#ifndef _WIN32_WINNT
#define _WIN32_WINNT WINSHELLINTEGRATION_WINVER
#endif // ndef _WIN32_WINNT
#if (_WIN32_WINNT < WINSHELLINTEGRATION_WINVER)
#error "_WIN32_WINNT define is too small. Only 0x0602 (Windows 8) or greater are supported"
#endif // (_WIN32_WINNT < WINSHELLINTEGRATION_WINVER)
#include <sdkddkver.h>
// Used WinAPI headers
#include <Windows.h>
#include <Shobjidl.h> // COM
#include <Shlobj.h> // SHAddToRecentDocs, SHCreateItemFromParsingName ; to link with Shell32.lib
#include <propsys.h> // IPropertyStore
#include <Propidl.h> // PROPVARIANT
#include <propkey.h> // PKEY_Title
#include <propvarutil.h> // InitPropVariantFromString
#include <atlbase.h> // CComPtr
#endif // ndef WINSHELLINTEGRATION_WINAPI_H

View File

@@ -1,10 +1,10 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#include "COM_errors.h"
#include <string> // std::string
#include <array> // std::array
#include <charconv> // std::to_chars
#include <utility> // std::move
#include "winshellintegration/COM_errors.h"
#include <string> // std::string
#include <array> // std::array
#include <charconv> // std::to_chars
#include <utility> // std::move
namespace intellij::ui::win::errors

View File

@@ -1,19 +1,19 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#include "application.h"
#include "winapi.h" // SetCurrentProcessExplicitAppUserModelID,
// GetCurrentProcessExplicitAppUserModelID,
// COM,
// Shell
#include "winshellintegration/application.h"
#include "winshellintegration/winapi.h" // SetCurrentProcessExplicitAppUserModelID,
// GetCurrentProcessExplicitAppUserModelID,
// COM,
// Shell
#include "COM_errors.h" // errors::throwCOMException
#include "jump_item.h" // JumpItem
#include "jump_task.h" // JumpTask
#include "jump_list.h" // JumpList
#include <string_view> // std::string_view
#include <exception> // std::uncaught_exceptions
#include <stdexcept> // std::logic_error
#include <cassert> // assert
#include "winshellintegration/COM_errors.h" // errors::throwCOMException
#include "winshellintegration/jump_item.h" // JumpItem
#include "winshellintegration/jump_task.h" // JumpTask
#include "winshellintegration/jump_list.h" // JumpList
#include <string_view> // std::string_view
#include <exception> // std::uncaught_exceptions
#include <stdexcept> // std::logic_error
#include <cassert> // assert
namespace intellij::ui::win

View File

@@ -1,7 +1,7 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#include "jump_item.h"
#include "COM_errors.h" // errors::throwCOMException
#include "winshellintegration/jump_item.h"
#include "winshellintegration/COM_errors.h" // errors::throwCOMException
namespace intellij::ui::win

View File

@@ -1,6 +1,6 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#include "jump_list.h"
#include "winshellintegration/jump_list.h"
namespace intellij::ui::win

View File

@@ -1,10 +1,10 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#include "jump_task.h"
#include "COM_errors.h" // errors::throwCOMException
#include <string_view> // std::string_view
#include <type_traits> // std::is_same_v
#include <cassert> // assert
#include "winshellintegration/jump_task.h"
#include "winshellintegration/COM_errors.h" // errors::throwCOMException
#include <string_view> // std::string_view
#include <type_traits> // std::is_same_v
#include <cassert> // assert
namespace intellij::ui::win

View File

@@ -0,0 +1,40 @@
# Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
if (NOT JDK_PATH)
message(SEND_ERROR "Path to the JDK is not specified. winshellintegrationbridge target will not be generated.")
endif()
add_library(winshellintegrationbridge SHARED
"COM_guard.h"
"COM_guard.cpp"
"com_intellij_ui_win_RecentTasks.h"
"com_intellij_ui_win_RecentTasks.cpp"
"dllmain.cpp"
)
target_include_directories(winshellintegrationbridge
PRIVATE "${JDK_PATH}/include"
PRIVATE "${JDK_PATH}/include/win32"
)
target_link_libraries(winshellintegrationbridge
PRIVATE "winshellintegration"
PRIVATE "Ole32.lib"
)
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set_target_properties(winshellintegrationbridge PROPERTIES
OUTPUT_NAME "winshellintegrationbridge64"
)
else()
set_target_properties(winshellintegrationbridge PROPERTIES
OUTPUT_NAME "winshellintegrationbridge"
)
endif()
include("${PROJECT_SOURCE_DIR}/src/build/EnableCompilerExtraWarnings.cmake")
enable_target_compile_extra_warnings(winshellintegrationbridge)
# TODO: insert copyrights to DLL->Properties->Details

View File

@@ -1,7 +1,8 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#include "COM_guard.h"
#include "COM_errors.h" // errors::throwCOMException
#include "winshellintegration/COM_errors.h" // errors::throwCOMException
#include <Objbase.h> // CoInitializeEx, CoUninitialize
namespace intellij::ui::win
{

View File

@@ -6,11 +6,14 @@
* @author Nikita Provotorov
*/
#ifndef WINJUMPLISTBRIDGE_COM_GUARD_H
#define WINJUMPLISTBRIDGE_COM_GUARD_H
#ifndef WINSHELLINTEGRATIONBRIDGE_COM_GUARD_H
#define WINSHELLINTEGRATIONBRIDGE_COM_GUARD_H
#include "winapi.h" // DWORD, CoInitializeEx, CoUninitialize
#include <memory> // std::shared_ptr
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // ndef WIN32_LEAN_AND_MEAN
#include <Windows.h> // DWORD
#include <memory> // std::shared_ptr
namespace intellij::ui::win
@@ -49,4 +52,4 @@ namespace intellij::ui::win
} // namespace intellij::ui::win
#endif // ndef WINJUMPLISTBRIDGE_COM_GUARD_H
#endif // ndef WINSHELLINTEGRATIONBRIDGE_COM_GUARD_H

View File

@@ -7,17 +7,16 @@
*/
#include "com_intellij_ui_win_RecentTasks.h"
#include "COM_guard.h" // intellij::ui::win::COMGuard
#include "jump_list.h" // intellij::ui::win::JumpList
#include "application.h" // intellij::ui::win::Application
#include <string_view> // std::string_view
#include <thread> // std::thread::id
#include <stdexcept> // std::system_error, std::runtime_error, std::logic_error, std::exception
#include <optional> // std::optional
#include <vector> // std::vector
#include <sstream> // std::stringstream
#include <type_traits> // std::decay_t, std::is_base_of
#include <cassert> // assert
#include "COM_guard.h" // COMGuard
#include "winshellintegration.h" // intellij::ui::win::*
#include <string_view> // std::string_view
#include <thread> // std::thread::id
#include <stdexcept> // std::system_error, std::runtime_error, std::logic_error, std::exception
#include <optional> // std::optional
#include <vector> // std::vector
#include <sstream> // std::stringstream
#include <type_traits> // std::decay_t, std::is_base_of
#include <cassert> // assert
namespace intellij::ui::win::jni