[STOBJECT] Keep the object alive while the thread is running,

Fix shutting down the thread.
This commit is contained in:
Mark Jansen 2022-06-18 21:19:42 +02:00
parent f10d40f912
commit 334c7cee35
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
2 changed files with 26 additions and 10 deletions

View file

@ -9,6 +9,7 @@
#include "precomp.h" #include "precomp.h"
#include <regstr.h>
#include <undocshell.h> #include <undocshell.h>
#include <shellutils.h> #include <shellutils.h>
@ -19,8 +20,14 @@ SysTrayIconHandlers_t g_IconHandlers [] = {
}; };
const int g_NumIcons = _countof(g_IconHandlers); const int g_NumIcons = _countof(g_IconHandlers);
CSysTray::CSysTray() {} CSysTray::CSysTray() : dwServicesEnabled(0)
CSysTray::~CSysTray() {} {
wm_DESTROYWINDOW = RegisterWindowMessageW(L"CSysTray_DESTROY");
}
CSysTray::~CSysTray()
{
}
VOID CSysTray::GetServicesEnabled() VOID CSysTray::GetServicesEnabled()
{ {
@ -30,8 +37,7 @@ VOID CSysTray::GetServicesEnabled()
/* Enable power, volume and hotplug by default */ /* Enable power, volume and hotplug by default */
this->dwServicesEnabled = POWER_SERVICE_FLAG | VOLUME_SERVICE_FLAG | HOTPLUG_SERVICE_FLAG; this->dwServicesEnabled = POWER_SERVICE_FLAG | VOLUME_SERVICE_FLAG | HOTPLUG_SERVICE_FLAG;
if (RegCreateKeyExW(HKEY_CURRENT_USER, if (RegCreateKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_SYSTRAY,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\SysTray",
0, 0,
NULL, NULL,
REG_OPTION_NON_VOLATILE, REG_OPTION_NON_VOLATILE,
@ -132,9 +138,9 @@ HRESULT CSysTray::ShutdownIcons()
{ {
if (this->dwServicesEnabled & g_IconHandlers[i].dwServiceFlag) if (this->dwServicesEnabled & g_IconHandlers[i].dwServiceFlag)
{ {
this->dwServicesEnabled &= ~g_IconHandlers[i].dwServiceFlag;
HRESULT hr = g_IconHandlers[i].pfnShutdown(this); HRESULT hr = g_IconHandlers[i].pfnShutdown(this);
if (FAILED(hr)) FAILED_UNEXPECTEDLY(hr);
return hr;
} }
} }
@ -253,12 +259,14 @@ HRESULT CSysTray::SysTrayThreadProc()
CoUninitialize(); CoUninitialize();
Release();
FreeLibraryAndExitThread(hLib, ret); FreeLibraryAndExitThread(hLib, ret);
} }
HRESULT CSysTray::CreateSysTrayThread() HRESULT CSysTray::CreateSysTrayThread()
{ {
TRACE("CSysTray Init TODO: Initialize tray icon handlers.\n"); TRACE("CSysTray Init TODO: Initialize tray icon handlers.\n");
AddRef();
HANDLE hThread = CreateThread(NULL, 0, s_SysTrayThreadProc, this, 0, NULL); HANDLE hThread = CreateThread(NULL, 0, s_SysTrayThreadProc, this, 0, NULL);
@ -269,8 +277,11 @@ HRESULT CSysTray::CreateSysTrayThread()
HRESULT CSysTray::DestroySysTrayWindow() HRESULT CSysTray::DestroySysTrayWindow()
{ {
DestroyWindow(); if (!DestroyWindow())
hwndSysTray = NULL; {
// Window is from another thread, ask it politely to destroy itself:
SendMessage(wm_DESTROYWINDOW);
}
return S_OK; return S_OK;
} }
@ -303,6 +314,10 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
if (hWnd != m_hWnd) if (hWnd != m_hWnd)
return FALSE; return FALSE;
if (wm_DESTROYWINDOW && uMsg == wm_DESTROYWINDOW)
{
return DestroyWindow();
}
switch (uMsg) switch (uMsg)
{ {
case WM_NCCREATE: case WM_NCCREATE:
@ -325,6 +340,7 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
case WM_DESTROY: case WM_DESTROY:
KillTimer(1); KillTimer(1);
ShutdownIcons(); ShutdownIcons();
PostQuitMessage(0);
return TRUE; return TRUE;
} }

View file

@ -29,7 +29,7 @@ class CSysTray :
// TODO: keep icon handlers here // TODO: keep icon handlers here
DWORD dwServicesEnabled; DWORD dwServicesEnabled;
HWND hwndSysTray; UINT wm_DESTROYWINDOW;
static DWORD WINAPI s_SysTrayThreadProc(PVOID param); static DWORD WINAPI s_SysTrayThreadProc(PVOID param);
HRESULT SysTrayMessageLoop(); HRESULT SysTrayMessageLoop();