我目前正在尝试在我的应用程序中使用 Windows 剪贴板及其通知。具体来说,我正在尝试WM_CLIPBOARDUPDATE
使用该AddClipboardFormatListener()
函数订阅窗口消息。以前,我一直在使用该SetClipboardViewer()
功能将我的窗口直接添加到剪贴板查看器链中。这工作得很好,我已经收到了相关的消息WM_DRAWCLIPBOARD
,并且WM_DESTROYCLIPBOARD
在预期的时候。但是,我想避免继续使用剪贴板链,因为它可能很不稳定。
WM_CLIPBOARDUPDATE
我的理解是打电话后我完全可以接听AddClipboardFormatListener()
。我还缺少另一个步骤吗?我需要做些什么来确保我能正确收到此消息?就目前而言,执行复制操作时我没有收到它。
这是我的代码的一个简化示例:
WNDPROC 覆盖:
LRESULT CALLBACK ClipboardService::CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
switch ( pMsg->message )
{
case WM_DRAWCLIPBOARD:
// Handle clipboard available event and forward message
break;
case WM_CLIPBOARDUPDATE:
// This is never triggered
break;
case WM_DESTROYCLIPBOARD:
// Handle clipboard cleared event and forward message
break;
}
return ::CallNextHookEx( g_Hook, nCode, wParam, lParam );
}
由构造函数调用:
HRESULT ClipboardService::SetOrRefreshWindowsHook()
{
HRESULT hr = S_OK;
try
{
if (!m_bHookSet)
{
g_hwndCurrent = ::CreateWindowEx(0, "Message", "ClipboardMessageWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
m_dwThreadID = ::GetWindowThreadProcessId(g_hwndCurrent, &m_dwProcessID);
_Module.Lock();
SetLastError(0);
g_Hook = ::SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, 0, m_dwThreadID);
//g_hwndNext = ::SetClipboardViewer(g_hwndCurrent); old way to subscribe
// This is what I expect should subscribe me to WM_CLIPBOARDUPDATE messages
if (!::AddClipboardFormatListener(g_hwndCurrent))
hr_exit(E_UNEXPECTED);
DWORD dwLastError = ::GetLastError();
g_This = this;
m_bHookSet = true;
}
}
catch (...)
{
hr_exit(E_UNEXPECTED);
}
wrapup:
return hr;
}
这是一个由 .NET 包装器调用的 COM 接口,但我认为在这种情况下,这两件事中的任何一个都与我的问题无关(我想以防万一)。