實現網路螞蟻的實時監視剪貼簿功能 (轉)

worldblog發表於2007-12-15
實現網路螞蟻的實時監視剪貼簿功能 (轉)[@more@]

實現螞蟻的實時監視剪貼簿功能
  作者:黑龍江省五大連池  馬明臣 
 我們知道,網路螞蟻能夠實時地監視剪貼簿,如果我們能夠在自己的中實現這個功能,肯定為我們的程式增色不少。
 那它到底是如何實現的呢?我們可以想到的最簡單的方法是,直接開個計時器,定時檢查剪貼簿上的內容,或者另寫個執行緒來檢查。這兩個方法都能夠監視剪貼簿,但遺憾的是實時性太差,又佔用了的大量資源,很不合算。好一點的方法可以用中關於剪貼簿鉤子(HOOK)的,只要了剪貼簿的鉤子函式,就可以做到實時地監視剪貼簿,因為任何剪貼簿的改變都會觸發一條訊息,而鉤子函式攔截了這條資訊。然而,這要求當前程式必須要有機會獲得控制權才能處理這個訊息。如果該程式這時並沒有釋放CPU,監視剪貼簿的程式並不能處理訊息。只有當該程式完了之後,別的程式才能獲得處理機會,但此時,剪貼簿只剩下最後一次貼上的內容了。而且,使用鉤子函式非常危險,一旦你的程式出了問題,整個系統也就跟著癱瘓了。
既然這些方法都不太理想,那我們不妨轉換一下思維,不再去管剪貼簿,而想想如何讓剪貼簿直接向自己的程式發訊息,這樣肯定能做到百分之百的實時。為此我仔細的檢視了各種的資料,結果是:因為剪貼簿不具有自己的控制程式碼(Handle),它本身也不是Windows的一個類,故剪貼簿是不會自己發訊息的。但是系統是如何能夠接收剪下/複製到剪貼簿等命令呢?也即是如何接收WM_COPY和WM_CUT,WM_PASTE等訊息呢?經過研究發現能夠傳送訊息的是剪貼簿檢視器,原來多個剪貼簿檢視器依次連線成剪貼簿檢視鏈。因此,要實現實時監視剪貼簿必須將自己的程式註冊成為剪貼簿檢視器(即加入連結串列中)。下面筆者以C++ Builder 5.0為例程式設計說明其具體實現過程。
首先新建一個工程,在Form1上增加一個Memo,然後在Form1的.h裡面加上#include ,因為下面要用到的API函式大多是在該頭中定義的。
在Form1的.h的public加上:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DRAWCLIPBOARD,TMessage,ClipboardChanged) //對映這個訊息
END_MESSAGE_MAP(TForm)
HWND LastHandle;// 用於儲存剪貼簿檢視器鏈中下一個視窗的控制程式碼。
 接下來,當然是把自己的程式視窗註冊成為剪貼簿檢視器了。在Form1的OnCreate事件中加入一句:
 LastHandle=SetClipboardViewer(Form1->Handle);
 該函式會將指定的視窗加入剪貼簿檢視器鏈,引數handle就是你欲新加入的視窗的控制程式碼,返回值則為系統的剪貼簿檢視器鏈中下一個視窗的控制程式碼。
 當你自己的程式退出時,必須從剪貼簿檢視器鏈中刪除本視窗。在Form1的OnClose事件中加入兩句:
ChangeClipboardChain(Form1->Handle,LastHandle);
 函式ChangeClipboardChain是SetClipboardViewer的逆操作,能將第一個引數handle指定的視窗從剪貼簿檢視器鏈中刪除,第二個引數是剪貼簿檢視器鏈中下一個視窗的控制程式碼,是供系統調整剪貼簿檢視器連結串列用的,我們不用管它。
 最後一步,也是最關鍵的一步,如果剪貼簿內容有變化,視窗將自動啟用 WM_DRAWCLIPBOARD訊息,也即間接地實現了讓剪貼簿向自己的程式發訊息的功能,這就能夠實時監視剪貼簿,相信網路螞蟻也應該是用這個方法。有一點要注意的是,在接收處理WM_DRAWCLIPBOARD訊息時要將訊息傳遞給剪貼簿檢視鏈中的下一個視窗,以便讓其它程式也能監視剪貼簿,因為該訊息只直接發給鏈中的第一個程式,其他程式不會直接收到該訊息。
 程式如下,在Form1的.h的private加上:
void __fastcall ClipboardChanged(TMessage& Msg);
 再編寫自己的處理過程,這就是你自由發揮的地方了。本例設為自動將剪貼簿的文字貼上到Memo控制元件中。
 在Form1的.cpp內加上:
void __fastcall TForm1::ClipboardChanged(TMessage& Msg)
{
 if (Clipboard()->Haormat(CF_TEXT))
  Memo1->Text = Clipboard()->AsText;
 } 
 這一過程中使用了 TClipboard 類的 Clipboard 函式獲取剪貼簿內文字內容,至於如何獲取剪貼簿內的其它非文字型別的內容則不在本文討論範圍內了,讀者可自己在C++ Builder中輸入TClipboard ,再按F1,鍵,就可以看到各個函式的詳細用法了,不過這些幫助可都是英文的呀!
以上程式在C++ Builder 5.0+P系統下透過,由於筆者水平有限,上文如有不妥之處,請大家與我一起探討。

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993838/,如需轉載,請註明出處,否則將追究法律責任。

相關文章