mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-10-12 10:28:08 +00:00
[idd] helper: stop using MsgWaitForMultipleObjects
`MsgWaitForMultipleObjects` doesn't handle inner message loops, which may happen during `TrackPopupMenu`, causing exits to fail.
This commit is contained in:
@@ -22,7 +22,8 @@ bool CNotifyWindow::registerClass()
|
|||||||
return s_atom;
|
return s_atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
CNotifyWindow::CNotifyWindow() : m_iconData({ 0 }), m_menu(CreatePopupMenu())
|
CNotifyWindow::CNotifyWindow() : m_iconData({ 0 }), m_menu(CreatePopupMenu()),
|
||||||
|
closeRequested(false)
|
||||||
{
|
{
|
||||||
CreateWindowEx(0, MAKEINTATOM(s_atom), NULL,
|
CreateWindowEx(0, MAKEINTATOM(s_atom), NULL,
|
||||||
0, 0, 0, 0, 0, NULL, NULL, hInstance, this);
|
0, 0, 0, 0, 0, NULL, NULL, hInstance, this);
|
||||||
@@ -63,6 +64,13 @@ LRESULT CNotifyWindow::onCreate()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LRESULT CNotifyWindow::onClose()
|
||||||
|
{
|
||||||
|
if (closeRequested)
|
||||||
|
destroy();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CNotifyWindow::onNotifyIcon(UINT uEvent, WORD wIconId, int x, int y)
|
LRESULT CNotifyWindow::onNotifyIcon(UINT uEvent, WORD wIconId, int x, int y)
|
||||||
{
|
{
|
||||||
switch (uEvent)
|
switch (uEvent)
|
||||||
@@ -95,3 +103,9 @@ void CNotifyWindow::registerIcon()
|
|||||||
if (!Shell_NotifyIcon(NIM_SETVERSION, &m_iconData))
|
if (!Shell_NotifyIcon(NIM_SETVERSION, &m_iconData))
|
||||||
DEBUG_ERROR_HR(GetLastError(), "Shell_NotifyIcon(NIM_SETVERSION)");
|
DEBUG_ERROR_HR(GetLastError(), "Shell_NotifyIcon(NIM_SETVERSION)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CNotifyWindow::close()
|
||||||
|
{
|
||||||
|
closeRequested = true;
|
||||||
|
PostMessage(m_hwnd, WM_CLOSE, 0, 0);
|
||||||
|
}
|
||||||
|
@@ -10,15 +10,19 @@ class CNotifyWindow : public CWindow
|
|||||||
|
|
||||||
NOTIFYICONDATA m_iconData;
|
NOTIFYICONDATA m_iconData;
|
||||||
HMENU m_menu;
|
HMENU m_menu;
|
||||||
|
bool closeRequested;
|
||||||
|
|
||||||
LRESULT onNotifyIcon(UINT uEvent, WORD wIconId, int x, int y);
|
LRESULT onNotifyIcon(UINT uEvent, WORD wIconId, int x, int y);
|
||||||
void registerIcon();
|
void registerIcon();
|
||||||
|
|
||||||
virtual LRESULT handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
|
virtual LRESULT handleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
|
||||||
virtual LRESULT onCreate() override;
|
virtual LRESULT onCreate() override;
|
||||||
|
virtual LRESULT onClose() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CNotifyWindow();
|
CNotifyWindow();
|
||||||
~CNotifyWindow() override;
|
~CNotifyWindow() override;
|
||||||
static bool registerClass();
|
static bool registerClass();
|
||||||
|
|
||||||
|
void close();
|
||||||
};
|
};
|
||||||
|
@@ -31,6 +31,13 @@ static HandleT<HANDLENullTraits> l_process;
|
|||||||
|
|
||||||
static void Launch();
|
static void Launch();
|
||||||
|
|
||||||
|
void CALLBACK DestroyNotifyWindow(PVOID lpParam, BOOLEAN bTimedOut)
|
||||||
|
{
|
||||||
|
DEBUG_INFO("Parent process exited, exiting...");
|
||||||
|
CNotifyWindow *window = (CNotifyWindow *)lpParam;
|
||||||
|
window->close();
|
||||||
|
}
|
||||||
|
|
||||||
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
|
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
|
||||||
{
|
{
|
||||||
wchar_t buffer[MAX_PATH];
|
wchar_t buffer[MAX_PATH];
|
||||||
@@ -79,46 +86,24 @@ int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!g_pipe.Init())
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
CNotifyWindow window;
|
CNotifyWindow window;
|
||||||
|
|
||||||
if (!g_pipe.Init())
|
HANDLE hWait;
|
||||||
|
if (!RegisterWaitForSingleObject(&hWait, hParent.Get(), DestroyNotifyWindow, &window, INFINITE, WT_EXECUTEONLYONCE))
|
||||||
|
DEBUG_ERROR_HR(GetLastError(), "Failed to RegisterWaitForSingleObject");
|
||||||
|
|
||||||
|
MSG msg;
|
||||||
|
while (GetMessage(&msg, NULL, 0, 0) > 0)
|
||||||
{
|
{
|
||||||
window.destroy();
|
TranslateMessage(&msg);
|
||||||
hParent.Close();
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true)
|
(void) UnregisterWait(hWait);
|
||||||
{
|
|
||||||
DWORD dwHandles = hParent.IsValid() ? 1 : 0;
|
|
||||||
LPHANDLE lpHandles = hParent.GetAddressOf();
|
|
||||||
|
|
||||||
DWORD dwResult = MsgWaitForMultipleObjects(dwHandles, lpHandles, FALSE, INFINITE, QS_ALLINPUT);
|
|
||||||
if (dwResult == WAIT_FAILED)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR_HR(GetLastError(), "MsgWaitForMultipleObjects Failed");
|
|
||||||
g_pipe.DeInit();
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
else if (dwResult == WAIT_OBJECT_0 + dwHandles)
|
|
||||||
{
|
|
||||||
MSG msg;
|
|
||||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
||||||
{
|
|
||||||
if (msg.message == WM_QUIT)
|
|
||||||
goto exit;
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_INFO("Parent process exited, exiting...");
|
|
||||||
hParent.Close();
|
|
||||||
window.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
DEBUG_INFO("Helper window destroyed.");
|
DEBUG_INFO("Helper window destroyed.");
|
||||||
g_pipe.DeInit();
|
g_pipe.DeInit();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
Reference in New Issue
Block a user