標籤:excel turn board clip 拖放 arch let 全域記憶體 搜尋
原文轉自 http://www.cnblogs.com/wind-net/archive/2012/11/01/2749558.html
剪下板:系統維護的一個全域公用記憶體地區.每次只允許一個進程對其進行訪問。
剪下板操作方法如下:(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_MOVEABLE和GMEM_ZEROINT塊標誌聯合使用,即可移動同時初始化為0
GPTR
GMEM_FIXED和GMEM_ZEROINT標誌聯合使用,即不可移動同時初始化為0
1. 將資料儲存到剪下板
void CMFC_TabCtrlDlg::SetClipBoardData_(CString strText){ /* OpenClipboard開啟剪下板:指定關聯到開啟的剪下板的視窗控制代碼,傳入NULL表示關聯到當前任務。每次只允許一 個進程開啟並訪問。每開啟一次就要關閉,否則其他進程無法訪問剪下板。 EmptyClipboard清空剪下板:寫入前必須先清空,得到佔有權 */ if (::OpenClipboard(m_hWnd) &&::EmptyClipboard()) { //根據環境變數擷取資料長度 size_t cbStr = (strText.GetLength() + 1) * sizeof(TCHAR); //在堆上動態分配以位元組為單位的全域記憶體地區。成功則指向該記憶體,失敗NULL。參數:1.分配記憶體屬性,2.大小 HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, cbStr); if (hMem == NULL) { //關閉剪下板,釋放剪下板所有權,關閉後就不能寫入資料 CloseClipboard(); return; } //鎖定由GlobalAlloc分配的記憶體,並將記憶體對象的鎖定計數器+1;成功返回指向記憶體對象起始地址的指標。失敗NULL LPTSTR lpDest = (LPTSTR)GlobalLock(hMem); /* 系統為每個全域記憶體對象維護一個鎖定計數器,初始為0,GlobalLock使計數器+1, */ //拷貝資料到剪貼簿記憶體。 memcpy_s(lpDest, cbStr, strText.LockBuffer(), cbStr); strText.UnlockBuffer(); //解除記憶體鎖定,將屬性為GMEM_MOVEABLE的記憶體對象計數器-1. GlobalUnlock(hMem); /* GlobalUnLock計數器-1.一旦計數器值大於0,這塊記憶體地區將不允許被移動或刪除,只 有當為0時,才解除對這塊記憶體的鎖定。如果分配時GMEM_FIXED屬性,計數器一直為0 */ //根據環境變數設定資料格式 UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR))?CF_UNICODETEXT:CF_TEXT; //設定資料到剪貼簿。執行成功,返回資料控制代碼,否則返回NULL if(SetClipboardData(uiFormat, hMem) == NULL); { CloseClipboard(); return; } CloseClipboard(); }}
2.從剪下板記憶體擷取資料
void CMFC_TabCtrlDlg::GetClipBoardData_(void){ //if (IsClipboardFormatAvailable(CF_UNICODETEXT)) //判斷某種格式的資料是否可用 if(::OpenClipboard(m_hWnd)) { UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR))?CF_UNICODETEXT:CF_TEXT; ////執行成功,返回資料控制代碼,否則返回NULL。參數:1.資料格式,2.指定格式的資料的控制代碼 HGLOBAL hMem = GetClipboardData(uiFormat); if (hMem != NULL) { //擷取UNICODE的字串。 LPCTSTR lpStr = (LPCTSTR)GlobalLock(hMem); if (lpStr != NULL) { SetDlgItemText(IDC_EDIT1, lpStr); } GlobalUnlock(hMem); } } CloseClipboard();}
【Windows API】OpenClipboard --- 剪下板(轉)