Windows API——OpenClipboard——剪切板
剪切板:系統(tǒng)維護(hù)的一個(gè)全局公共內(nèi)存區(qū)域.每次只允許一個(gè)進(jìn)程對(duì)其進(jìn)行訪問(wèn)。
剪切板操作方法如下:(MSDN上搜索Clipboard Operations)
1.打開(kāi)剪切板
Bool OpenClipboard(HWND hWndNewOwner);
指定關(guān)聯(lián)到打開(kāi)的剪切板的窗口句柄,傳入NULL表示關(guān)聯(lián)到當(dāng)前任務(wù)。每次只允許一個(gè)進(jìn)程打開(kāi)并訪問(wèn)。
每打開(kāi)一次就要關(guān)閉,否則其他進(jìn)程無(wú)法訪問(wèn)剪切板。
2.清空剪切板
Bool EmptyClipboard(void)
寫(xiě)入前必須先清空,得到剪切板占有權(quán)
3.分配內(nèi)存
HGLOBAL GlobalAlloc(UINT uFlags, SIZE_T dwBytes);
在堆上動(dòng)態(tài)分配以字節(jié)為單位的內(nèi)存區(qū)域。成功則指向該內(nèi)存,失敗NULL。參數(shù):1.分配內(nèi)存屬性, 2.分配的大小
4.鎖定內(nèi)存
LPVOID GlobalLock(HGLOBAL hMem);
鎖定由GlobalAlloc分配的內(nèi)存,并將內(nèi)存對(duì)象的鎖定計(jì)數(shù)器+1,成功返回指向內(nèi)存對(duì)象起始地址的指針。失敗NULL
系統(tǒng)為每個(gè)全局內(nèi)存對(duì)象維護(hù)一個(gè)鎖定計(jì)數(shù)器,初始為0,GlobalLock使計(jì)數(shù)器+1,GlobalUnLock計(jì)數(shù)器-1.一旦計(jì)數(shù)器值大于0,
這塊內(nèi)存區(qū)域?qū)⒉辉试S被移動(dòng)或刪除,只有當(dāng)為0時(shí),才解除對(duì)這塊內(nèi)存的鎖定。如果分配時(shí)GMEM_FIXED屬性,計(jì)數(shù)器一直為0
5.設(shè)置剪切板
HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);
執(zhí)行成功,返回?cái)?shù)據(jù)句柄,否則返回NULL
6.解除鎖定
BOOL GlobalUnlock(HGLOBAL hMem);
將GlobalAlloc分配的屬性為GMEM_MOVEABLE的內(nèi)存對(duì)象計(jì)數(shù)器-1.
?
7.關(guān)閉剪切板
Bool CloseClipboard(void);
必須關(guān)閉剪切板其他進(jìn)程才能使用剪切板,且關(guān)閉后當(dāng)前進(jìn)程就不能寫(xiě)入數(shù)據(jù)。
8.獲取剪切板數(shù)據(jù)
HANDLE GetClipboardData(UINT uFormat);
執(zhí)行成功,返回?cái)?shù)據(jù)句柄,否則返回NULL數(shù)據(jù)格式,指定格式的數(shù)據(jù)的句柄
?
一:UINT uFormate格式說(shuō)明:標(biāo)準(zhǔn)剪貼簿數(shù)據(jù)格式
Windows支持不同的預(yù)先定義剪貼簿格式, 這些格式在WINUSER.H定義成以CF為前綴的標(biāo)識(shí)符。
■三種能夠儲(chǔ)存在剪貼簿上的文字?jǐn)?shù)據(jù)型態(tài):
①CF_TEXT??? 以NULL結(jié)尾的ANSI字符集字符串。它在每行末尾包含一個(gè)carriage? return和linefeed字符,這是最簡(jiǎn)單的剪貼簿數(shù)據(jù)格式。
②CF_OEMTEXT??? 含有文字?jǐn)?shù)據(jù)(與CF_TEXT類(lèi)似)的內(nèi)存塊。但是它使用的是OEM字符集。
③CF_UNICODETEXT??? 含有Unicode文字的內(nèi)存塊。與CF_TEXT類(lèi)似,它在每一行的末尾包含一個(gè)carriage? return和linefeed字符,以及一個(gè)NULL字符(兩個(gè)0字節(jié))以表示數(shù)據(jù)結(jié)束。CF_UNICODETEXT只支援Windows NT。
■兩種附加的剪貼簿格式、但是它們不需要以NULL結(jié)尾,因?yàn)楦袷揭呀?jīng)定義了數(shù)據(jù)的結(jié)尾。
①CF_SYLK 包含Microsoft 「符號(hào)連結(jié)」數(shù)據(jù)格式的整體內(nèi)存塊。這種格式用在Microsoft的Multiplan、Chart和Excel程序之間交換數(shù)據(jù),它是一種ASCII碼格式。
②CF_DIF??? 包含數(shù)據(jù)交換格式(DIF)之?dāng)?shù)據(jù)的整體內(nèi)存塊。用于把數(shù)據(jù)送到VisiCalc電子表格程序中。這也是一種ASCII碼格式
■下面三種剪貼簿格式與位圖有關(guān)。所謂位圖就是數(shù)據(jù)位的矩形數(shù)組
①CF_BITMAP??? 與設(shè)備相關(guān)的位圖格式。位圖是通過(guò)位圖句柄傳送給剪貼簿的。
②CF_DIB??? 定義一個(gè)設(shè)備無(wú)關(guān)位圖的內(nèi)存塊。
③CF_PALETTE??? 調(diào)色盤(pán)句柄。
■下面是兩個(gè)metafile格式、metafile就是一個(gè)以二進(jìn)制格式儲(chǔ)存的畫(huà)圖命令集
①CF_METAFILEPICT??? 以舊的metafile格式存放的「圖片」 。
②CF_ENHMETAFILE??? 增強(qiáng)型metafile(32位Windows支持的)句柄。
■最后介紹幾個(gè)混合型的剪貼簿格式:
CF_PENDATA與Windows的筆式輸入擴(kuò)充功能聯(lián)合使用。
CF_WAVE聲音(波形)文件。
CF_RIFF使用資源交換文件格式(Resource Interchange File Format)的多媒體數(shù)據(jù)。
CF_HDROP與拖放服務(wù)相關(guān)的文件列表。
?
二:UINT uFlags格式說(shuō)明:內(nèi)存屬性
GMEM_FIXED
分配一塊固定的內(nèi)存區(qū)域,不允許系統(tǒng)移動(dòng),這時(shí)返回值是一個(gè)指針。
GMEM_MOVEABLE
分配一塊可移動(dòng)的內(nèi)存區(qū)域,實(shí)際上內(nèi)存塊在物理內(nèi)存中是不可移動(dòng)的,這里的可移動(dòng)指的是在應(yīng)用程序的默認(rèn)邏輯堆內(nèi)可以移動(dòng)。返回值是內(nèi)存對(duì)象的句柄??梢酝ㄟ^(guò)調(diào)研GlobalLock()函數(shù)將一個(gè)句柄轉(zhuǎn)化為一個(gè)指針,這個(gè)標(biāo)志不能喝GMEM_FIXED 同時(shí)使用
GMEM_ZEROINT
初始化內(nèi)存對(duì)象為全0,如果不用這個(gè)標(biāo)志,內(nèi)存對(duì)象將為不確定的內(nèi)容
GHND
GMEM_MOVEABLE和GMEM_ZEROINT塊標(biāo)志聯(lián)合使用,即可移動(dòng)同時(shí)初始化為0
GPTR
GMEM_FIXED和GMEM_ZEROINT標(biāo)志聯(lián)合使用,即不可移動(dòng)同時(shí)初始化為0
?1?void??CMFC_TabCtrlDlg::SetClipBoardData_(CString?strText) ?2?{ ?3?????/* ?4?????OpenClipboard打開(kāi)剪切板:指定關(guān)聯(lián)到打開(kāi)的剪切板的窗口句柄,傳入NULL表示關(guān)聯(lián)到當(dāng)前任務(wù)。每次只允許一 ?5?????個(gè)進(jìn)程打開(kāi)并訪問(wèn)。每打開(kāi)一次就要關(guān)閉,否則其他進(jìn)程無(wú)法訪問(wèn)剪切板。 ?6?????EmptyClipboard清空剪切板:寫(xiě)入前必須先清空,得到占有權(quán) ?7?????*/ ?8?????if?(::OpenClipboard(m_hWnd)?&&::EmptyClipboard()) ?9?????{ 10?????????//根據(jù)環(huán)境變量獲取數(shù)據(jù)長(zhǎng)度 11?????????size_t?cbStr?=?(strText.GetLength()?+?1)?*?sizeof(TCHAR); 12? 13?????????//在堆上動(dòng)態(tài)分配以字節(jié)為單位的全局內(nèi)存區(qū)域。成功則指向該內(nèi)存,失敗NULL。參數(shù):1.分配內(nèi)存屬性,2.大小 14?????????HGLOBAL?hMem?=?GlobalAlloc(GMEM_MOVEABLE,?cbStr);? 15? 16?????????if?(hMem?==?NULL)? 17?????????{ 18?????????????//關(guān)閉剪切板,釋放剪切板所有權(quán),關(guān)閉后就不能寫(xiě)入數(shù)據(jù) 19?????????????CloseClipboard(); 20?????????????return;? 21?????????} 22? 23?????????//鎖定由GlobalAlloc分配的內(nèi)存,并將內(nèi)存對(duì)象的鎖定計(jì)數(shù)器+1;成功返回指向內(nèi)存對(duì)象起始地址的指針。失敗NULL 24?????????LPTSTR?lpDest?=?(LPTSTR)GlobalLock(hMem); 25?????????/* 26?????????系統(tǒng)為每個(gè)全局內(nèi)存對(duì)象維護(hù)一個(gè)鎖定計(jì)數(shù)器,初始為0,GlobalLock使計(jì)數(shù)器+1, 27?????????*/ 28? 29?????????//拷貝數(shù)據(jù)到剪貼板內(nèi)存。 30?????????memcpy_s(lpDest,?cbStr,?strText.LockBuffer(),?cbStr); 31?????????strText.UnlockBuffer(); 32? 33?????????//解除內(nèi)存鎖定,將屬性為GMEM_MOVEABLE的內(nèi)存對(duì)象計(jì)數(shù)器-1. 34?????????GlobalUnlock(hMem);? 35?????????/* 36?????????GlobalUnLock計(jì)數(shù)器-1.一旦計(jì)數(shù)器值大于0,這塊內(nèi)存區(qū)域?qū)⒉辉试S被移動(dòng)或刪除,只 37?????????有當(dāng)為0時(shí),才解除對(duì)這塊內(nèi)存的鎖定。如果分配時(shí)GMEM_FIXED屬性,計(jì)數(shù)器一直為0 38? 39?????????*/ 40? 41?????????//根據(jù)環(huán)境變量設(shè)置數(shù)據(jù)格式 42?????????UINT?uiFormat?=?(sizeof(TCHAR)?==?sizeof(WCHAR))?CF_UNICODETEXT:CF_TEXT; 43? 44?????????//設(shè)置數(shù)據(jù)到剪貼板。執(zhí)行成功,返回?cái)?shù)據(jù)句柄,否則返回NULL 45?????????if(SetClipboardData(uiFormat,?hMem)?==?NULL);? 46?????????{ 47?????????????CloseClipboard(); 48?????????????return; 49?????????} 50? 51?????????CloseClipboard(); 52?????} 53?}
?
2.從剪切板內(nèi)存獲取數(shù)據(jù)
?1?void?CMFC_TabCtrlDlg::GetClipBoardData_(void) ?2?{ ?3?????//if?(IsClipboardFormatAvailable(CF_UNICODETEXT))?//判斷某種格式的數(shù)據(jù)是否可用 ?4?????if(::OpenClipboard(m_hWnd)) ?5?????{ ?6?????????UINT?uiFormat?=?(sizeof(TCHAR)?==?sizeof(WCHAR))?CF_UNICODETEXT:CF_TEXT; ?7? ?8?????????////執(zhí)行成功,返回?cái)?shù)據(jù)句柄,否則返回NULL。參數(shù):1.數(shù)據(jù)格式,2.指定格式的數(shù)據(jù)的句柄 ?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?}
?