我正在尝试对我的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,则没有任何变化。
您的消息循环是错误的。
[CreateWindowEx()
在退出前发送WM_CREATE
消息,这就是您的WindowProc()
收到该消息的原因。
但是,PeekMessage()
不会将消息发送到Windows,这就是为什么WindowProc()
无法接收WM_CLIPBOARDUPDATE
消息的原因。为此,您的消息循环需要调用DispatchMessage()
。您还应该使用GetMessage()
而不是PeekMessage()
,以便在没有消息要处理时,循环使调用线程休眠。
标准消息循环看起来更像这样:
MSG message;
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}