1. 程式人生 > >閒來無事,說說Windows剪貼簿 -- 剪貼簿概述部分

閒來無事,說說Windows剪貼簿 -- 剪貼簿概述部分


<小fisher首發office精英俱樂部-http://www.officefans.net/cdb/,轉載請註明出處>
  首先,討論一下剪貼簿是什麼
  Windows的幫助檔案中對剪貼簿的描述是這樣的:剪貼簿是從一個地方複製或移動並打算在其他地方使用的資訊的臨時儲存區域。可以選擇文字或圖形,然後使用“剪下”或“複製”命令將所選內容移動到剪貼簿,在使用“貼上”命令將該內容插入到其他地方之前,它會一直儲存在剪貼簿中。例如,您可能要複製網站上的一部分文字,然後將其貼上到電子郵件中。大多數 Windows 程式中都可以使用剪貼簿。
  對於經常使用Ctrl+C/X、Ctrl+V的Windows使用者來說,這個解釋是非常易懂並且符合人們感觀上的認識的。
  既然我們今天討論的話題是如何在VBA程式中通過API呼叫剪貼簿,那就先看看微軟MSDN中對於剪貼簿的定義吧:剪貼簿是一組用於在多個應用程式之間交換資料的函式和訊息(原文:The clipboard is a set of functions and messages that enable applications to transfer data)。
  呵呵,是不是有些暈?沒關係,因為這句話是針對C/C++程式設計師給出的說明,我們仍然可以按習慣上的理解把它當做一個物件(使用過VB6的同志們可能更容易理解,因為VB6中確實有一個名字叫ClipBoard的物件,它其實是VB對windows的剪貼簿API函式封裝後產生的真正的物件)。
  然後,再來看看這個物件有什麼特點,又是如何工作的呢?概括來說,剪貼簿有以下的特性(這是我個人總結的,不一定正確或精確,也不一定全面):
公開性
剪貼簿中的資料存放在全域性記憶體中,因此大部分的windows應用程式都可以訪問其中的資料,在遵守相關API函式約定的前提下,應用程式可以自由地開啟剪貼簿(OpenClipboard),讀取剪貼簿內的資料(GetClipboardData)、或者清空剪貼簿(EmptyClipboard)、然後設定剪貼簿內的資料(SetClipboardData),最後關閉剪貼簿(CloseClipboard);
獨佔性
既然剪貼簿是公開的,那麼多個程式同時訪問必然會導致衝突,比如資料互相覆蓋。因此,Windows規定應用程式對剪貼簿的訪問是獨佔性的,當一個應用程式使用OpenClipboard開啟剪貼簿之後,其他程式 就不可以再訪問剪貼簿,直至前一程式使用CloseClipboard關閉剪貼簿 。通常我們使用剪貼簿的時候不會感覺受其他程式的影響,這是因為剪貼簿內的資料操作都是在記憶體中進行的,速度非常快,對於特大塊的資料,應用程式還可以選擇延時處理(Delayed Rendering)機制以保證速度。但是,我們在對剪貼簿程式設計的時候要注意以下兩點:1)每次使用完剪貼簿之後一定要記得使用CloseClipBoard關閉 它;2)在OpenClipboard和CloseClipboard之間不要放置耗時很長的程式碼,以免影響其他程式正常工作。
設定剪貼簿內資料的應用程式視窗被稱為剪貼簿資料擁有者(ClipboardOwner),可以通過GetClipboardOwner函式獲得它的控制代碼。反過來說,如果一個應用程式想向剪貼簿中放入資料,需要先成為ClipboardOwner。程式要成為ClipboardOwner需要先將自己的控制代碼傳給OpenClipboard函式,如果剪貼簿中已經有資料存在,還需要先呼叫EmptyClipboard;
多元性
剪貼簿中可以同時存放多種格式的資料,各自放在全域性記憶體的不同位置 ;剪貼簿中的資料有標準格式/預定義格式的,如文字、點陣圖、Wav聲音……;也有非標準格式/使用者自定義格式,比如word中的域和公式、Excel中的圖表
可檢索性
對於每種在剪貼簿中存放過的格式,Windows都會給它分配一個獨特的長整型編號,通過這個編號可以知道對應的資料格式的名稱(GetClipboardFormatName),或者 查詢對應的資料在剪貼簿中是否存在(IsClipBoardFormatAvailable),如果存在,還可以通過這個編號找到對應的資料在記憶體中存放的位置(GetClipboardData);
對於標準格式,這個編號是固定的,可以通過VB6自帶的APIViewer查詢以CF_開頭的常量得到,比如:
Public Const CF_TEXT = 1
Public Const CF_BITMAP = 2
Public Const CF_METAFILEPICT = 3
Public Const CF_SYLK = 4
……
對於非標準格式,這個編號由提供此格式資料的應用程式給此格式定義一個名稱,然後將此名稱傳遞給RegisterClipboardFormat函式,如果此名稱已經存在,函式將返回此名稱對應的編號,如果此名稱不存在,函式將返回一個之前未使用的編號,在系統關機重啟之前,這個名稱和編號可以一直使用下去。
可監視性
有一組特別的視窗可以持續監視剪貼簿內的資料變化,這組視窗被稱作剪貼簿觀察程式(ClipboardViewer),由它們構成的這個小圈子叫作剪貼簿觀察程式鏈ClipBoardViewerChain,每當剪貼簿內資料發生變化時,windows將向訊息鏈中的第一個視窗傳送一個WM_DRAWCLIPBOARD訊息,再由它轉發給第二個……直至訊息到達訊息鏈中的最後一個視窗,同樣,當訊息鏈中的成員發生變化時,每個視窗都會收到一個WM_CHANGECBCHAIN訊息;
通過SetClipboardViewer函式,應用程式可以將自己的視窗控制代碼告訴windows,從而註冊成為剪貼簿觀察程式鏈中的一員;通過ChangeClipboardChain函式,應用程式可以退出剪貼簿觀察程式鏈而不影響它後面的視窗繼續接收相關訊息。
希望以上文字能對大家重新認識剪貼簿能夠有所幫助。休息一會兒,我們再討論剪貼簿在Office VBA中的用途。