https://git.reactos.org/?p=reactos.git;a=commitdiff;h=27bc31100eda0d5424ef991b6dbe033bd31522b5

commit 27bc31100eda0d5424ef991b6dbe033bd31522b5
Author:     Mark Jansen <[email protected]>
AuthorDate: Sat Jun 18 21:24:41 2022 +0200
Commit:     Mark Jansen <[email protected]>
CommitDate: Tue Sep 6 21:11:09 2022 +0200

    [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 ++
 dll/shellext/stobject/resources/mouse/disabled.ico | Bin 0 -> 1406 bytes
 .../stobject/resources/mouse/left_active.ico       | Bin 0 -> 1406 bytes
 .../resources/mouse/left_active_right_down.ico     | Bin 0 -> 1406 bytes
 .../stobject/resources/mouse/left_down.ico         | Bin 0 -> 1406 bytes
 .../resources/mouse/left_down_right_active.ico     | Bin 0 -> 1406 bytes
 .../stobject/resources/mouse/left_right_active.ico | Bin 0 -> 1406 bytes
 .../stobject/resources/mouse/left_right_down.ico   | Bin 0 -> 1406 bytes
 dll/shellext/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(+)

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 <[email protected]>
+ */
+
+#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 00000000000..e5b51a6d65b
Binary files /dev/null and b/dll/shellext/stobject/resources/mouse/disabled.ico 
differ
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 00000000000..d87b21b3d36
Binary files /dev/null and 
b/dll/shellext/stobject/resources/mouse/left_active.ico differ
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 00000000000..ee977316081
Binary files /dev/null and 
b/dll/shellext/stobject/resources/mouse/left_active_right_down.ico differ
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 00000000000..97346434deb
Binary files /dev/null and 
b/dll/shellext/stobject/resources/mouse/left_down.ico differ
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 00000000000..95899121b79
Binary files /dev/null and 
b/dll/shellext/stobject/resources/mouse/left_down_right_active.ico differ
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 00000000000..4964f037312
Binary files /dev/null and 
b/dll/shellext/stobject/resources/mouse/left_right_active.ico differ
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 00000000000..0283f66338a
Binary files /dev/null and 
b/dll/shellext/stobject/resources/mouse/left_right_down.ico differ
diff --git a/dll/shellext/stobject/resources/mouse/none.ico 
b/dll/shellext/stobject/resources/mouse/none.ico
new file mode 100644
index 00000000000..0c84cf292e1
Binary files /dev/null and b/dll/shellext/stobject/resources/mouse/none.ico 
differ
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 00000000000..b2dcfe6fa2d
Binary files /dev/null and 
b/dll/shellext/stobject/resources/mouse/right_active.ico differ
diff --git a/dll/shellext/stobject/resources/mouse/right_down.ico 
b/dll/shellext/stobject/resources/mouse/right_down.ico
new file mode 100644
index 00000000000..624999a41c9
Binary files /dev/null and 
b/dll/shellext/stobject/resources/mouse/right_down.ico differ
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 <reactos/manifest_dll.rc>

Reply via email to