【问题标题】:PeekMessage always returns FALSEPeekMessage 总是返回 FALSE
【发布时间】: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


【解决方案1】:

为什么PeekMessage 总是返回FALSE

假设您传递给PeekMessage 的窗口句柄是有效的,那么PeekMessage 返回FALSE 的原因仅仅是队列中没有消息。

这种情况可以从documentation 中看出:

如果消息可用,则返回值非零。

如果没有消息可用,则返回值为零。

【讨论】:

    猜你喜欢
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 2016-07-20
    • 2021-11-05
    • 2018-11-05
    • 2019-05-06
    • 2017-04-29
    • 2013-04-30
    相关资源
    最近更新 更多