我正在使用全局钩子编写dll。其中一项任务是查看剪贴板并在有人执行复制操作时从中删除所有数据。这是我的窗口回调函数:
string test("my data");
LRESULT CALLBACK WndHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_CREATE:
nextClipboardViewer = SetClipboardViewer(windowHandler);
MessageBeep(MB_ICONINFORMATION);
break;
case WM_CHANGECBCHAIN:
if((HWND) wParam == nextClipboardViewer)
nextClipboardViewer == (HWND) lParam;
else if(nextClipboardViewer != NULL)
SendMessage(nextClipboardViewer, msg, wParam, lParam);
break;
case WM_DRAWCLIPBOARD:
if(OpenClipboard(windowHandler)) {
EmptyClipboard();
HGLOBAL hClipboardData;
hClipboardData = GlobalAlloc(GMEM_MOVEABLE, test.size() + 1);
char * pchData;
pchData = (char*)GlobalLock(hClipboardData);
memcpy(pchData, test.c_str(), test.size() + 1);
GlobalUnlock(hClipboardData);
SetClipboardData(CF_TEXT, hClipboardData);
CloseClipboard();
}
SendMessage(nextClipboardViewer, msg, wParam, lParam);
break;
case WM_DESTROY:
ChangeClipboardChain(windowHandler, nextClipboardViewer);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
return 0;
}
我只是在剪贴板中尝试替换信息,但此代码不起作用。
更新:现在我使用隐形窗口和SetClipboardViewer来监控更改。但剪贴板中的数据不会改变。
答案 0 :(得分:1)
我怀疑在处理WM_DRAWCLIPBOARD
消息时更改剪贴板的内容真的很安全 - 至少我很惊讶你没有触发无限循环(因为你打电话给{{1} }和EmptyClipboard()
可能会触发另一条SetClipboardData()
消息)。可能系统有防范 - 我从未试图找出 - 但它仍然感觉不对:)
尝试这个版本,a)将剪贴板更新移动到窗口自身发布的单独消息(将其移到剪贴板更改通知代码之外)和b)使用全局标志来忽略它自己做出的更改。 / p>
(注意:我认为代码的实际错误是当您处理WM_DRAWCLIPBOARD
时,尚未分配WM_CREATE
。您可能会将其设置为值windowHandler
返回,但是在处理CreateWindowEx
时WM_CREATE
尚未实际返回。这意味着剪贴板查看器实际上从未正确建立。我已更改引用以使用CreateWindowEx
来修复此。)
hwnd