无法接收WM_CLIPBOARDUPDATE消息

问题描述 投票:-1回答:1

我正在尝试对我的C ++控制台应用程序使用剪贴板格式监听器。目标是监视剪贴板中的每个更改。我创建了MessageOnly窗口,在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,则没有任何变化。

c++ winapi clipboard
1个回答
0
投票

您的消息循环是错误的。

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

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

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

MSG message;
while (GetMessage(&message, NULL, 0, 0))
{
    TranslateMessage(&message);
    DispatchMessage(&message);
}
© www.soinside.com 2019 - 2024. All rights reserved.