xref: /reactos/dll/shellext/stobject/mouse.cpp (revision 83e13630)
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