1. 程式人生 > >windows 剪貼簿監控

windows 剪貼簿監控

迅雷下載或者旋風下載都有一個很有意思的剪貼簿監控功能,當你開啟剪貼簿監控時,如果你複製了一個下載的URL,這兩個程式都會彈出來下載框來讓你去下載,顯得很智慧,昨天發現靈格斯詞霸也有個剪貼簿取詞功能。

上個月寫了個智慧登錄檔定位器,輸入一段登錄檔字串,能為你開啟登錄檔編輯器並定位到相應的登錄檔位置,有個哥麼說想智慧點,當我複製登錄檔字串時,給我自動拷貝到輸入框去啊,後來就研究了一下剪貼簿監控,發現還是蠻簡單的,原來這一切,微軟都給我們想好了,:-)。

這是智慧登錄檔定位器的外觀

 智慧登錄檔定位器

首先你要把一個視窗控制代碼傳到windows的剪貼簿監聽鏈中,使用API:SetClipboardViewer,這樣在使用者複製或者剪下時,Windows會給我們的視窗傳送一個WM_DRAWCLIPBOARD訊息。而且,當有其他程式加入或者退出這個監聽者連結串列時,Windows會給我們的視窗傳送一個WM_CHANGECBCHAIN訊息。注意:當自己的視窗接收到這兩個訊息時,應該使用SendMessage函式來把訊息傳送給下一個監聽者。

m_hNextClipboard = ::SetClipboardViewer(GetSafeHwnd());呼叫該API會返回下一個監聽的視窗控制代碼,這個要儲存下來,等下有用。

我下面的說明都是以MFC為例的,SDK裡面怎麼做,其實是類似的,我就不加說明了,我也沒試過,但是原理是一樣的。

然後對映兩個訊息:ON_WM_CHANGECBCHAIN() 和 ON_WM_DRAWCLIPBOARD()

標頭檔案裡面新增如下兩個訊息函式宣告:

afx_msg void OnChangeCbChain(HWND hWndRemove, HWND hWndAfter);

afx_msg void OnDrawClipboard();

WM_CHANGECBCHAIN訊息的處理,程式碼如下:

當有其他程式加入或者退出windows剪貼簿監控鏈時,你會收到此訊息,兩個引數hWndRemove正要移出剪貼簿監聽鏈的視窗控制代碼,hWndAfter是移出監聽鏈的視窗控制代碼的下一個監聽視窗控制代碼,此時你要處理兩件事情,如果退出的視窗控制代碼剛好是當前監聽視窗的下一個控制代碼,則把hWndAfter賦值給m_hNextClipboard,保持整個監聽鏈的聯通,如果不是的話則給m_hNextClipboard傳送一個相同的WM_CHANGECBCHAIN訊息,最終目的也是保持整個監聽鏈的聯通性。這是屬於一個規範的問題,試想如果有一個程式不這樣做,則會造成監聽鏈斷裂,某些加入了監聽鏈的視窗就會收不到系統傳送的剪貼簿訊息了(原因是因為系統只給剪貼簿鏈的頭髮送ON_WM_DRAWCLIPBOARD()訊息,然後每個視窗負責給後面剪貼簿視窗鏈上的視窗傳送ON_WM_DRAWCLIPBOARD()訊息,如果你沒有正確處理ON_WM_CHANGECBCHAIN訊息,會造成某個視窗不能更新自己的下一個監聽鏈視窗控制代碼,整個鏈就斷了,鏈在它之後的視窗就收不到剪貼簿變化訊息了)。

ON_WM_DRAWCLIPBOARD訊息處理,程式碼如下:

開啟剪貼簿,獲取資料的方法這裡就不說明了,我這裡只想強調的是,一定要給監聽鏈上的下一個視窗傳送一個相同的ON_WM_DRAWCLIPBOARD訊息,否則會怎麼樣,你可以自己寫個程式試試。

在視窗銷燬時,應該使這個視窗退出windwos剪貼簿監控鏈,使用API:ChangeClipboardChain,傳入呼叫SetClipboardViewer時的控制代碼。

附錄

原始碼下載:

我在網上找了一些剪貼簿的API,可以去查查MSDN,嘿嘿,你想監控啥型別的資料就自己去程式設計實現啦。

(一)ChangeClipboardChain
將剪貼的連線從一個控制代碼轉到下一個控制代碼。
BOOL ChangeClipboardChain(
HWND hWndRemove, // handle to window to remove
HWND hWndNewNext // handle to next window
);
(1)hWndRemove表示第一個視窗的控制代碼(斷開)。
(2)hWndNewNext表示第二個視窗的控制代碼(連線)。
注意,在使用之前應該使用SetClipboardViewer事先進行視窗控制代碼的連線。
(二)CloseClipboard
關閉剪貼簿。
BOOL CloseClipboard(VOID)//VOID意思是空白。
本函式沒有引數,事先應該用OpenClipboard函式開啟過剪貼簿。
(三)CountClipboardFormats
不管剪貼簿是什麼格式,全部轉化為資料格式。
int CountClipboardFormats(VOID)
本函式沒有引數。
(四)EmptyClipboard
清空剪貼簿。
BOOL EmptyClipboard(VOID)
本函式沒有引數。
(五)EnumClipboardFormats
使剪貼簿內的格式轉變成指定格式。
UINT EnumClipboardFormats(
UINT format // specifies a known available clipboard format
);
其中format表示的是將要轉化成的格式。該引數的意義可參照後面。
(六)GetClipboardData
獲取剪貼簿內的資料。
HANDLE GetClipboardData(
UINT uFormat // clipboard format
);
其中format表示的是剪貼簿內資料的格式。該引數的意義可參照後面。
(七)GetClipboardFormatName
獲取剪貼簿內資料格式的名稱。
int GetClipboardFormatName(
UINT format, // clipboard format to retrieve
LPTSTR lpszFormatName, // address of buffer for name
int cchMaxCount // length of name string in characters
);
(1)format表示的意義同前,應該是不事先規定格式;
(2)lpszFormatName表示的是格式名稱地址;
(3)cchMaxCount剪貼簿內資料的長度。
(八)GetClipboardOwner
獲取當前剪貼簿是屬於哪一個視窗的控制代碼。
HWND GetClipboardOwner(VOID)
返回那個視窗的控制代碼。
(九)GetClipboardSequenceNumber
返回剪貼簿序號。
DWORD GetClipboardSequenceNumber(VOID)
(十)GetClipboardViewer
返回剪貼簿屬於視窗的控制代碼。
HWND GetClipboardViewer(VOID)
(十一)GetOpenClipboardWindow
返回開啟剪貼簿的那個視窗控制代碼。
HWND GetOpenClipboardWindow(VOID)
(十二)GetPriorityClipboardFormat
int GetPriorityClipboardFormat(
UINT *paFormatPriorityList, // address of priority list
int cFormats // number of entries in list
);
(十三)IsClipboardFormatAvailable
判斷剪貼簿的格式。
BOOL IsClipboardFormatAvailable(
UINT format // clipboard format
);
其中format表示的是剪貼簿內資料的格式。該引數的意義可參照後面。
(十四)OpenClipboard
開啟剪貼簿。
BOOL OpenClipboard(
HWND hWndNewOwner // handle to window opening clipboard
);
返回剪貼簿的控制代碼。
(十五)RegisterClipboardFormat
註冊新的剪貼簿格式。
UINT RegisterClipboardFormat(
LPCTSTR lpszFormat // address of name string
);
lpszFormat新的剪貼簿格式名稱。
(十六)SetClipboardData
設定剪貼簿內的資料。
HANDLE SetClipboardData(
UINT uFormat, // clipboard format
HANDLE hMem // data handle
);
uFormat表示的是要放進剪貼簿資料的格式;
hMem表示資料的地址指標。
(十七)SetClipboardViewer
將剪貼簿內容連線到視窗。
HWND SetClipboardViewer(
HWND hWndNewViewer // handle to clipboard viewer window
);
hWndNewViewer表示要連線到的那個視窗控制代碼。
上文中剪貼簿格式Format的可選引數如下:
CF_BITMAP點陣圖格式;
CF_DIB
CF_DIBV5
CF_DIF
CF_DSPBITMAP
CF_DSPENHMETAFILE
CF_DSPMETAFILEPICT
CF_DSPTEXT
CF_ENHMETAFILE
CF_GDIOBJFIRST
CF_GDIOBJLAST
CF_HDROP
CF_LOCALE
CF_METAFILEPICT
CF_OEMTEXT
CF_OWNERDISPLAY
CF_PALETTE
CF_PENDATA
CF_PRIVATEFIRST
CF_PRIVATELAST
CF_RIFF
CF_SYLK
CF_TEXT文字格式;
CF_WAVE音樂格式;
CF_TIFF
CF_UNICODETEXT

【END】