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 zcmeHHO>YuW6n$t=DNJWzfHEyGl!^uH6kIg5#t$TY-SuPHjjsJAUFhFv`yZqUbgv8B z(ozi~*j7zkh^|~nj_1u-%feq^dMD?;ob&E|=jCN`h4Aq+48eRuJo5_?7eeF-N+Lrj z-Hj{WGMp=w3c}$UB9R(Qa|f~L4&w2b7#pi0k*LA4>KGrdBbjU;mjkMiH!s=l%bBuic4T{A*%*^bgRN5zhk7A(%$LU~x{s_5T7q_N+)IXw7 zI3Z41*F(A7!`$2%mX}YlvT}yi)lXPk`;7JV6FhnP1sfY*@#6V6Y;N|kwWaVK+uJ`d z7!06-?{taFH~8QG0dE}m{XXB{!60Sf=7cq=1_?vTrQ5lf88!^BLP~!zm5iEUJ*xyM zW$4bs#cK8Og9%O_#Wkn0#CVjw=J8ZcTmw=HWycx4xPTBL zO}ox!uU|@aDzggJKg<>Nc-7q()pPDq_eSjhvwJRj>o1!0uL{wncbC%cFsSYR16|hl J+4oZy;x{Y?fd>Ep 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 zcmeHHF%H5o47{{hu+fPXMxK%9@Jyb<6Bv;~V(i#05FvF(adfWEzFe9rDG+2#6D03& zA>aVuERYgT0*?YbIx2!VGYrA^l#A5!2h2Cx#~e<`7MMn647R^1R)kC zY51EGso;YT4R8Cud3_mA)ei(R*XpO#S26$ZzO?4Pw%tMJJN50__MS)Jz6EZh;VPmv Ks8;7Z_P`7HkQ}A} 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 zcmeHHOAZ1d41LVl=+0TW)uqSaI3ClZcm$Uw2(=&P6Jp}tQ1S||eUL%`AV`}gh(F*) zzzM)rAR$}?8aErfYdpsoIi$QN-tXo_c$NLOC_rPOx+(q~c Ks?|BKBk%#lp&U2> literal 0 HcmV?d00001 diff --git a/dll/shellext/stobject/resources/mouse/left_down.ico b/dll/shellext/stobject/resources/mouse/left_down.ico new file mode 100644 index 0000000000000000000000000000000000000000..97346434deb25fe1991c5db74496ce9dc748158e GIT binary patch literal 1406 zcmeH{Jr2S!4254>EZFG83M0qJaX2PN;RuXKAu;|*3yP4sS8?@ReeScBRB3@A*EB)$ z0XG6p0Inh_;Udzy#o)IlbBvKwN}O}%QVMH`r>nn%eg?LG2INx@8q04Xgpr7Lb0r9P zxTWDQ5~<;bhlbnd|JfE(lg_hs`Ba;?!rowhZ?%GQ#kyVJ-unzZ_rPOx-Nm#f^=i-S G2z&tBCLC%2 literal 0 HcmV?d00001 diff --git a/dll/shellext/stobject/resources/mouse/left_down_right_active.ico b/dll/shellext/stobject/resources/mouse/left_down_right_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..95899121b791194f8fcf6b5a9038c7484344ad09 GIT binary patch literal 1406 zcmeHHK@P$&40ARjxUmygIP#1>XV2s*Jb@!pX-nK}fGQ;JsIHvJi4#>-J3wqr6D;m9 zD{ugCHd+cNBl8u5f0|fA2qnf?Qc5M~TnO`Y_A}^r;Q#M{J#`^ozXg#|RX1x!OgP-q z=(kj*;X@CNZtLH5-OLg=ukK3}w(30Bl(p8@y+Ky{GJ*Z>WWvEgk0Wr~0@u-bG1D*7 J%bxolcml&s95?^~ 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 zcmeHHK@P$o5S(q@=*^zI>d|NPIX=^;_ymt82sq1PRbt}Zu+0peVQ7KS0>W#WK;Gb_ zzz)EXpoIfreyPEmhVwknIfRg7j5(#0t(fWPd(h9o|DOSV>SDG07DPr>T|FJ4@bXBb zUsBZqZ+d8S+y7mc$y6%OgF=NMo3@*U?R}s9Zj_YIw-}bHvM$$`ci#ioHEk JvNqqH9CQEx 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 zcmeHHOAf*y5Pj1+(Vbnn)uqSaI3ClZcm$Uw2sod%7-HhS;gL6;H}fEbKmn35O^|rN zje!$@t58a~2(@k){L{n|LMSoDl2R%;=b{i#XFr2}2ey9)- U@Z19rS8&%e{(|LN&Fct!00JBv761SM literal 0 HcmV?d00001 diff --git a/dll/shellext/stobject/resources/mouse/right_active.ico b/dll/shellext/stobject/resources/mouse/right_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..b2dcfe6fa2d0a9cc22f9d6070927a68d168d5c8b GIT binary patch literal 1406 zcmeHHK@P$o5S(q@=*^zI>d|NLoIca1^a&nK5O9~J#Sjzk4NGRp>MRff&HHWx$2~`Jqtu5GauFp39&Fs z!z*Q0!xtYK-s-=3UQ9{be8iAe=Od-^vaR2%x-B5q&U9>JwaZ7ZMoG>wU_O=+M!`k(+na>fy2_qZ}} z1aJ|R5YD0+R|#a7o5~L%AjXK45^~NcrBuZ3_6_t6{PzY(Wf_rZVCL-{AptH