【发布时间】:2021-04-04 01:05:51
【问题描述】:
我试图实现的目标是收听有关锁定、解锁等的会话通知。由于架构和避免阻塞主线程,我必须在另一个线程中执行此操作。这是我正在做的事情:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_WTSSESSION_CHANGE:
switch (wParam) {
case WTS_CONSOLE_CONNECT:
case WTS_SESSION_LOGON:
case WTS_REMOTE_CONNECT:
case WTS_SESSION_UNLOCK:
case WTS_CONSOLE_DISCONNECT:
case WTS_REMOTE_DISCONNECT:
case WTS_SESSION_LOGOFF:
case WTS_SESSION_LOCK:
case WTS_SESSION_REMOTE_CONTROL:
case WTS_SESSION_CREATE:
case WTS_SESSION_TERMINATE:
break;
default:
break;
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
void startListeningNotifications()
{
const wchar_t g_szClassName[] = L"myWindowClass";
WNDCLASSEX wc = {};
wc.lpfnWndProc = WndProc;
wc.lpszClassName = g_szClassName;
wc.cbSize = sizeof(WNDCLASSEX);
if (!RegisterClassEx(&wc))
{
return;
}
HWND hwnd = CreateWindowEx(NULL, g_szClassName, L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
if (hwnd == NULL)
{
return;
}
if (!WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_ALL_SESSIONS))
{
return;
}
ShowWindow(hwnd, SW_HIDE);
MSG Msg = {};
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
int main()
{
std::thread listener(startListeningNotifications);
listener.join();
return 0;
}
我现在面临的问题是我不知道如何正确编写 stopListeningNotifications() 方法。我必须以某种方式破坏我的窗口并退出消息循环。请建议如何安全地做到这一点。提前致谢。
【问题讨论】:
-
您应该知道,每个消息循环都在它自己的线程中运行。因此,简单地向该窗口发送消息并不是一个好主意。我会尝试使用
std::condition_variable来表示它应该关闭的窗口。如果收到通知,接收窗口可以简单地调用它自己的Close()函数。 -
PostMessageW(hwnd, WM_CLOSE, 0, 0) -
但是这个线程安全吗?
-
当然是线程安全的。这里有什么不安全的地方?
标签: c++ multithreading winapi thread-safety createwindow