1 /* 2 * PROJECT: ReactOS system libraries 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Mouse keys notification icon handler 5 * COPYRIGHT: Copyright 2022 Mark Jansen <mark.jansen@reactos.org> 6 */ 7 8 #include "precomp.h" 9 10 static MOUSEKEYS g_Mk; 11 static UINT g_MkState; 12 static HICON g_MkStateIcon; 13 14 HRESULT STDMETHODCALLTYPE 15 MouseKeys_Init(_In_ CSysTray *pSysTray) 16 { 17 TRACE("MouseKeys_Init!\n"); 18 19 return MouseKeys_Update(pSysTray); 20 } 21 22 HRESULT STDMETHODCALLTYPE 23 MouseKeys_Shutdown(_In_ CSysTray *pSysTray) 24 { 25 TRACE("MouseKeys_Shutdown!\n"); 26 27 if (g_MkStateIcon) 28 { 29 DestroyIcon(g_MkStateIcon); 30 g_MkStateIcon = NULL; 31 } 32 33 if (g_MkState) 34 { 35 g_MkState = 0; 36 pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_MOUSE, g_MkStateIcon, L"MouseKeys"); 37 } 38 39 return S_OK; 40 } 41 42 HRESULT STDMETHODCALLTYPE 43 MouseKeys_Update(_In_ CSysTray *pSysTray) 44 { 45 TRACE("MouseKeys_Update!\n"); 46 47 g_Mk.cbSize = sizeof(g_Mk); 48 SystemParametersInfoW(SPI_GETMOUSEKEYS, sizeof(g_Mk), &g_Mk, 0); 49 50 UINT state = 0; 51 if ((g_Mk.dwFlags & (MKF_INDICATOR | MKF_MOUSEKEYSON)) == (MKF_INDICATOR | MKF_MOUSEKEYSON)) 52 { 53 if (g_Mk.dwFlags & MKF_MOUSEMODE) 54 { 55 switch (g_Mk.dwFlags & (MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONDOWN | MKF_RIGHTBUTTONSEL)) 56 { 57 case 0: 58 default: 59 state = IDI_MOUSE_NOBTN; 60 break; 61 case MKF_LEFTBUTTONSEL: 62 state = IDI_MOUSE_L_ACTIVE; 63 break; 64 case MKF_LEFTBUTTONDOWN: 65 case MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL: 66 state = IDI_MOUSE_L_DOWN; 67 break; 68 case MKF_RIGHTBUTTONSEL: 69 state = IDI_MOUSE_R_ACTIVE; 70 break; 71 case MKF_RIGHTBUTTONDOWN: 72 case MKF_RIGHTBUTTONDOWN | MKF_RIGHTBUTTONSEL: 73 state = IDI_MOUSE_R_DOWN; 74 break; 75 case MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONSEL: 76 state = IDI_MOUSE_LR_ACTIVE; 77 break; 78 case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN: 79 case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL: 80 case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN | MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONSEL: 81 case MKF_RIGHTBUTTONDOWN | MKF_LEFTBUTTONDOWN | MKF_RIGHTBUTTONSEL: 82 state = IDI_MOUSE_LR_DOWN; 83 break; 84 case MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONDOWN: 85 case MKF_LEFTBUTTONSEL | MKF_RIGHTBUTTONDOWN | MKF_RIGHTBUTTONSEL: 86 state = IDI_MOUSE_L_ACTIVE_R_DOWN; 87 break; 88 case MKF_LEFTBUTTONDOWN | MKF_RIGHTBUTTONSEL: 89 case MKF_LEFTBUTTONDOWN | MKF_RIGHTBUTTONSEL | MKF_LEFTBUTTONSEL: 90 state = IDI_MOUSE_R_ACTIVE_L_DOWN; 91 break; 92 } 93 } 94 else 95 { 96 state = IDI_MOUSE_DISABLED; 97 } 98 } 99 100 UINT uId = NIM_MODIFY; 101 if (state != g_MkState) 102 { 103 if (g_MkStateIcon) 104 { 105 DestroyIcon(g_MkStateIcon); 106 g_MkStateIcon = NULL; 107 } 108 109 if (g_MkState == 0) 110 uId = NIM_ADD; 111 112 g_MkState = state; 113 if (g_MkState) 114 { 115 g_MkStateIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(g_MkState)); 116 } 117 } 118 119 if (g_MkState == 0) 120 { 121 uId = NIM_DELETE; 122 } 123 124 return pSysTray->NotifyIcon(uId, ID_ICON_MOUSE, g_MkStateIcon, L"MouseKeys"); 125 } 126