无法收到 WM_CLIPBOARDUPDATE 条消息

Cannot receive WM_CLIPBOARDUPDATE messages

我正在尝试为我的 C++ 控制台应用程序使用剪贴板格式侦听器。目标是监视剪贴板中的每个更改。我创建了 MessageOnly window,在 WM_CREATE 中成功调用了 AddClipboardFormatListener,但从未在 WindowProc 函数中收到 WM_CLIPBOARDUPDATE 消息。

#include <iostream>
#include "windows.h"

using namespace std;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        if (AddClipboardFormatListener(hwnd))
            cout << "    Listener started" << endl;
        else
            cout << "    Start listener failed" << endl;
        break;

    case WM_DESTROY:
        if (RemoveClipboardFormatListener(hwnd))
            cout << "    Listener stopped" << endl;
        else
            cout << "    Stop listener failed" << endl;
        break;

    case WM_CLIPBOARDUPDATE:
        // Clipboard content has changed

        cout << "    Clipboard updated" << endl;
        break;

    default:
        break;
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int main(int argc, char* argv[])
{
    HWND hWindow = nullptr;

    static const wchar_t* className = L"ClipboardListener";
    WNDCLASSEX wx = {};
    wx.cbSize = sizeof(WNDCLASSEX);
    wx.lpfnWndProc = WindowProc;
    wx.hInstance = GetModuleHandle(NULL);
    wx.lpszClassName = className;
    if (!RegisterClassEx(&wx)) {
        cout << "Cannot register class" << endl;
    }
    else
    {
        hWindow = CreateWindowEx(
            0,
            className,
            L"ClipboardListener",
            0, 0, 0, 0, 0,
            HWND_MESSAGE,
            NULL, NULL, NULL);
    }

    if (!hWindow)
    {
        cout << "Cannot create window" << endl;
    }
    else
    {
        while (true)
        {
            // Peek for a WM_CLIPBOARDUPDATE message
            MSG message = { 0 };
            PeekMessage(&message, hWindow, WM_CLIPBOARDUPDATE, WM_CLIPBOARDUPDATE, PM_REMOVE);
            if (message.message == WM_CLIPBOARDUPDATE)
            {
                cout << "Sample window received WM_CLIPBOARDUPDATE message" << endl;
            }
        }   
    }

    cin.get();

    DestroyWindow(hWindow);

    return 0;
}

PeekMessage 效果很好,但我不想使用循环接收消息。 如果我删除 PeekMessage 或将 PM_REMOVE 替换为 PM_NOREMOVE,则没有任何变化。

你的消息循环是错误的。

CreateWindowEx() 在退出前发送一条 WM_CREATE 消息,这就是您的 WindowProc() 收到该消息的原因。

但是,PeekMessage() 不会向 windows 发送消息,这就是为什么您的 WindowProc() 没有收到 WM_CLIPBOARDUPDATE 消息的原因。您的消息循环需要为此调用 DispatchMessage()。您还应该使用 GetMessage() 而不是 PeekMessage(),这样当没有要处理的消息时,循环会使调用线程休眠。

一个标准的消息循环看起来更像这样:

MSG message;
while (GetMessage(&message, NULL, 0, 0))
{
    TranslateMessage(&message);
    DispatchMessage(&message);
}