https://git.reactos.org/?p=reactos.git;a=commitdiff;h=334c7cee35e4ba184b3138550994229a5e24eb71

commit 334c7cee35e4ba184b3138550994229a5e24eb71
Author:     Mark Jansen <[email protected]>
AuthorDate: Sat Jun 18 21:19:42 2022 +0200
Commit:     Mark Jansen <[email protected]>
CommitDate: Tue Sep 6 21:11:09 2022 +0200

    [STOBJECT] Keep the object alive while the thread is running,
    
    Fix shutting down the thread.
---
 dll/shellext/stobject/csystray.cpp | 32 ++++++++++++++++++++++++--------
 dll/shellext/stobject/csystray.h   |  4 ++--
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/dll/shellext/stobject/csystray.cpp 
b/dll/shellext/stobject/csystray.cpp
index 14f9c213a9f..93d17406115 100644
--- a/dll/shellext/stobject/csystray.cpp
+++ b/dll/shellext/stobject/csystray.cpp
@@ -9,6 +9,7 @@
 
 #include "precomp.h"
 
+#include <regstr.h>
 #include <undocshell.h>
 #include <shellutils.h>
 
@@ -19,8 +20,14 @@ SysTrayIconHandlers_t g_IconHandlers [] = {
 };
 const int g_NumIcons = _countof(g_IconHandlers);
 
-CSysTray::CSysTray() {}
-CSysTray::~CSysTray() {}
+CSysTray::CSysTray() : dwServicesEnabled(0)
+{
+    wm_DESTROYWINDOW = RegisterWindowMessageW(L"CSysTray_DESTROY");
+}
+
+CSysTray::~CSysTray()
+{
+}
 
 VOID CSysTray::GetServicesEnabled()
 {
@@ -30,8 +37,7 @@ VOID CSysTray::GetServicesEnabled()
     /* Enable power, volume and hotplug by default */
     this->dwServicesEnabled = POWER_SERVICE_FLAG | VOLUME_SERVICE_FLAG | 
HOTPLUG_SERVICE_FLAG;
 
-    if (RegCreateKeyExW(HKEY_CURRENT_USER,
-                        
L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\SysTray",
+    if (RegCreateKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_SYSTRAY,
                         0,
                         NULL,
                         REG_OPTION_NON_VOLATILE,
@@ -132,9 +138,9 @@ HRESULT CSysTray::ShutdownIcons()
     {
         if (this->dwServicesEnabled & g_IconHandlers[i].dwServiceFlag)
         {
+            this->dwServicesEnabled &= ~g_IconHandlers[i].dwServiceFlag;
             HRESULT hr = g_IconHandlers[i].pfnShutdown(this);
-            if (FAILED(hr))
-                return hr;
+            FAILED_UNEXPECTEDLY(hr);
         }
     }
 
@@ -253,12 +259,14 @@ HRESULT CSysTray::SysTrayThreadProc()
 
     CoUninitialize();
 
+    Release();
     FreeLibraryAndExitThread(hLib, ret);
 }
 
 HRESULT CSysTray::CreateSysTrayThread()
 {
     TRACE("CSysTray Init TODO: Initialize tray icon handlers.\n");
+    AddRef();
 
     HANDLE hThread = CreateThread(NULL, 0, s_SysTrayThreadProc, this, 0, NULL);
 
@@ -269,8 +277,11 @@ HRESULT CSysTray::CreateSysTrayThread()
 
 HRESULT CSysTray::DestroySysTrayWindow()
 {
-    DestroyWindow();
-    hwndSysTray = NULL;
+    if (!DestroyWindow())
+    {
+        // Window is from another thread, ask it politely to destroy itself:
+        SendMessage(wm_DESTROYWINDOW);
+    }
     return S_OK;
 }
 
@@ -303,6 +314,10 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, 
WPARAM wParam, LPARAM
     if (hWnd != m_hWnd)
         return FALSE;
 
+    if (wm_DESTROYWINDOW && uMsg == wm_DESTROYWINDOW)
+    {
+        return DestroyWindow();
+    }
     switch (uMsg)
     {
     case WM_NCCREATE:
@@ -325,6 +340,7 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, 
WPARAM wParam, LPARAM
     case WM_DESTROY:
         KillTimer(1);
         ShutdownIcons();
+        PostQuitMessage(0);
         return TRUE;
     }
 
diff --git a/dll/shellext/stobject/csystray.h b/dll/shellext/stobject/csystray.h
index 0ff52367825..692948efcbf 100644
--- a/dll/shellext/stobject/csystray.h
+++ b/dll/shellext/stobject/csystray.h
@@ -29,7 +29,7 @@ class CSysTray :
     // TODO: keep icon handlers here
 
     DWORD dwServicesEnabled;
-    HWND hwndSysTray;
+    UINT wm_DESTROYWINDOW;
 
     static DWORD WINAPI s_SysTrayThreadProc(PVOID param);
     HRESULT SysTrayMessageLoop();
@@ -76,4 +76,4 @@ public:
         COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
     END_COM_MAP()
 
-};
\ No newline at end of file
+};

Reply via email to