我正在用全局钩子写入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来监视更改。但是剪贴板中的数据不会改变。
发布于 2013-08-19 19:59:11
我怀疑在处理WM_DRAWCLIPBOARD消息时更改剪贴板的内容是否真的安全--至少我很惊讶您没有触发无限循环(因为对EmptyClipboard()和SetClipboardData()的调用可能会触发另一条WM_DRAWCLIPBOARD消息)。也许这个系统对此有保护--我从来没有想过要找出--但它还是感觉不对:)
试试这个版本,其中:
注意:我认为您的代码的实际错误是在处理WM_CREATE时,还没有分配windowHandler。您大概是将其设置为CreateWindowEx返回的值,但在处理WM_CREATE时,CreateWindowEx实际上还没有返回。这意味着剪贴板查看器从未真正正确地建立起来。我已经更改了引用,以使用hwnd来修复这个问题。
string test("my data");
#define MSG_UPDATECLIPBOARD (WM_APP + 1)
static bool g_fIgnoreClipboardChange = false;
LRESULT CALLBACK WndHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_CREATE:
nextClipboardViewer = SetClipboardViewer(hwnd);
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 (!g_fIgnoreClipboardChange)
PostMessage(hwnd, MSG_UPDATECLIPBOARD, 0, 0);
if(nextClipboardViewer != NULL)
SendMessage(nextClipboardViewer, msg, wParam, lParam);
break;
case MSG_UPDATECLIPBOARD:
g_fIgnoreClipboardChange = true;
if(OpenClipboard(hwnd)) {
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();
}
g_fIgnoreClipboardChange = false;
break;
case WM_DESTROY:
ChangeClipboardChain(hwnd, nextClipboardViewer);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
return 0;
}https://stackoverflow.com/questions/18311274
复制相似问题