正确使用AddClipboardFormatListener并订阅WM_CLIPBOARDUPDATE消息

问题描述 投票:1回答:2

我目前正在尝试在应用程序中使用Windows剪贴板及其通知。具体来说,我正在尝试使用WM_CLIPBOARDUPDATE功能订阅WM_CLIPBOARDUPDATE窗口消息。以前,我一直使用AddClipboardFormatListener()函数将窗口直接添加到剪贴板查看器链中。这工作得很好,并且在预期时我收到了相关的消息AddClipboardFormatListener()SetClipboardViewer()。但是,我想避免继续使用剪贴板链,因为它的波动性很大。

我的理解是,致电SetClipboardViewer()后,我将完全能够接收WM_DRAWCLIPBOARD。在这里我还缺少其他步骤吗?我需要怎么做才能确保我正确接收到此消息?就目前情况而言,执行复制操作时不会收到它。

这是我的代码的简短示例:

WNDPROC替代:

WM_DESTROYCLIPBOARD

由构造函数调用:

WM_CLIPBOARDUPDATE

这是一个由.NET包装器调用的COM接口,但在这种情况下,我认为这两件事都不与我的问题有关(图上我会以防万一)。

c++ winapi clipboard wndproc window-messages
2个回答
0
投票
RegisterClass/Ex()

-1
投票
例如,基于Windows桌面应用程序项目模板,您需要做的是调用WndProc并添加CreateWindowEx()开关大小写。

HINSTANCE g_hThisInst = NULL; HWND g_hwndCurrent = NULL; //HWND g_hwndNext = NULL; bool g_AddedListener = false; BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { g_hThisInst = hinstDLL; return TRUE; } LRESULT CALLBACK ClipboardService::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: //g_hwndNext = ::SetClipboardViewer(hwnd); g_AddedListener = ::AddClipboardFormatListener(hwnd); return g_AddedListener ? 0 : -1; case WM_DESTROY: /* ChangeClipboardChain(hwnd, g_hwndNext); g_hwndNext = NULL; */ if (g_AddedListener) { RemoveClipboardFormatListener(hwnd); g_AddedListener = false; } return 0; /* case WM_CHANGECBCHAIN: if (g_hwndNext == (HWND)wParam) g_hwndNext = (HWND)lParam; else if (g_hwndNext) SendMessage(g_hwndNext, uMsg, wParam, lParam); break; case WM_DRAWCLIPBOARD: // Handle clipboard available event if (g_hwndNext) SendMessage(g_hwndNext, uMsg, wParam, lParam); break; */ case WM_CLIPBOARDUPDATE: // Handle clipboard updated event return 0; case WM_DESTROYCLIPBOARD: // Handle clipboard cleared event and forward message break; } return ::DefWindowProc(hwnd, uMsg, wParam, lParam); } HRESULT ClipboardService::SetOrRefreshWindowsHook() { try { if (!g_hwndCurrent) { WNDCLASS wndClass = {}; wndClass.lpfnWndProc = &ClipboardService::WndProc; wndClass.hInstance = g_hThisInst; wndClass.lpszClassName = TEXT("ClipboardMessageWindow"); if (!::RegisterClass(&wndClass)) { DWORD dwLastError = ::GetLastError(); if (dwLastError != ERROR_CLASS_ALREADY_EXISTS) return HRESULT_FROM_WIN32(dwLastError); } g_hwndCurrent = ::CreateWindowEx(0, wndClass.lpszClassName, "", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, g_hThisInst, NULL); if (!g_hwndCurrent) { DWORD dwLastError = ::GetLastError(); return HRESULT_FROM_WIN32(dwLastError); } g_This = this; } } catch (...) { return E_UNEXPECTED; } return S_OK; }

AddClipboardFormatListener

© www.soinside.com 2019 - 2024. All rights reserved.