Windows API——OpenClipboard——剪切板

剪切板:系統維護的一個全局公共內存區域.每次只允許一個進程對其進行訪問。

剪切板操作方法如下:(MSDN上搜索Clipboard Operations)

1.打開剪切板
Bool OpenClipboard(HWND hWndNewOwner);
  指定關聯到打開的剪切板的窗口句柄,傳入NULL表示關聯到當前任務。每次只允許一個進程打開並訪問。

每打開一次就要關閉,否則其他進程無法訪問剪切板。


2.清空剪切板
Bool EmptyClipboard(void)

  寫入前必須先清空,得到剪切板佔有權

3.分配內存
HGLOBAL GlobalAlloc(UINT uFlags, SIZE_T dwBytes);
  在堆上動態分配以字節爲單位的內存區域。成功則指向該內存,失敗NULL。參數:1.分配內存屬性, 2.分配的大小


4.鎖定內存
LPVOID GlobalLock(HGLOBAL hMem);
  鎖定由GlobalAlloc分配的內存,並將內存對象的鎖定計數器+1,成功返回指向內存對象起始地址的指針。失敗NULL

系統爲每個全局內存對象維護一個鎖定計數器,初始爲0,GlobalLock使計數器+1,GlobalUnLock計數器-1.一旦計數器值大於0,

這塊內存區域將不允許被移動或刪除,只有當爲0時,才解除對這塊內存的鎖定。如果分配時GMEM_FIXED屬性,計數器一直爲0

5.設置剪切板
HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);

  執行成功,返回數據句柄,否則返回NULL

6.解除鎖定
BOOL GlobalUnlock(HGLOBAL hMem);
  將GlobalAlloc分配的屬性爲GMEM_MOVEABLE的內存對象計數器-1.

 

7.關閉剪切板
Bool CloseClipboard(void);

  必須關閉剪切板其他進程才能使用剪切板,且關閉後當前進程就不能寫入數據。

8.獲取剪切板數據
HANDLE GetClipboardData(UINT uFormat);

  執行成功,返回數據句柄,否則返回NULL數據格式,指定格式的數據的句柄

 

一:UINT uFormate格式說明:標準剪貼簿數據格式

Windows支持不同的預先定義剪貼簿格式, 這些格式在WINUSER.H定義成以CF爲前綴的標識符。

■三種能夠儲存在剪貼簿上的文字數據型態:

CF_TEXT    以NULL結尾的ANSI字符集字符串。它在每行末尾包含一個carriage  return和linefeed字符,這是最簡單的剪貼簿數據格式。

CF_OEMTEXT    含有文字數據(與CF_TEXT類似)的內存塊。但是它使用的是OEM字符集。

CF_UNICODETEXT    含有Unicode文字的內存塊。與CF_TEXT類似,它在每一行的末尾包含一個carriage  return和linefeed字符,以及一個NULL字符(兩個0字節)以表示數據結束。CF_UNICODETEXT只支援Windows NT。

■兩種附加的剪貼簿格式、但是它們不需要以NULL結尾,因爲格式已經定義了數據的結尾。

CF_SYLK    包含Microsoft 「符號連結」數據格式的整體內存塊。這種格式用在Microsoft的Multiplan、Chart和Excel程序之間交換數據,它是一種ASCII碼格式。

CF_DIF    包含數據交換格式(DIF)之數據的整體內存塊。用於把數據送到VisiCalc電子表格程序中。這也是一種ASCII碼格式

■下面三種剪貼簿格式與位圖有關。所謂位圖就是數據位的矩形數組

CF_BITMAP    與設備相關的位圖格式。位圖是通過位圖句柄傳送給剪貼簿的。

CF_DIB    定義一個設備無關位圖的內存塊。

CF_PALETTE    調色盤句柄。

■下面是兩個metafile格式、metafile就是一個以二進制格式儲存的畫圖命令集

CF_METAFILEPICT    以舊的metafile格式存放的「圖片」 。

CF_ENHMETAFILE    增強型metafile(32位Windows支持的)句柄。

■最後介紹幾個混合型的剪貼簿格式:

CF_PENDATA與Windows的筆式輸入擴充功能聯合使用。

CF_WAVE聲音(波形)文件。

CF_RIFF使用資源交換文件格式(Resource Interchange File Format)的多媒體數據。

CF_HDROP與拖放服務相關的文件列表。

 

二:UINT uFlags格式說明:內存屬性

GMEM_FIXED

  分配一塊固定的內存區域,不允許系統移動,這時返回值是一個指針。

GMEM_MOVEABLE

  分配一塊可移動的內存區域,實際上內存塊在物理內存中是不可移動的,這裏的可移動指的是在應用程序的默認邏輯堆內可以移動。返回值是內存對象的句柄。可以通過調研GlobalLock()函數將一個句柄轉化爲一個指針,這個標誌不能喝GMEM_FIXED 同時使用

GMEM_ZEROINT   

  初始化內存對象爲全0,如果不用這個標誌,內存對象將爲不確定的內容

GHND

  GMEM_MOVEABLEGMEM_ZEROINT塊標誌聯合使用,即可移動同時初始化爲0

GPTR

  GMEM_FIXEDGMEM_ZEROINT標誌聯合使用,即不可移動同時初始化爲0

 1 void  CMFC_TabCtrlDlg::SetClipBoardData_(CString strText)
 2 {
 3     /*
 4     OpenClipboard打開剪切板:指定關聯到打開的剪切板的窗口句柄,傳入NULL表示關聯到當前任務。每次只允許一
 5     個進程打開並訪問。每打開一次就要關閉,否則其他進程無法訪問剪切板。
 6     EmptyClipboard清空剪切板:寫入前必須先清空,得到佔有權
 7     */
 8     if (::OpenClipboard(m_hWnd) &&::EmptyClipboard())
 9     {
10         //根據環境變量獲取數據長度
11         size_t cbStr = (strText.GetLength() + 1) * sizeof(TCHAR);
12 
13         //在堆上動態分配以字節爲單位的全局內存區域。成功則指向該內存,失敗NULL。參數:1.分配內存屬性,2.大小
14         HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, cbStr); 
15 
16         if (hMem == NULL) 
17         {
18             //關閉剪切板,釋放剪切板所有權,關閉後就不能寫入數據
19             CloseClipboard();
20             return; 
21         }
22 
23         //鎖定由GlobalAlloc分配的內存,並將內存對象的鎖定計數器+1;成功返回指向內存對象起始地址的指針。失敗NULL
24         LPTSTR lpDest = (LPTSTR)GlobalLock(hMem);
25         /*
26         系統爲每個全局內存對象維護一個鎖定計數器,初始爲0,GlobalLock使計數器+1,
27         */
28 
29         //拷貝數據到剪貼板內存。
30         memcpy_s(lpDest, cbStr, strText.LockBuffer(), cbStr);
31         strText.UnlockBuffer();
32 
33         //解除內存鎖定,將屬性爲GMEM_MOVEABLE的內存對象計數器-1.
34         GlobalUnlock(hMem); 
35         /*
36         GlobalUnLock計數器-1.一旦計數器值大於0,這塊內存區域將不允許被移動或刪除,只
37         有當爲0時,才解除對這塊內存的鎖定。如果分配時GMEM_FIXED屬性,計數器一直爲0
38 
39         */
40 
41         //根據環境變量設置數據格式
42         UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR))?CF_UNICODETEXT:CF_TEXT;
43 
44         //設置數據到剪貼板。執行成功,返回數據句柄,否則返回NULL
45         if(SetClipboardData(uiFormat, hMem) == NULL); 
46         {
47             CloseClipboard();
48             return;
49         }
50 
51         CloseClipboard();
52     }
53 }

 

2.從剪切板內存獲取數據

 1 void CMFC_TabCtrlDlg::GetClipBoardData_(void)
 2 {
 3     //if (IsClipboardFormatAvailable(CF_UNICODETEXT)) //判斷某種格式的數據是否可用
 4     if(::OpenClipboard(m_hWnd))
 5     {
 6         UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR))?CF_UNICODETEXT:CF_TEXT;
 7 
 8         ////執行成功,返回數據句柄,否則返回NULL。參數:1.數據格式,2.指定格式的數據的句柄
 9         HGLOBAL hMem = GetClipboardData(uiFormat); 
10 
11         if (hMem != NULL) 
12         { 
13             //獲取UNICODE的字符串。
14             LPCTSTR lpStr = (LPCTSTR)GlobalLock(hMem); 
15             if (lpStr != NULL) 
16             { 
17                 SetDlgItemText(IDC_EDIT1, lpStr);
18             } 
19             GlobalUnlock(hMem);
20         } 
21     }
22     CloseClipboard();
23 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章