Reactos
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
10static MOUSEKEYS g_Mk;
11static UINT g_MkState;
12static HICON g_MkStateIcon;
13
14HRESULT STDMETHODCALLTYPE
15MouseKeys_Init(_In_ CSysTray *pSysTray)
16{
17 TRACE("MouseKeys_Init!\n");
18
19 return MouseKeys_Update(pSysTray);
20}
21
22HRESULT STDMETHODCALLTYPE
23MouseKeys_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
42HRESULT STDMETHODCALLTYPE
43MouseKeys_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
127HRESULT STDMETHODCALLTYPE MouseKeys_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
128{
129 switch (uMsg)
130 {
131 case ID_ICON_MOUSE:
132 switch (lParam)
133 {
134 case WM_LBUTTONDBLCLK:
135 case WM_RBUTTONDBLCLK:
136 pSysTray->RunAccessCpl(",,4");
137 return S_OK;
138 }
139 break;
140 }
141 return S_FALSE;
142}