无法收到 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);
}
我正在尝试为我的 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);
}