分享

【MoreWindows工作笔记12】WM

 宇文江齐 2019-04-06

有很多程序会监视剪贴板,比如迅雷,这样当你复制一个迅雷下载链接时,迅雷就可以自动启动并创建一个新的下载任务。下面我们就来看看如何实现这个技术。

实现这个技术一共需要4步:

第一步:Add the window to the clipboard viewer chain.

通过SetClipboardViewer()传入窗口句柄,所有监视剪贴板的窗口句柄会组成一个链表(后来者靠前)。这样当剪贴板内容发生变化时,Windows系统给给这些窗口发生消息。

第二步:Process the WM_CHANGECBCHAIN message.

当这个监视剪贴板的窗口句柄链表发生变化时,会收到这个消息。每个窗口都应该给下一个窗口传递消息。

这个消息的wParamlParam说明如下:

wParam表示

A handle to the window being removedfrom the clipboard viewer chain

lParam表示

A handle to the next window in thechain following the window being removed. This parameter is NULL if thewindow being removed is the last window in the chain

第三步:Process the WM_DRAWCLIPBOARD message.

当剪贴板数据发送变化时,窗口会依次收到这个消息。

第四步:Remove the window from the clipboard viewer chain before itis destroyed.

当窗口关闭时,应该调用ChangeClipboardChain()来通知Windows系统将自己从监视剪贴板的窗口句柄链表中移除。

代码如下(下载地址:http://download.csdn.net/download/morewindows/6793027

  1. <code class='language-cpp'>// 【MoreWindows工作笔记12】WM_DRAWCLIPBOARD 监视剪切板  
  2. // http://blog.csdn.net/morewindows/article/details/17655429  
  3. // By MoreWindows( http://blog.csdn.net/MoreWindows )  
  4. BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)  
  5. {  
  6.   static HWND s_hwnd_new_clipboard_viewer = NULL;  
  7.   static HWND s_hwnd_edit_clipboard_info = NULL;  
  8.   
  9.     switch (message)  
  10.     {  
  11.     case WM_INITDIALOG:  
  12.     // 4-1 Add the window to the clipboard viewer chain.   
  13.     s_hwnd_new_clipboard_viewer = SetClipboardViewer(hDlg);  
  14.     // 把hwnd加入监视链,返回上一个加入的窗口句柄,如果是第一个,则返回值为NULL。新加的窗口在链条头部,成为“当前监视器”  
  15.         CenterWindow(hDlg);  
  16.     s_hwnd_edit_clipboard_info = GetDlgItem(hDlg, IDC_EDIT_CLIPBOARD_INFO);  
  17.         return FALSE;  
  18.   
  19.   // 4-2 Process the WM_CHANGECBCHAIN message.   
  20.   case WM_CHANGECBCHAIN:  
  21.     if ((HWND)wParam == s_hwnd_new_clipboard_viewer)  
  22.       s_hwnd_new_clipboard_viewer = (HWND)lParam;  
  23.     else  
  24.       SendMessage(s_hwnd_new_clipboard_viewer, message, wParam, lParam);  
  25.   
  26.   // 4-3 Process the WM_DRAWCLIPBOARD message.   
  27.   case WM_DRAWCLIPBOARD:  //剪切板内容发生变化  
  28.     if (OpenClipboard(hDlg)) {  
  29.       UINT clipboard_format = EnumClipboardFormats(0);  
  30.       HGLOBAL global_memory = GetClipboardData(clipboard_format);  
  31.       DWORD data_size = GlobalSize(global_memory);  
  32.       CloseClipboard();  
  33.       WCHAR clipboard_info[1024];  
  34.       swprintf(clipboard_info, L'Clipboard\r\n Data Format = %x\r\n Data Address = 0x%x\r\n Data Size = %d', clipboard_format, global_memory, data_size);  
  35.       if (clipboard_format == CF_UNICODETEXT) {  
  36.         LPCWSTR clipboard_data = (LPCWSTR)GlobalLock(global_memory);  
  37.         if (clipboard_data != NULL) {  
  38.           wcscat(clipboard_info, L'\r\nData: \r\n');  
  39.           WCHAR buffer[1024];  
  40.           DWORD data_size = GlobalSize(global_memory);  
  41.           for (size_t i = 0; i < data_size; i )  
  42.             buffer[i] = clipboard_data[i];  
  43.           buffer[data_size] = L'\0';  
  44.           wcscat(clipboard_info, buffer);  
  45.         }  
  46.       }  
  47.       SetWindowTextW(s_hwnd_edit_clipboard_info, clipboard_info);  
  48.     }  
  49.     return FALSE;  
  50.   
  51.     case WM_COMMAND:  
  52.         switch (LOWORD(wParam))  
  53.         {  
  54.         case IDOK:  
  55.         case IDCANCEL:  
  56.       // 4-4 Remove the window from the clipboard viewer chain before it is destroyed.   
  57.       ChangeClipboardChain(hDlg, s_hwnd_new_clipboard_viewer);  
  58.             EndDialog(hDlg, FALSE);  
  59.             return TRUE;  
  60.         }  
  61.         break;  
  62.     }  
  63.     return FALSE;  
  64. }</code>  
  1. // 【MoreWindows工作笔记12】WM_DRAWCLIPBOARD 监视剪切板
  2. // http://blog.csdn.net/morewindows/article/details/17655429
  3. // By MoreWindows( http://blog.csdn.net/MoreWindows )
  4. BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  5. {
  6. static HWND s_hwnd_new_clipboard_viewer = NULL;
  7. static HWND s_hwnd_edit_clipboard_info = NULL;
  8. switch (message)
  9. {
  10. case WM_INITDIALOG:
  11. // 4-1 Add the window to the clipboard viewer chain.
  12. s_hwnd_new_clipboard_viewer = SetClipboardViewer(hDlg);
  13. // 把hwnd加入监视链,返回上一个加入的窗口句柄,如果是第一个,则返回值为NULL。新加的窗口在链条头部,成为“当前监视器”
  14. CenterWindow(hDlg);
  15. s_hwnd_edit_clipboard_info = GetDlgItem(hDlg, IDC_EDIT_CLIPBOARD_INFO);
  16. return FALSE;
  17. // 4-2 Process the WM_CHANGECBCHAIN message.
  18. case WM_CHANGECBCHAIN:
  19. if ((HWND)wParam == s_hwnd_new_clipboard_viewer)
  20. s_hwnd_new_clipboard_viewer = (HWND)lParam;
  21. else
  22. SendMessage(s_hwnd_new_clipboard_viewer, message, wParam, lParam);
  23. // 4-3 Process the WM_DRAWCLIPBOARD message.
  24. case WM_DRAWCLIPBOARD: //剪切板内容发生变化
  25. if (OpenClipboard(hDlg)) {
  26. UINT clipboard_format = EnumClipboardFormats(0);
  27. HGLOBAL global_memory = GetClipboardData(clipboard_format);
  28. DWORD data_size = GlobalSize(global_memory);
  29. CloseClipboard();
  30. WCHAR clipboard_info[1024];
  31. swprintf(clipboard_info, L'Clipboard\r\n Data Format = %x\r\n Data Address = 0x%x\r\n Data Size = %d', clipboard_format, global_memory, data_size);
  32. if (clipboard_format == CF_UNICODETEXT) {
  33. LPCWSTR clipboard_data = (LPCWSTR)GlobalLock(global_memory);
  34. if (clipboard_data != NULL) {
  35. wcscat(clipboard_info, L'\r\nData: \r\n');
  36. WCHAR buffer[1024];
  37. DWORD data_size = GlobalSize(global_memory);
  38. for (size_t i = 0; i < data_size; i )
  39. buffer[i] = clipboard_data[i];
  40. buffer[data_size] = L'\0';
  41. wcscat(clipboard_info, buffer);
  42. }
  43. }
  44. SetWindowTextW(s_hwnd_edit_clipboard_info, clipboard_info);
  45. }
  46. return FALSE;
  47. case WM_COMMAND:
  48. switch (LOWORD(wParam))
  49. {
  50. case IDOK:
  51. case IDCANCEL:
  52. // 4-4 Remove the window from the clipboard viewer chain before it is destroyed.
  53. ChangeClipboardChain(hDlg, s_hwnd_new_clipboard_viewer);
  54. EndDialog(hDlg, FALSE);
  55. return TRUE;
  56. }
  57. break;
  58. }
  59. return FALSE;
  60. }

运行程序,复制《【霍比特人2:史矛革之战】》的下载链接,然后程序会显示:

最后再列一下目录,方便大家查看。

1.《【MoreWindows工作笔记9OleGetClipboard 访问剪切板的文本内容》

http://blog.csdn.net/morewindows/article/details/17655053

2.《【MoreWindows工作笔记10OleGetClipboard 访问剪切板上的文件信息》

http://blog.csdn.net/morewindows/article/details/17655057

3.《【MoreWindows工作笔记11EnumClipboardFormats剪切板内容的数据格式》

http://blog.csdn.net/morewindows/article/details/17655299

4.《【MoreWindows工作笔记12WM_DRAWCLIPBOARD 监视剪切板》

http://blog.csdn.net/morewindows/article/details/17655429

本文地址:http://blog.csdn.net/morewindows/article/details/17655429   转载请标明出处,谢谢。

欢迎关注微博:http://weibo.com/MoreWindows 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多