From 27bc31100eda0d5424ef991b6dbe033bd31522b5 Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Sat, 18 Jun 2022 21:24:41 +0200 Subject: [PATCH] [STOBJECT] Add support for the mouse key tray icon --- dll/shellext/stobject/CMakeLists.txt | 1 + dll/shellext/stobject/csystray.cpp | 25 ++++ dll/shellext/stobject/csystray.h | 1 + dll/shellext/stobject/mouse.cpp | 125 ++++++++++++++++++ dll/shellext/stobject/precomp.h | 6 + dll/shellext/stobject/resource.h | 12 ++ .../stobject/resources/mouse/disabled.ico | Bin 0 -> 1406 bytes .../stobject/resources/mouse/left_active.ico | Bin 0 -> 1406 bytes .../mouse/left_active_right_down.ico | Bin 0 -> 1406 bytes .../stobject/resources/mouse/left_down.ico | Bin 0 -> 1406 bytes .../mouse/left_down_right_active.ico | Bin 0 -> 1406 bytes .../resources/mouse/left_right_active.ico | Bin 0 -> 1406 bytes .../resources/mouse/left_right_down.ico | Bin 0 -> 1406 bytes .../stobject/resources/mouse/none.ico | Bin 0 -> 1406 bytes .../stobject/resources/mouse/right_active.ico | Bin 0 -> 1406 bytes .../stobject/resources/mouse/right_down.ico | Bin 0 -> 1406 bytes dll/shellext/stobject/stobject.rc | 12 ++ 17 files changed, 182 insertions(+) create mode 100644 dll/shellext/stobject/mouse.cpp create mode 100644 dll/shellext/stobject/resources/mouse/disabled.ico create mode 100644 dll/shellext/stobject/resources/mouse/left_active.ico create mode 100644 dll/shellext/stobject/resources/mouse/left_active_right_down.ico create mode 100644 dll/shellext/stobject/resources/mouse/left_down.ico create mode 100644 dll/shellext/stobject/resources/mouse/left_down_right_active.ico create mode 100644 dll/shellext/stobject/resources/mouse/left_right_active.ico create mode 100644 dll/shellext/stobject/resources/mouse/left_right_down.ico create mode 100644 dll/shellext/stobject/resources/mouse/none.ico create mode 100644 dll/shellext/stobject/resources/mouse/right_active.ico create mode 100644 dll/shellext/stobject/resources/mouse/right_down.ico diff --git a/dll/shellext/stobject/CMakeLists.txt b/dll/shellext/stobject/CMakeLists.txt index b8b18915cab..7604c3caecf 100644 --- a/dll/shellext/stobject/CMakeLists.txt +++ b/dll/shellext/stobject/CMakeLists.txt @@ -10,6 +10,7 @@ list(APPEND SOURCE csystray.cpp stobject.cpp hotplug.cpp + mouse.cpp power.cpp volume.cpp precomp.h) diff --git a/dll/shellext/stobject/csystray.cpp b/dll/shellext/stobject/csystray.cpp index 93d17406115..bab008c0d01 100644 --- a/dll/shellext/stobject/csystray.cpp +++ b/dll/shellext/stobject/csystray.cpp @@ -22,6 +22,7 @@ const int g_NumIcons = _countof(g_IconHandlers); CSysTray::CSysTray() : dwServicesEnabled(0) { + wm_SHELLHOOK = RegisterWindowMessageW(L"SHELLHOOK"); wm_DESTROYWINDOW = RegisterWindowMessageW(L"CSysTray_DESTROY"); } @@ -128,6 +129,8 @@ HRESULT CSysTray::InitIcons() } } + MouseKeys_Init(this); + return InitNetShell(); } @@ -144,6 +147,8 @@ HRESULT CSysTray::ShutdownIcons() } } + MouseKeys_Shutdown(this); + return ShutdownNetShell(); } @@ -318,6 +323,17 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM { return DestroyWindow(); } + + if (wm_SHELLHOOK && uMsg == wm_SHELLHOOK) + { + if (wParam == HSHELL_ACCESSIBILITYSTATE && lParam == ACCESS_MOUSEKEYS) + { + MouseKeys_Update(this); + } + lResult = 0L; + return TRUE; + } + switch (uMsg) { case WM_NCCREATE: @@ -328,6 +344,7 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM GetServicesEnabled(); InitIcons(); SetTimer(1, 2000, NULL); + RegisterShellHookWindow(hWnd); return TRUE; case WM_TIMER: @@ -337,8 +354,16 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM ProcessIconMessage(uMsg, wParam, lParam, lResult); return TRUE; + case WM_SETTINGCHANGE: + if (wParam == SPI_SETMOUSEKEYS) + { + MouseKeys_Update(this); + } + break; + case WM_DESTROY: KillTimer(1); + DeregisterShellHookWindow(hWnd); ShutdownIcons(); PostQuitMessage(0); return TRUE; diff --git a/dll/shellext/stobject/csystray.h b/dll/shellext/stobject/csystray.h index 692948efcbf..059e7047f0b 100644 --- a/dll/shellext/stobject/csystray.h +++ b/dll/shellext/stobject/csystray.h @@ -29,6 +29,7 @@ class CSysTray : // TODO: keep icon handlers here DWORD dwServicesEnabled; + UINT wm_SHELLHOOK; UINT wm_DESTROYWINDOW; static DWORD WINAPI s_SysTrayThreadProc(PVOID param); diff --git a/dll/shellext/stobject/mouse.cpp b/dll/shellext/stobject/mouse.cpp new file mode 100644 index 00000000000..103b1235503 --- /dev/null +++ b/dll/shellext/stobject/mouse.cpp @@ -0,0 +1,125 @@ +/* + * PROJECT: ReactOS system libraries + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Mouse keys notification icon handler + * COPYRIGHT: Copyright 2022 Mark Jansen + */ + +#include "precomp.h" + +static MOUSEKEYS g_Mk; +static UINT g_MkState; +static HICON g_MkStateIcon; + +HRESULT STDMETHODCALLTYPE +MouseKeys_Init(_In_ CSysTray *pSysTray) +{ + TRACE("MouseKeys_Init!\n"); + + return MouseKeys_Update(pSysTray); +} + +HRESULT STDMETHODCALLTYPE +MouseKeys_Shutdown(_In_ CSysTray *pSysTray) +{ + TRACE("MouseKeys_Shutdown!\n"); + + if (g_MkStateIcon) + { + DestroyIcon(g_MkStateIcon); + g_MkStateIcon = NULL; + } + + if (g_MkState) + { + g_MkState = 0; + pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_MOUSE, g_MkStateIcon, L"MouseKeys"); + } + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE +MouseKeys_Update(_In_ CSysTray *pSysTray) +{ + TRACE("MouseKeys_Update!\n"); + + g_Mk.cbSize = sizeof(g_Mk); + SystemParametersInfoW(SPI_GETMOUSEKEYS, sizeof(g_Mk), &g_Mk, 0); + + UINT state = 0; + if ((g_Mk.dwFlags & (MKF_INDICATOR | MKF_MOUSEKEYSON)) == (MKF_INDICATOR | MKF_MOUSEKEYSON)) + { + if (g_Mk.dwFlags & MKF_MOUSEMODE) + { + switch (g_Mk.dwFlags & (MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONDOWN | MKF_RIGHTBUTTONSEL)) + { + case 0: + default: + state = IDI_MOUSE_NOBTN; + break; + case MKF_LEFTBUTTONSEL: + state = IDI_MOUSE_L_ACTIVE; + break; + case MKF_LEFTBUTTONDOWN: + case MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL: + state = IDI_MOUSE_L_DOWN; + break; + case MKF_RIGHTBUTTONSEL: + state = IDI_MOUSE_R_ACTIVE; + break; + case MKF_RIGHTBUTTONDOWN: + case MKF_RIGHTBUTTONDOWN | MKF_RIGHTBUTTONSEL: + state = IDI_MOUSE_R_DOWN; + break; + case MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONSEL: + state = IDI_MOUSE_LR_ACTIVE; + break; + case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN: + case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL: + case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONSEL: + case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN | MKF_RIGHTBUTTONSEL: + state = IDI_MOUSE_LR_DOWN; + break; + case MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONDOWN: + case MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONDOWN | MKF_RIGHTBUTTONSEL: + state = IDI_MOUSE_L_ACTIVE_R_DOWN; + break; + case MKF_LEFTBUTTONDOWN | MKF_RIGHTBUTTONSEL: + case MKF_LEFTBUTTONDOWN | MKF_RIGHTBUTTONSEL | MKF_LEFTBUTTONSEL: + state = IDI_MOUSE_R_ACTIVE_L_DOWN; + break; + } + } + else + { + state = IDI_MOUSE_DISABLED; + } + } + + UINT uId = NIM_MODIFY; + if (state != g_MkState) + { + if (g_MkStateIcon) + { + DestroyIcon(g_MkStateIcon); + g_MkStateIcon = NULL; + } + + if (g_MkState == 0) + uId = NIM_ADD; + + g_MkState = state; + if (g_MkState) + { + g_MkStateIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(g_MkState)); + } + } + + if (g_MkState == 0) + { + uId = NIM_DELETE; + } + + return pSysTray->NotifyIcon(uId, ID_ICON_MOUSE, g_MkStateIcon, L"MouseKeys"); +} diff --git a/dll/shellext/stobject/precomp.h b/dll/shellext/stobject/precomp.h index e60b0a265b8..3d891af31b6 100644 --- a/dll/shellext/stobject/precomp.h +++ b/dll/shellext/stobject/precomp.h @@ -33,6 +33,7 @@ extern HINSTANCE g_hInstance; #define ID_ICON_VOLUME (WM_APP + 0x4CB) #define ID_ICON_HOTPLUG (WM_APP + 0x4CC) #define ID_ICON_POWER (WM_APP + 0x4CD) +#define ID_ICON_MOUSE (WM_APP + 0x4CE) #define POWER_SERVICE_FLAG 0x00000001 #define HOTPLUG_SERVICE_FLAG 0x00000002 @@ -74,6 +75,11 @@ extern HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE Power_Update(_In_ CSysTray * pSysTray); extern HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult); +extern HRESULT STDMETHODCALLTYPE MouseKeys_Init(_In_ CSysTray * pSysTray); +extern HRESULT STDMETHODCALLTYPE MouseKeys_Shutdown(_In_ CSysTray * pSysTray); +extern HRESULT STDMETHODCALLTYPE MouseKeys_Update(_In_ CSysTray * pSysTray); + + #define POWER_TIMER_ID 2 #define VOLUME_TIMER_ID 3 #define HOTPLUG_TIMER_ID 4 diff --git a/dll/shellext/stobject/resource.h b/dll/shellext/stobject/resource.h index 71d500ec25b..66e6aed204f 100644 --- a/dll/shellext/stobject/resource.h +++ b/dll/shellext/stobject/resource.h @@ -56,4 +56,16 @@ #define IDI_HOTPLUG_ERR 420 #define IDI_HOTPLUG_OK 421 +#define IDI_MOUSE_DISABLED 440 +#define IDI_MOUSE_NOBTN 441 +#define IDI_MOUSE_L_ACTIVE 442 +#define IDI_MOUSE_L_DOWN 443 +#define IDI_MOUSE_R_ACTIVE 444 +#define IDI_MOUSE_R_DOWN 445 +#define IDI_MOUSE_LR_ACTIVE 446 +#define IDI_MOUSE_LR_DOWN 447 +#define IDI_MOUSE_L_ACTIVE_R_DOWN 448 +#define IDI_MOUSE_R_ACTIVE_L_DOWN 449 + + #define IDR_SYSTRAY 11001 diff --git a/dll/shellext/stobject/resources/mouse/disabled.ico b/dll/shellext/stobject/resources/mouse/disabled.ico new file mode 100644 index 0000000000000000000000000000000000000000..e5b51a6d65bce5e26569bca315d9720af8c519f6 GIT binary patch literal 1406 zcmZQzU}Ruq5D);-91Iz(3=Con3=A3!3=9Gc3=9ek5OD?&U;+`S*ulZ!zo6i*|3X5$ z{tFB5{x2%B`@fjj&i~@#yZ%c^?D{V$x$nP})V}{RGW-9_%I^QKps?@1lG48a%F6ry zb8=q!&&hS=KR5T)|2(|c|MT)*|If#N^FKfTjsNoUr~k{#pZPB&eC5BW=+*yXV%PqQ zi(mgQAaLuykno-V!oqj{i-_F&FD`!nzl6l)|B{kd{!2<+|1T$Z{lBd2o&R$3cm7LA zKK!q!aO1y*#)bb{S{MK8=v?}*uYc*khQ{6hTAKI%>+0V7Z*G3=zpCnk|7z+F|7&PG z`md?^_`jy+lmGhq5C0n&Jp6BJ`t-lA@00(2eoz1V`#<|15b*qeM8xC&v2ic{x3#_g z-`(~8|B@vi{x4k$!XN)HTlVSy-@kwVg8%~q!~an{8V18W4L}M6R#rwv2#bM%!PQk$ zMOso3RFHsqZrZA%!h!+<5EZVjtXi@%BEo|FN+1DOS63cGI~OM>M_XxDuyR*kT?aQe zH#d7FHVB_v-@?Yq(ozF#g^R1JtAU=nyu6$$*aBA&Ffh>7Ep literal 0 HcmV?d00001 diff --git a/dll/shellext/stobject/resources/mouse/left_active.ico b/dll/shellext/stobject/resources/mouse/left_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..d87b21b3d36bc76866ad20e683799ff7c9dc94f3 GIT binary patch literal 1406 zcmZQzU}Ruq5D);-91Iz(3=Con3=A3!3=9Gc3=9ek5OD?&U;+^s_`idL!~fsEfB*mc z_wWCI|Ni|40R{$!|D$*`3`WzyuulV^5`vMDkr7@nFfuZ;va+(kL>O6N0HOqqkKnSh zf)pU}nb7#?^4R$xx4VjT!v}T-h6l_Le1MUGfe;3%1?l<0&%gix_>df? literal 0 HcmV?d00001 diff --git a/dll/shellext/stobject/resources/mouse/left_active_right_down.ico b/dll/shellext/stobject/resources/mouse/left_active_right_down.ico new file mode 100644 index 0000000000000000000000000000000000000000..ee977316081a39acb7938249612137c7ef5b3896 GIT binary patch literal 1406 zcmZQzU}Ruq5D);-91Iz(3=Con3=A3!3=9Gc3=9ek5OD?&U;+^s_`idL!~fsEfB*mc z_wWCI|Ni|40R{$!|D$*`3`WzyuulV^5`vMDkr7@nFfuZ;va+(kL>O6N0HOqqkKnSh zf)pU}nb7#?^4R$xx4O6N0HOqqkKnSh zf)pU}nb7#?^4R$xx4O6N0HOqqkKnSh zf)pU}nb7#?^4R$xx4p(cRzL%9qL iP}4yg|Hv~id|+o_c)$$72N)R`2w{*~ke(m>3=9CnO&mA? literal 0 HcmV?d00001 diff --git a/dll/shellext/stobject/resources/mouse/left_right_active.ico b/dll/shellext/stobject/resources/mouse/left_right_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..4964f037312b4ad0b8dede912c1d841300357940 GIT binary patch literal 1406 zcmZQzU}Ruq5D);-91Iz(3=Con3=A3!3=9Gc3=9ek5OD?&U;+^s_`idL!~fsEfB*mc z_wWCI|Ni|40R{$!|D$*`3`WzyuulV^5`vMDkr7@nFfuZ;va+(kL>O6N0HOqqkKnSh zf)pU}nb7#?^4R$xx43>455oav2z) irh`2EN1lP<13Lr517-+5z{tQr2!qsu^!(swU;qH%w;Xf; literal 0 HcmV?d00001 diff --git a/dll/shellext/stobject/resources/mouse/left_right_down.ico b/dll/shellext/stobject/resources/mouse/left_right_down.ico new file mode 100644 index 0000000000000000000000000000000000000000..0283f66338adcac67544fb8f00bac316f278bed0 GIT binary patch literal 1406 zcmZQzU}Ruq5D);-91Iz(3=Con3=A3!3=9Gc3=9ek5OD?&U;+^s_`idL!~fsEfB*mc z_wWCI|Ni|40R{$!|D$*`3`WzyuulV^5`vMDkr7@nFfuZ;va+(kL>O6N0HOqqkKnSh zf)pU}nb7#?^4R$xx4#uFu@csGBPrO6N0HOqqkKnSh zf)pU}nb7#?^4R$xx4Ws|A#6XrA9+wGz5l!2rz;G+?$My%&e@eER4`1f{_&lAOdK71ecW+ zqyUM}gvLjg$Ib`21%^ST7ua@?NuZL9fdOJZZazc-SRPD3bby#34E7|{bP)TGJOjfA Zb_RwA%n*Elk%55_2B`(<`N7Y?002Q29h(3E literal 0 HcmV?d00001 diff --git a/dll/shellext/stobject/stobject.rc b/dll/shellext/stobject/stobject.rc index f9b6e1bcf3d..bf310d7b95d 100644 --- a/dll/shellext/stobject/stobject.rc +++ b/dll/shellext/stobject/stobject.rc @@ -31,6 +31,18 @@ IDI_HOTPLUG_ERR ICON "resources/hotplug/0.ico" IDI_HOTPLUG_OK ICON "resources/hotplug/1.ico" +IDI_MOUSE_DISABLED ICON "resources/mouse/disabled.ico" +IDI_MOUSE_NOBTN ICON "resources/mouse/none.ico" +IDI_MOUSE_L_ACTIVE ICON "resources/mouse/left_active.ico" +IDI_MOUSE_L_DOWN ICON "resources/mouse/left_down.ico" +IDI_MOUSE_R_ACTIVE ICON "resources/mouse/right_active.ico" +IDI_MOUSE_R_DOWN ICON "resources/mouse/right_down.ico" +IDI_MOUSE_LR_ACTIVE ICON "resources/mouse/left_right_active.ico" +IDI_MOUSE_LR_DOWN ICON "resources/mouse/left_right_down.ico" +IDI_MOUSE_L_ACTIVE_R_DOWN ICON "resources/mouse/left_active_right_down.ico" +IDI_MOUSE_R_ACTIVE_L_DOWN ICON "resources/mouse/left_down_right_active.ico" + + IDR_SYSTRAY REGISTRY "resources/rgs/systray.rgs" #include -- 2.51.2