【发布时间】:2022-07-26 23:18:18
【问题描述】:
我编写了一个小型测试应用程序,它通过延迟渲染将文件(带有硬编码路径)插入到当前活动的文件夹/应用程序中。它按预期工作。但我有一个问题——为什么PeekMessage 总是返回FALSE?但是如果你删除PeekMessage 调用,Wndproc 将永远不会被调用。我读过类似的post,但我正在尝试处理消息的同一线程中创建一个窗口。
代码:
static LRESULT CALLBACK WindProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
switch (Msg) {
case WM_RENDERALLFORMATS: {
OpenClipboard(hWnd);
EmptyClipboard();
}
case WM_RENDERFORMAT: {
printf("WM_RENDERFORMAT received");
<Here the file paths are copied to the clipboard>
if (Msg == WM_RENDERALLFORMATS)
CloseClipboard();
return 0;
}
case WM_DESTROYCLIPBOARD:
return 0;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
HWND hwnd_;
void thread_(void* ignored) {
WNDCLASSEX wcx = { 0 };
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.lpfnWndProc = WindProc;
wcx.hInstance = GetModuleHandle(NULL);
wcx.lpszClassName = TEXT("my_class");
RegisterClassEx(&wcx);
hwnd_ = CreateWindowEx(0, TEXT("my_class"), TEXT(""), 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
MSG msg;
while (true) {
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
printf("PeekMessage returned TRUE\n");
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
}
Sleep(1000);
}
}
void main() {
CloseHandle((HANDLE)_beginthread(thread_, 0, NULL));
// let's give some time to thread to create msg window
Sleep(100);
if (OpenClipboard(hwnd_)) {
EmptyClipboard();
SetClipboardData(CF_HDROP, NULL);
CloseClipboard();
}
while (true) {
Sleep(100);
}
}
【问题讨论】:
-
我希望你不打算使用剪贴板进行线程间数据传递,这是完全不合适的。
-
CreateWindowEx成功了吗? -
当然,否则什么都做不了
-
绝对值得添加所有缺失的错误检查(不要忽略返回值)。但也许
PeekMessage返回FALSE,因为没有排队的消息。要么是那个,要么是窗口句柄无效。 -
大概是因为
PeekMessage调度了跨线程发送的消息(见When can a thread receive window messages?)。
标签: c++ multithreading winapi peekmessage