mirror of
https://github.com/reactos/reactos.git
synced 2026-10-03 16:21:54 +08:00
[EXPLORER] Implement Win+<number> hotkeys (#9555)
This commit implements Win+<number>, Win+Shift+<number>, Win+Shift+Ctrl+<number> and Win+Alt+<number> hotkeys. These hotkeys activate Nth task on the taskbar. CORE-20781
This commit is contained in:
committed by
GitHub
parent
1fd8b503be
commit
00a09fd24a
@@ -36,5 +36,6 @@ add_executable(explorer ${SOURCE} explorer.rc)
|
||||
target_link_libraries(explorer uuid wine cpprt atl_classes)
|
||||
set_module_type(explorer win32gui UNICODE)
|
||||
add_importlibs(explorer setupapi advapi32 gdi32 user32 comctl32 ole32 oleaut32 shell32 browseui shlwapi shdocvw version uxtheme msvcrt kernel32 ntdll)
|
||||
add_delay_importlibs(explorer psapi)
|
||||
add_pch(explorer precomp.h SOURCE)
|
||||
add_cd_file(TARGET explorer DESTINATION reactos FOR all)
|
||||
|
||||
@@ -395,6 +395,7 @@ HRESULT CSysPagerWnd_CreateInstance(HWND hwndParent, REFIID riid, void **ppv);
|
||||
*/
|
||||
|
||||
#define TSWM_UPDATETASKBARPOS (WM_USER + 2)
|
||||
#define TSWM_ACTIVATETASKINDEX (WM_USER + 88)
|
||||
|
||||
HRESULT CTaskSwitchWnd_CreateInstance(IN HWND hWndParent, IN OUT ITrayWindow *Tray, REFIID riid, void **ppv);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <commoncontrols.h>
|
||||
#include <regstr.h>
|
||||
#include <shlwapi_undoc.h>
|
||||
#include <psapi.h>
|
||||
|
||||
/* Set DUMP_TASKS to 1 to enable a dump of the tasks and task groups every
|
||||
5 seconds */
|
||||
@@ -101,6 +102,23 @@ SHELL_IsRudeWindow(_In_opt_ HMONITOR hMonitor, _In_ HWND hWnd, _In_ BOOL bDontCh
|
||||
return ::EqualRect(&rcUnion, &rcWnd) && (bDontCheckActive || SHELL_IsRudeWindowActive(hWnd));
|
||||
}
|
||||
|
||||
static BOOL
|
||||
SHELL_GetImageFileNameByWindow(_In_ HWND hWnd, _Out_cap_(cchPath) LPWSTR pszPath, _In_ DWORD cchPath)
|
||||
{
|
||||
DWORD dwProcessId;
|
||||
HANDLE hProcess;
|
||||
BOOL bSuccess;
|
||||
if (GetWindowThreadProcessId(hWnd, &dwProcessId) == 0)
|
||||
return FALSE;
|
||||
// TODO: Switch to PROCESS_QUERY_LIMITED_INFORMATION once NT6 kernel32 support is implemented.
|
||||
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId);
|
||||
if (hProcess == NULL)
|
||||
return FALSE;
|
||||
bSuccess = GetModuleFileNameExW(hProcess, NULL, pszPath, cchPath) != 0;
|
||||
CloseHandle(hProcess);
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
const WCHAR szTaskSwitchWndClass[] = L"MSTaskSwWClass";
|
||||
@@ -2096,6 +2114,72 @@ public:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT OnActivateTaskIndex(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
DWORD dwAccelerators = HIWORD(wParam);
|
||||
WCHAR szExecutablePath[MAX_PATH];
|
||||
|
||||
PTASK_ITEM pTaskItem = FindTaskItemByIndex(LOWORD(wParam));
|
||||
if (pTaskItem && ::IsWindow(pTaskItem->hWnd))
|
||||
{
|
||||
// Win+Shift: New instance
|
||||
if ((dwAccelerators & MOD_SHIFT) == MOD_SHIFT)
|
||||
{
|
||||
if (!SHELL_GetImageFileNameByWindow(pTaskItem->hWnd,
|
||||
szExecutablePath,
|
||||
_countof(szExecutablePath)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// Win+Shift+Ctrl is used for creating a new instance of a task as Administrator
|
||||
LPCWSTR szVerb = L"open";
|
||||
if ((dwAccelerators & MOD_CONTROL) == MOD_CONTROL)
|
||||
szVerb = L"runas";
|
||||
ShellExecuteW(NULL, szVerb, szExecutablePath, NULL, NULL, SW_SHOWNORMAL);
|
||||
return TRUE;
|
||||
}
|
||||
// Win+Alt: Jump list
|
||||
else if ((dwAccelerators & MOD_ALT) == MOD_ALT)
|
||||
{
|
||||
// TODO: Use JumpList once implemented
|
||||
|
||||
// Find TaskItem's position on the screen
|
||||
RECT rcItem, rcToolbar;
|
||||
m_TaskBar.GetItemRect(pTaskItem->Index, &rcItem);
|
||||
m_TaskBar.GetWindowRect(&rcToolbar);
|
||||
OffsetRect(&rcItem, rcToolbar.left, rcToolbar.top);
|
||||
|
||||
::SendMessageCallbackW(pTaskItem->hWnd, WM_POPUPSYSTEMMENU, 0, MAKELPARAM(rcItem.left, rcItem.top),
|
||||
SendAsyncProc, (ULONG_PTR)pTaskItem);
|
||||
}
|
||||
// Win+Ctrl: Switch to last window of a task
|
||||
else if ((dwAccelerators & MOD_CONTROL) == MOD_CONTROL)
|
||||
{
|
||||
// TODO: Implement once Superbar is implemented.
|
||||
return FALSE;
|
||||
}
|
||||
// No modifier: just switch to the task
|
||||
else
|
||||
{
|
||||
// TODO: This should launch a pinned task once Superbar is implemented
|
||||
|
||||
BOOL bIsMinimized = ::IsIconic(pTaskItem->hWnd);
|
||||
BOOL bIsActive = (pTaskItem == m_ActiveTaskItem);
|
||||
|
||||
if (!bIsMinimized && bIsActive)
|
||||
{
|
||||
if (!::IsHungAppWindow(pTaskItem->hWnd))
|
||||
::ShowWindowAsync(pTaskItem->hWnd, SW_MINIMIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
::SwitchToThisWindow(pTaskItem->hWnd, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT OnTaskbarSettingsChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
BOOL bSettingsChanged = FALSE;
|
||||
@@ -2277,6 +2361,7 @@ public:
|
||||
MESSAGE_HANDLER(WM_COMMAND, OnCommand)
|
||||
MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
|
||||
MESSAGE_HANDLER(TSWM_UPDATETASKBARPOS, OnUpdateTaskbarPos)
|
||||
MESSAGE_HANDLER(TSWM_ACTIVATETASKINDEX, OnActivateTaskIndex)
|
||||
MESSAGE_HANDLER(TWM_SETTINGSCHANGED, OnTaskbarSettingsChanged)
|
||||
MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
|
||||
MESSAGE_HANDLER(WM_TIMER, OnTimer)
|
||||
|
||||
@@ -44,6 +44,8 @@ HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, ICont
|
||||
#define IDHK_DESKTOP 0x1fe
|
||||
#define IDHK_PAGER 0x1ff
|
||||
|
||||
#define IDHK_ACTIVATE_TASK 0x209
|
||||
|
||||
enum { NONE, TILED, CASCADED } g_Arrangement = NONE;
|
||||
|
||||
struct WINDOWPOSBACKUPDATA
|
||||
@@ -2437,6 +2439,61 @@ ChangePos:
|
||||
MAKELONG(IDHK_SYS_PROPERTIES, MAKEWORD(VK_PAUSE, MOD_WIN)),
|
||||
MAKELONG(IDHK_DESKTOP, MAKEWORD('D', MOD_WIN)),
|
||||
MAKELONG(IDHK_PAGER, MAKEWORD('B', MOD_WIN)),
|
||||
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('1', MOD_WIN)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('2', MOD_WIN)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('3', MOD_WIN)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('4', MOD_WIN)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('5', MOD_WIN)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('6', MOD_WIN)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('7', MOD_WIN)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('8', MOD_WIN)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('9', MOD_WIN)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('0', MOD_WIN)),
|
||||
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('1', MOD_WIN | MOD_ALT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('2', MOD_WIN | MOD_ALT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('3', MOD_WIN | MOD_ALT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('4', MOD_WIN | MOD_ALT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('5', MOD_WIN | MOD_ALT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('6', MOD_WIN | MOD_ALT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('7', MOD_WIN | MOD_ALT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('8', MOD_WIN | MOD_ALT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('9', MOD_WIN | MOD_ALT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('0', MOD_WIN | MOD_ALT)),
|
||||
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('1', MOD_WIN | MOD_CONTROL)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('2', MOD_WIN | MOD_CONTROL)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('3', MOD_WIN | MOD_CONTROL)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('4', MOD_WIN | MOD_CONTROL)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('5', MOD_WIN | MOD_CONTROL)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('6', MOD_WIN | MOD_CONTROL)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('7', MOD_WIN | MOD_CONTROL)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('8', MOD_WIN | MOD_CONTROL)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('9', MOD_WIN | MOD_CONTROL)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('0', MOD_WIN | MOD_CONTROL)),
|
||||
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('1', MOD_WIN | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('2', MOD_WIN | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('3', MOD_WIN | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('4', MOD_WIN | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('5', MOD_WIN | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('6', MOD_WIN | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('7', MOD_WIN | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('8', MOD_WIN | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('9', MOD_WIN | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('0', MOD_WIN | MOD_SHIFT)),
|
||||
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('1', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('2', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('3', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('4', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('5', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('6', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('7', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('8', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('9', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
MAKELONG(IDHK_ACTIVATE_TASK, MAKEWORD('0', MOD_WIN | MOD_CONTROL | MOD_SHIFT)),
|
||||
};
|
||||
if (!SHRestricted(REST_NOWINKEYS))
|
||||
{
|
||||
@@ -3107,6 +3164,13 @@ HandleTrayContextMenu:
|
||||
|
||||
LRESULT OnHotkey(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (wParam == IDHK_ACTIVATE_TASK)
|
||||
{
|
||||
// Map the ('1'-'9','0') hotkey to a zero-based task index
|
||||
DWORD iTask = (HIWORD(lParam) - '0' + 9) % 10;
|
||||
// Request the task switcher to perform the switch
|
||||
::SendMessageW(m_TaskSwitch, TSWM_ACTIVATETASKINDEX, MAKEWPARAM(iTask, LOWORD(lParam)), 0);
|
||||
}
|
||||
return HandleHotKey(wParam);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user