日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

剪贴板所有api函数

發(fā)布時(shí)間:2024/4/14 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 剪贴板所有api函数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
編寫(xiě)剪貼板相關(guān)程序是收集的相關(guān)API函數(shù)。
(一)ChangeClipboardChain
將剪貼的連接從一個(gè)句柄轉(zhuǎn)到下一個(gè)句柄。
BOOL ChangeClipboardChain(
HWND hWndRemove, // handle to window to remove
HWND hWndNewNext // handle to next window
);
(1)hWndRemove表示第一個(gè)窗口的句柄(斷開(kāi))。
(2)hWndNewNext表示第二個(gè)窗口的句柄(連接)。
注意,在使用之前應(yīng)該使用SetClipboardViewer事先進(jìn)行窗口句柄的連接。
(二)CloseClipboard
關(guān)閉剪貼板。
BOOL CloseClipboard(VOID)//VOID意思是空白。
本函數(shù)沒(méi)有參數(shù),事先應(yīng)該用OpenClipboard函數(shù)打開(kāi)過(guò)剪貼板。
(三)CountClipboardFormats
不管剪貼板是什么格式,全部轉(zhuǎn)化為數(shù)據(jù)格式。
int CountClipboardFormats(VOID)
本函數(shù)沒(méi)有參數(shù)。
(四)EmptyClipboard
清空剪貼板。
BOOL EmptyClipboard(VOID)
本函數(shù)沒(méi)有參數(shù)。
(五)EnumClipboardFormats
使剪貼板內(nèi)的格式轉(zhuǎn)變成指定格式。
UINT EnumClipboardFormats(
UINT format // specifies a known available clipboard format
);
其中format表示的是將要轉(zhuǎn)化成的格式。該參數(shù)的意義可參照后面。
(六)GetClipboardData
獲取剪貼板內(nèi)的數(shù)據(jù)。
HANDLE GetClipboardData(
UINT uFormat // clipboard format
);
其中format表示的是剪貼板內(nèi)數(shù)據(jù)的格式。該參數(shù)的意義可參照后面。
(七)GetClipboardFormatName
獲取剪貼板內(nèi)數(shù)據(jù)格式的名稱(chēng)。
int GetClipboardFormatName(
UINT format, // clipboard format to retrieve
LPTSTR lpszFormatName, // address of buffer for name
int cchMaxCount // length of name string in characters
);
(1)format表示的意義同前,應(yīng)該是不事先規(guī)定格式;
(2)lpszFormatName表示的是格式名稱(chēng)地址;
(3)cchMaxCount剪貼板內(nèi)數(shù)據(jù)的長(zhǎng)度。
(八)GetClipboardOwner
獲取當(dāng)前剪貼板是屬于哪一個(gè)窗口的句柄。
HWND GetClipboardOwner(VOID)
返回那個(gè)窗口的句柄。
(九)GetClipboardSequenceNumber
返回剪貼板序號(hào)。
DWORD GetClipboardSequenceNumber(VOID)
(十)GetClipboardViewer
返回剪貼板屬于窗口的句柄。
HWND GetClipboardViewer(VOID)
(十一)GetOpenClipboardWindow
返回打開(kāi)剪貼板的那個(gè)窗口句柄。
HWND GetOpenClipboardWindow(VOID)
(十二)GetPriorityClipboardFormat
int GetPriorityClipboardFormat(
UINT *paFormatPriorityList, // address of priority list
int cFormats // number of entries in list
);
(十三)IsClipboardFormatAvailable
判斷剪貼板的格式。
BOOL IsClipboardFormatAvailable(
UINT format // clipboard format
);
其中format表示的是剪貼板內(nèi)數(shù)據(jù)的格式。該參數(shù)的意義可參照后面。
(十四)OpenClipboard
打開(kāi)剪貼板。
BOOL OpenClipboard(
HWND hWndNewOwner // handle to window opening clipboard
);
返回剪貼板的句柄。
(十五)RegisterClipboardFormat
注冊(cè)新的剪貼板格式。
UINT RegisterClipboardFormat(
LPCTSTR lpszFormat // address of name string
);
lpszFormat新的剪貼板格式名稱(chēng)。
(十六)SetClipboardData
設(shè)置剪貼板內(nèi)的數(shù)據(jù)。
HANDLE SetClipboardData(
UINT uFormat, // clipboard format
HANDLE hMem // data handle
);
uFormat表示的是要放進(jìn)剪貼板數(shù)據(jù)的格式;
hMem表示數(shù)據(jù)的地址指針。
(十七)SetClipboardViewer
將剪貼板內(nèi)容連接到窗口。
HWND SetClipboardViewer(
HWND hWndNewViewer // handle to clipboard viewer window
);
hWndNewViewer表示要連接到的那個(gè)窗口句柄。
上文中剪貼板格式Format的可選參數(shù)如下:
CF_BITMAP位圖格式;
CF_DIB
CF_DIBV5
CF_DIF
CF_DSPBITMAP
CF_DSPENHMETAFILE
CF_DSPMETAFILEPICT
CF_DSPTEXT
CF_ENHMETAFILE
CF_GDIOBJFIRST
CF_GDIOBJLAST
CF_HDROP
CF_LOCALE
CF_METAFILEPICT
CF_OEMTEXT
CF_OWNERDISPLAY
CF_PALETTE
CF_PENDATA
CF_PRIVATEFIRST
CF_PRIVATELAST
CF_RIFF
CF_SYLK
CF_TEXT文本格式;
CF_WAVE音樂(lè)格式;
CF_TIFF
CF_UNICODETEXT


Windows剪貼板

  Windows剪貼板是一種比較簡(jiǎn)單同時(shí)也是開(kāi)銷(xiāo)比較小的IPC(InterProcess Communication,進(jìn)程間通訊)機(jī)制。Windows系統(tǒng)支持剪貼板IPC的基本機(jī)制是由系統(tǒng)預(yù)留的一塊全局共享內(nèi)存,用來(lái)暫存在各進(jìn)程間進(jìn)行交換的數(shù)據(jù):提供數(shù)據(jù)的進(jìn)程創(chuàng)建一個(gè)全局內(nèi)存塊,并將要傳送的數(shù)據(jù)移到或復(fù)制到該內(nèi)存塊;接受數(shù)據(jù)的進(jìn)程(也可以是提供數(shù)據(jù)的進(jìn)程本身)獲取此內(nèi)存塊的句柄,并完成對(duì)該內(nèi)存塊數(shù)據(jù)的讀取。

  為使剪貼板的這種IPC機(jī)制更加完善和便于使用,需要解決好如下三個(gè)問(wèn)題:提供數(shù)據(jù)的進(jìn)程在結(jié)束時(shí)Windows系統(tǒng)將刪除其創(chuàng)建的全局內(nèi)存塊,而接受數(shù)據(jù)的進(jìn)程則希望在其退出后剪貼板中的數(shù)據(jù)仍然存在,可以繼續(xù)為其他進(jìn)程所獲取;能方便地管理和傳送剪貼板數(shù)據(jù)句柄;能方便設(shè)置和確定剪貼板數(shù)據(jù)格式。為完善上述功能,Windows提供了存在于USER32.dll中的一組API函數(shù)、消息和預(yù)定義數(shù)據(jù)格式等,并通過(guò)對(duì)這些函數(shù)、消息的使用來(lái)管理在進(jìn)程間進(jìn)行的剪貼板數(shù)據(jù)交換。

  Windows系統(tǒng)為剪貼板提供了一組API函數(shù)和多種消息,基本可以滿(mǎn)足編程的需要。而且Windows還為剪貼板預(yù)定義了多種數(shù)據(jù)格式。通過(guò)這些預(yù)定義的格式,可以使接收方正確再現(xiàn)數(shù)據(jù)提供方放置于剪貼板中的數(shù)據(jù)內(nèi)容。

  文本剪貼板和位圖剪貼板的使用

  這兩種剪貼板是比較常用的。其中,文本剪貼板是包含具有格式CF_TEXT的字符串的剪貼板,是最經(jīng)常使用的剪貼板之一。在文本剪貼板中傳遞的數(shù)據(jù)是不帶任何格式信息的ASCII字符。若要將文本傳送到剪貼板,可以先分配一個(gè)可移動(dòng)全局內(nèi)存塊,然后將要復(fù)制的文本內(nèi)容寫(xiě)入到此內(nèi)存區(qū)域。最后調(diào)用剪貼板函數(shù)將數(shù)據(jù)放置到剪貼板:

注意:
下面代碼中:
1、HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + 1);
分配內(nèi)存長(zhǎng)度必須是dwLength + 1,否則在調(diào)用SetClipboardData時(shí)會(huì)出錯(cuò);可以通過(guò)調(diào)用 int i2 = ::GlobalSize(hGlobalMemory );來(lái)查看分配的長(zhǎng)度。

2、hGlobalMemory不能釋放,即不能調(diào)用::GlobalFree(hGlobalMemory),因?yàn)槿绻谝粋€(gè)程序中還要粘貼的話(huà)就必須不能釋放,否則在同一程序中粘貼時(shí)獲得的指針為NULL,但如果只在別的程序中粘貼則可以釋放。

以上兩條是在編制HsfBrowserCtl(HOOPS三維瀏覽控件)時(shí)總結(jié)出來(lái)的。可參看原碼中的復(fù)制、粘貼部分。
  DWORD dwLength = 100; // 要復(fù)制的字串長(zhǎng)度
HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + 1); // 分配內(nèi)存
LPBYTE lpGlobalMemory = (LPBYTE)GlobalLock(hGlobalMemory); // 鎖定內(nèi)存
for (int i = 0; i 〈 dwLength; i++) // 將"*"復(fù)制到全局內(nèi)存塊
 *lpGlobalMemory++ = '*';
 GlobalUnlock(hGlobalMemory); // 鎖定內(nèi)存塊解鎖
 HWND hWnd = GetSafeHwnd(); // 獲取安全窗口句柄
 ::OpenClipboard(hWnd); // 打開(kāi)剪貼板
 ::EmptyClipboard(); // 清空剪貼板
 ::SetClipboardData(CF_TEXT, hGlobalMemory); // 將內(nèi)存中的數(shù)據(jù)放置到剪貼板
 ::CloseClipboard(); // 關(guān)閉剪貼板



  這里以O(shè)penClipboard()打開(kāi)剪貼板,并在調(diào)用了EmptyClipboard()后使hWnd指向的窗口成為剪貼板的擁有者,一直持續(xù)到CloseClipboard()函數(shù)的調(diào)用。在此期間,剪貼板為擁有者所獨(dú)占,其他進(jìn)程將無(wú)法對(duì)剪貼板內(nèi)容進(jìn)行修改。

  從剪貼板獲取文本的過(guò)程與之類(lèi)似,首先打開(kāi)剪貼板并獲取剪貼板的數(shù)據(jù)句柄,如果數(shù)據(jù)存在就拷貝其數(shù)據(jù)到程序變量。由于GetClipboardData()獲取的數(shù)據(jù)句柄是屬于剪貼板的,因此用戶(hù)程序必須在調(diào)用CloseClipboard()函數(shù)之前使用它:



  HWND hWnd = GetSafeHwnd(); // 獲取安全窗口句柄
::OpenClipboard(hWnd); // 打開(kāi)剪貼板
HANDLE hClipMemory = ::GetClipboardData(CF_TEXT);// 獲取剪貼板數(shù)據(jù)句柄
DWORD dwLength = GlobalSize(hClipMemory); // 返回指定內(nèi)存區(qū)域的當(dāng)前大小
LPBYTE lpClipMemory = (LPBYTE)GlobalLock(hClipMemory); // 鎖定內(nèi)存
m_sMessage = CString(lpClipMemory); // 保存得到的文本數(shù)據(jù)
GlobalUnlock(hClipMemory); // 內(nèi)存解鎖
::CloseClipboard(); // 關(guān)閉剪貼板



  大多數(shù)應(yīng)用程序?qū)D形數(shù)據(jù)采取的是位圖的剪貼板數(shù)據(jù)格式。位圖剪貼板的使用與文本剪貼板的使用是類(lèi)似的,只是數(shù)據(jù)格式要指明為CF_BITMAP,而且在使用SetClipboardData()或GetClipboardData()函數(shù)時(shí)交給剪貼板或從剪貼板返回的是設(shè)備相關(guān)位圖句柄。下面這段示例代碼將把存在于剪貼板中的位圖數(shù)據(jù)顯示到程序的客戶(hù)區(qū):



  HWND hWnd = GetSafeHwnd(); // 獲取安全窗口句柄
::OpenClipboard(hWnd); // 打開(kāi)剪貼板
HANDLE hBitmap = ::GetClipboardData(CF_BITMAP); // 獲取剪貼板數(shù)據(jù)句柄
HDC hDC = ::GetDC(hWnd); // 獲取設(shè)備環(huán)境句柄
HDC hdcMem = CreateCompatibleDC(hDC); // 創(chuàng)建與設(shè)備相關(guān)的內(nèi)存環(huán)境
SelectObject(hdcMem, hBitmap); // 選擇對(duì)象
SetMapMode(hdcMem, GetMapMode(hDC)); // 設(shè)置映射模式
BITMAP bm; // 得到位圖對(duì)象
GetObject(hBitmap, sizeof(BITMAP), &bm);
BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); //位圖復(fù)制
::ReleaseDC(hWnd, hDC); // 釋放設(shè)備環(huán)境句柄
DeleteDC(hdcMem); // 刪除內(nèi)存環(huán)境
::CloseClipboard(); // 關(guān)閉剪貼板





多數(shù)據(jù)項(xiàng)和延遲提交技術(shù)

  要把數(shù)據(jù)放入剪貼板,在打開(kāi)剪貼板后一定要調(diào)用EmptyClipboard()函數(shù)清除當(dāng)前剪貼板中的內(nèi)容,而不可以在原有數(shù)據(jù)項(xiàng)基礎(chǔ)上追加新的數(shù)據(jù)項(xiàng)。但是,可以在EmptyClipboard()和CloseClipboard()調(diào)用之間多次調(diào)用SetClipboardData()函數(shù)來(lái)放置多個(gè)不同格式的數(shù)據(jù)項(xiàng)。例如:



  OpenClipboard(hWnd);
EmptyClipboardData();
SetClipboardData(CF_TEXT, hGMemText);
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();



  這時(shí)如果用CF_TEXT或CF_BITMAP等格式標(biāo)記去調(diào)用IsClipboardFormatAvailable()都將返回TRUE,表明這幾種格式的數(shù)據(jù)同時(shí)存在于剪貼板中。以不同的格式標(biāo)記去調(diào)用GetClipboardData()函數(shù)可以得到相應(yīng)的數(shù)據(jù)句柄。

  對(duì)于多數(shù)據(jù)項(xiàng)的剪貼板數(shù)據(jù),還可以用CountClipboardFormats()和EnumClipboardFormats()函數(shù)得到當(dāng)前剪貼板中存在的數(shù)據(jù)格式數(shù)目和具體的數(shù)據(jù)格式。EnumClipboardFormats()的函數(shù)原型為:



  UINT EnumClipboardFormats(UINT format);



  參數(shù)format指定了剪貼板的數(shù)據(jù)格式。如果成功執(zhí)行將返回format指定的格式的下一個(gè)數(shù)據(jù)格式值,如果format為最后的數(shù)據(jù)格式值,那么將返回0。由此不難寫(xiě)出處理剪貼板中所有格式數(shù)據(jù)項(xiàng)的程序段代碼:



  UINT format = 0; // 從第一種格式值開(kāi)始枚舉
OpenClipboard(hWnd);
while(format = EnumClipboardFormats(format))
{
…… // 對(duì)相關(guān)格式數(shù)據(jù)的處理
}
CloseClipboard();



  在數(shù)據(jù)提供進(jìn)程創(chuàng)建了剪貼板數(shù)據(jù)后,一直到有其他進(jìn)程獲取剪貼板數(shù)據(jù)前,這些數(shù)據(jù)都要占據(jù)內(nèi)存空間。如在剪貼板放置的數(shù)據(jù)量過(guò)大,就會(huì)浪費(fèi)內(nèi)存空間,降低對(duì)資源的利用率。為避免這種浪費(fèi),可以采取延遲提交(Delayed rendering)技術(shù),即由數(shù)據(jù)提供進(jìn)程先創(chuàng)建一個(gè)指定數(shù)據(jù)格式的空(NULL)剪貼板數(shù)據(jù)塊,直到有其他進(jìn)程需要數(shù)據(jù)或自身進(jìn)程要終止運(yùn)行時(shí)才真正提交數(shù)據(jù)。

  延遲提交的實(shí)現(xiàn)并不復(fù)雜,只需剪貼板擁有者進(jìn)程在調(diào)用SetClipboardData()將數(shù)據(jù)句柄參數(shù)設(shè)置為NULL即可。延遲提交的擁有者進(jìn)程需要做的主要工作是對(duì)WM_RENDERFORMAT、WM_DESTORYCLIPBOARD和WM_RENDERALLFORMATS等剪貼板延遲提交消息的處理。

  當(dāng)另一個(gè)進(jìn)程調(diào)用GetClipboardData()函數(shù)時(shí),系統(tǒng)將會(huì)向延遲提交數(shù)據(jù)的剪貼板擁有者進(jìn)程發(fā)送WM_RENDERFORMAT消息。剪貼板擁有者進(jìn)程在此消息的響應(yīng)函數(shù)中應(yīng)使用相應(yīng)的格式和實(shí)際的數(shù)據(jù)句柄來(lái)調(diào)用SetClipboardData()函數(shù),但不必再調(diào)用OpenClipboard()和EmptyClipboard()去打開(kāi)和清空剪貼板了。在設(shè)置完數(shù)據(jù)有也無(wú)須調(diào)用CloseClipboard()關(guān)閉剪貼板。如果其他進(jìn)程打開(kāi)了剪貼板并且調(diào)用EmptyClipboard()函數(shù)去清空剪貼板的內(nèi)容,接管剪貼板的擁有權(quán)時(shí),系統(tǒng)將向延遲提交的剪貼板擁有者進(jìn)程發(fā)送WM_DESTROYCLIPBOARD消息,以通知該進(jìn)程對(duì)剪貼板擁有權(quán)的喪失。而失去剪貼板擁有權(quán)的進(jìn)程在收到該消息后則不會(huì)再向剪貼板提交數(shù)據(jù)。另外,在延遲提交進(jìn)程在提交完所有要提交的數(shù)據(jù)后也會(huì)收到此消息。如果延遲提交剪貼板擁有者進(jìn)程將要終止,系統(tǒng)將會(huì)為其發(fā)送一條WM_RENDERALLFORMATS消息,通知其打開(kāi)并清除剪貼板內(nèi)容。在調(diào)用SetClipboardData()設(shè)置各數(shù)據(jù)句柄后關(guān)閉剪貼板。

  下面這段代碼將完成對(duì)數(shù)據(jù)的延遲提交,WM_RENDERFORMAT消息響應(yīng)函數(shù)OnRenderFormat()并不會(huì)立即執(zhí)行,當(dāng)有進(jìn)程調(diào)用GetClipboardData()函數(shù)從剪貼板讀取數(shù)據(jù)時(shí)才會(huì)發(fā)出該消息。在消息處理函數(shù)中完成對(duì)數(shù)據(jù)的提交:

  進(jìn)行延遲提交:



  HWND hWnd = GetSafeHwnd(); // 獲取安全窗口句柄
::OpenClipboard(hWnd); // 打開(kāi)剪貼板
::EmptyClipboard(); // 清空剪貼板
::SetClipboardData(CF_TEXT, NULL); // 進(jìn)行剪貼板數(shù)據(jù)的延遲提交
::CloseClipboard(); // 關(guān)閉剪貼板



  在WM_RENDERFORMAT消息的響應(yīng)函數(shù)中:



  DWORD dwLength = 100; // 要復(fù)制的字串長(zhǎng)度
HANDLE hGlobalMemory = GlobalAlloc(GHND, dwLength + 1); // 分配內(nèi)存塊
LPBYTE lpGlobalMemory = (LPBYTE)GlobalLock(hGlobalMemory); // 鎖定內(nèi)存塊
for (int i = 0; i 〈 dwLength; i++) // 將"*"復(fù)制到全局內(nèi)存塊
*lpGlobalMemory++ = '*';
GlobalUnlock(hGlobalMemory); // 鎖定內(nèi)存塊解鎖
::SetClipboardData(CF_TEXT, hGlobalMemory); // 將內(nèi)存中的數(shù)據(jù)放置到剪貼板
DSP和自定義數(shù)據(jù)格式的使用

  Windows系統(tǒng)預(yù)定義了三個(gè)帶“DSP”前綴的數(shù)據(jù)格式:CF_DSPTEXT、CF_DSPBITMAP和CF_DSPMETAFILEPICT。這是一些偽標(biāo)準(zhǔn)格式,用于表示在程序中定義的私有剪貼板數(shù)據(jù)格式。對(duì)于不同的程序,這些格式的規(guī)定是不同的,因此這些格式只針對(duì)某一具體程序的不同實(shí)例才有意義。

  為使用DSP數(shù)據(jù)格式,必須確保進(jìn)程本身與剪貼板擁有者進(jìn)程同屬一個(gè)程序。可以調(diào)用GetClipboardOwner()函數(shù)來(lái)獲取剪貼板擁有者窗口句柄,并調(diào)用GetClassName()來(lái)獲取窗口類(lèi)名:

HWND hClipOwner = GetClipboardOwner();
GetClassName(hClipOwner, &ClassName, 255);

  如果剪貼板擁有者窗口類(lèi)名同本進(jìn)程的窗口類(lèi)名一致,就可以使用帶有DSP前綴的剪貼板數(shù)據(jù)格式了。
除了使用Windows預(yù)定義的剪貼板數(shù)據(jù)格式外,也可以在程序中使用自定義的數(shù)據(jù)格式。對(duì)于自定義的數(shù)據(jù)格式lpszFormat,可以調(diào)用RegisterClipboardFormat()函數(shù)來(lái)登記,并獲取其返回的格式標(biāo)識(shí)值:

UINT format = RegisterClipboardFormat(lpszFormat);

  對(duì)此返回的格式標(biāo)識(shí)值的使用與系統(tǒng)預(yù)定義的格式標(biāo)識(shí)是一樣的。可以通過(guò)GetClipboardFormatName()函數(shù)來(lái)獲取自定義格式的ASCII名。

  小結(jié)

  本文主要對(duì)Windows編程中的剪貼板機(jī)制作了較為深入的討論,對(duì)其中常用的文本、位圖、DSP和自定義數(shù)據(jù)格式的使用方法以及多數(shù)據(jù)項(xiàng)和延遲提交等重要技術(shù)一并做了闡述。并給出了具體的程序示例代碼,使讀者能夠更好的掌握剪貼板機(jī)制的使用。


功能實(shí)現(xiàn):復(fù)制位圖到剪切阪。

今日看了下COleDataSource的原碼和網(wǎng)上的文章。

COleDataSource用內(nèi)嵌類(lèi)實(shí)現(xiàn)了IDataObject接口
//COPY HBITMAP To CilpBoard
void CMyView::OnEditCopy()
{

COLORREF BACKGROUND_COLOR = RGB(255,255,255);
tagSTGMEDIUM * data;
CBitmap * junk;
COleDataSource* pData = new COleDataSource;
data = new tagSTGMEDIUM;
junk = new CBitmap();
CClientDC cdc(this);
CDC dc;
dc.CreateCompatibleDC(&cdc);
CRect client;
//replace this with something that calculates
//the proper rectangle size
GetClientRect(client);
junk->CreateCompatibleBitmap(&cdc,client.Width(),client.Height());
dc.SelectObject(junk);
CBrush fill(BACKGROUND_COLOR);
dc.FillRect(client,&fill);
//replace this with something that draws to a CDC
OnDraw(&dc);
data->tymed = TYMED_GDI;
data->hBitmap = HBITMAP(*junk);
pData->CacheData( CF_BITMAP, data );
pData->SetClipboard();
delete data;
delete junk;
//delete pData;
}

另轉(zhuǎn)載一篇文章,講的不怎樣,但可參看一下

利用MFC實(shí)現(xiàn)對(duì)象拖放

  對(duì)象拖放是指對(duì)某一指定的對(duì)象,利用鼠標(biāo)拖動(dòng)的方法,在不同應(yīng)用的窗口
之間、同一應(yīng)用的不同窗口之間或同一應(yīng)用的同一窗口內(nèi)進(jìn)行移動(dòng)、復(fù)制(粘貼)
等操作的技術(shù)。
  利用對(duì)象拖放,可以為用戶(hù)提供方便、直觀的操作界面。
實(shí)現(xiàn)對(duì)象拖放技術(shù),需要了解、使用MFC的CView、COleDataSource和COleDropTarget
等類(lèi),并利用這些類(lèi)協(xié)同工作。
本文討論了對(duì)象拖放技術(shù),并研究了如何利用MFC實(shí)現(xiàn)該技術(shù)。
利用MFC實(shí)現(xiàn)對(duì)象拖放,編程比較容易,代碼可讀性好。
修改稿
利用MFC實(shí)現(xiàn)對(duì)象拖放
1.對(duì)象拖放概念
  對(duì)象拖放是指對(duì)某一指定的對(duì)象,利用鼠標(biāo)拖動(dòng)的方法,在不同應(yīng)用的窗口
之間、同一應(yīng)用的不同窗口之間或同一應(yīng)用的同一窗口內(nèi)進(jìn)行移動(dòng)、復(fù)制(粘貼)
等操作的技術(shù)。
  對(duì)象拖放是在操作系統(tǒng)的幫助下完成的。 要開(kāi)始一次拖動(dòng), 首先需要指定
或生成被拖動(dòng)的對(duì)象,然后指定整個(gè)拖放操作過(guò)程所使用的數(shù)據(jù)格式,并按指定
的數(shù)據(jù)格式提供數(shù)據(jù),最后啟動(dòng)對(duì)象拖放操作;當(dāng)對(duì)象在某一窗口內(nèi)落下時(shí),拖
放過(guò)程結(jié)束,接收拖放對(duì)象的窗口按指定的數(shù)據(jù)格式提取有關(guān)數(shù)據(jù),并根據(jù)提取
的數(shù)據(jù)生成對(duì)象。
2.MFC中用于對(duì)象拖放的類(lèi)
MFC(Microsoft Foundation ClassLibrary)為實(shí)現(xiàn)對(duì)象拖放提供了如下三個(gè)類(lèi)。
為便于后邊的
討論我們先來(lái)熟悉一下這些類(lèi)。
2.1.COleDataSource。用于啟動(dòng)一次拖放操作,并向系統(tǒng)提供拖放對(duì)象的數(shù)據(jù)。
類(lèi)中的成員
函數(shù)有如下三種:
a.設(shè)定提供數(shù)據(jù)的方式和使用的數(shù)據(jù)格式。提供數(shù)據(jù)的方式有兩種,一種是即時(shí)
方式,另一種是延遲方式;即時(shí)方式需要在拖動(dòng)開(kāi)始之前提供數(shù)據(jù);延遲方式不
需要立即提供數(shù)據(jù),當(dāng)系統(tǒng)請(qǐng)求有關(guān)數(shù)據(jù)時(shí),由OnRenderData()等虛函數(shù)提供所
需的數(shù)據(jù)。
可以用CacheGlobalData()等函數(shù)指定使用即時(shí)方式提供數(shù)據(jù),也可以用
DelayRenderData()等函數(shù)指定使用延時(shí)方式提供數(shù)據(jù)。
b.響應(yīng)請(qǐng)求,提供數(shù)據(jù)。應(yīng)當(dāng)重載OnRenderFileData()或其他相應(yīng)的虛函數(shù),以
提供有關(guān)數(shù)據(jù)(后邊將詳細(xì)討論)。
c.實(shí)施拖放操作。調(diào)用函數(shù)DoDragDrop(),開(kāi)始實(shí)施拖放操作。
2.2.OleDataTarget。用于準(zhǔn)備接收拖放對(duì)象的目標(biāo)窗口;一個(gè)窗口要想能夠接收
拖放對(duì)象,必須包含一個(gè)COleDataTarget對(duì)象,并注冊(cè)該對(duì)象。類(lèi)中主要成員函數(shù):
a.注冊(cè)。函數(shù)Register()注冊(cè)該對(duì)象,以便使窗口能夠接收拖放對(duì)象。
b.響應(yīng)拖放過(guò)程中的動(dòng)作(虛成員函數(shù)) 當(dāng)鼠標(biāo)首次進(jìn)入窗口時(shí)系統(tǒng)將調(diào)用
OnDragEnter(),當(dāng)鼠標(biāo)移出窗口時(shí)系統(tǒng)將調(diào)用OnDragLeave(), 當(dāng)鼠標(biāo)在窗口內(nèi)移動(dòng),
系統(tǒng)將重復(fù)調(diào)用調(diào)用OnDragOver(),當(dāng)對(duì)象在窗口內(nèi)落下調(diào)用OnDrop()。
2.3.OleDataObject.用于接收拖放對(duì)象,類(lèi)中主要成員函數(shù)有兩種:
a.確定可以使用的數(shù)據(jù)格式。IsDataAvailable()等函數(shù)確定指定數(shù)據(jù)格式是否可用;
b.獲取數(shù)據(jù)。GetData()、GetFileData()等函數(shù)用于按指定數(shù)據(jù)格式獲得數(shù)據(jù)。
3.利用MFC實(shí)現(xiàn)對(duì)象拖放
   要實(shí)現(xiàn)一次對(duì)象拖放,需要做三方面的工作:對(duì)象所在的窗口準(zhǔn)備拖放對(duì)象并啟拖動(dòng)操作,
接受對(duì)象的窗口響應(yīng)有關(guān)拖放消息并接受落下的對(duì)象,以及拖放完成時(shí)的后期處理。
以下分別予以介紹。
3.1. 拖動(dòng)操作的啟動(dòng)。拖放操作一般是從單擊鼠標(biāo)左鍵開(kāi)始。在消息WM_LBUTTONDOWN的響應(yīng)
函數(shù)OnLButtonDown(...)中,首先要判定是否選定了某一對(duì)象,如果未選定或選定多個(gè),則不能進(jìn)
行拖放操作;如果選定了一個(gè)對(duì)象,則可以進(jìn)行拖放操作。
要啟動(dòng)一次拖放操作,需要先準(zhǔn)備一個(gè)COleDataSource對(duì)象。注意到類(lèi)COleClientIten和類(lèi)
COleServerItem都是從類(lèi)COleDataSource上派生的,如果選定的是COleClientItem對(duì)象或者是
COleServerItem對(duì)象,則可以直接使用;否則,需要生成一個(gè)COleDataSource對(duì)象,值得注意的
是:需要象上文中所說(shuō)的,應(yīng)該指定使用的數(shù)據(jù)格式,并按指定格式提供對(duì)象的有關(guān)數(shù)據(jù)。
下面給出準(zhǔn)備數(shù)據(jù)源的例子:
class myDataSource: public COleDataSource
public:
COLORREF color;
CString str;
protected:
virtual BOOL OnRenderFileData(LPFORMATETC,CFile*);
//......
};
BOOL myDataSource::OnRenderFileData(LPFORMATETC lpFormatEtc,CFile* pFile)
if(lpFormatEtc->cfFormat==CF_TEXT)
pFile.Write("Test DragDrop",13); //Magic String
pFile.Write(&color,sizeof(COLORREF));
int len= str.GetLength();
pFile.Write(&len,sizeof(int));
pFile.Write(str,len);
return TRUE;
COleDataSource::OnRenderFileData(lpFormatEtc,pFile);
return FALSE;
  有了以上數(shù)據(jù)源之后,就可以在消息WM_LBUTTON的響應(yīng)函數(shù)OnLButtonDown()中,按如下方式,指定使用的數(shù)據(jù)格式:
myDataSource* pItemDragDrop=new myDataSource;
pItemDragDrop->str="This string will dragdrop to another place";
pItemDragDrop->DelayRenderFileData(CF_TEXT,NULL);
  指定好使用的數(shù)據(jù)格式之后,調(diào)用此對(duì)象的成員函數(shù)DoDragDrop(...),啟動(dòng)對(duì)象拖放操作。
需要注意的是,函數(shù)DoDragDrop(...)并不立即返回,而是要等到鼠標(biāo)按鈕彈起之后。
3.2. 拖放對(duì)象的接收。缺省情況下,一般的窗口是不能接收拖放對(duì)象的;要使窗口可以接收拖
放對(duì)象,需要在窗口類(lèi)定義中加入成員對(duì)象COleDropTarget,并在生成窗口時(shí)調(diào)用函數(shù)
COleDataTarget::Register()。例如:
Class myView : public CScrollView
private:
COleDropTarget oleTarget;
protected:
virtual int OnCreate(LPCREATESTRUCT);
//......
int myView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  //......
  dropTarget.Register(this);
  return 0;
為實(shí)現(xiàn)拖放對(duì)象的接收,還應(yīng)重載CView或COleDropTarget的虛函數(shù):COnDragMove()、
OnDragEnter()和OnDrop()等。函數(shù)OnDragEnter()、OnDragMove()應(yīng)根據(jù)鼠標(biāo)在窗口中的位置,
返回以下數(shù)值:
DROPEFFECT_MOVE---表明可以把對(duì)象復(fù)制到現(xiàn)在的窗口、現(xiàn)在的位置;
DROPEFFECT_COPY---表明可以把對(duì)象從原來(lái)的窗口、原來(lái)的位置移到現(xiàn)在的窗口、現(xiàn)在的位置;
DROPEFFECT_NONE---表明不能在該窗口的該位置放下。
下例只允許移動(dòng)對(duì)象,而不允許復(fù)制對(duì)象:
DROPEFFECT myView::OnDragEnter(......)
  return DROPEFFECT_MOVE;
DROPEFFECT myView::OnDragOver(......)
return DROPEFFECT_MOVE;
函數(shù)OnDrop()應(yīng)處理拖動(dòng)對(duì)象放下后的工作。該函數(shù)的參數(shù)pDataObjec指向一個(gè)
COleDataObject對(duì)象,利用指針,可以獲取有關(guān)數(shù)據(jù)。該函數(shù)的一般實(shí)現(xiàn)是:
a.檢查對(duì)象的數(shù)據(jù)格式: 利用函數(shù)COleDataObject::IsDataAvailable();
b.按指定的格式獲取數(shù)據(jù):利用COleDataObject::GetFileData()等函數(shù);
c.建立對(duì)象(可能與原對(duì)象相同,也可能不建立對(duì)象僅使用對(duì)象中的數(shù)據(jù)):利用以上步驟
得到的數(shù)據(jù)建立對(duì)象。例如:
char magic_string[13];
COLORREF color;
CString str;
int len;
myDataSource* pMyData;
if(IsDataAvailable(CF_TEXT))
CFile file=GetFileData(CF_TEXT);
file.Read(magic_string,13);
if(strncmp(magic_string,"Test DragDrop",13)==0)
file.Read(&color,sizeof(COLORREF));
file.Read(&len,sizeof(int));
file.Read(str,len);
CClientDC dc(this);
dc.SetTextColor(color);
dc.SetBkMode(TRANSPARENT);
dc.TextOut(100,50,str,len);
pMyData=new myDataSource;
pMyData->color=color;
pMyData->str=str;
對(duì)于COleClientItem或COleServerItem對(duì)象,可以按以下方法很容易地重建對(duì)象:
COleClient* pItem=GetDocument()->CreateNewItem();
pItem->CreateFrom(pDataObject);
3.3. 拖放操作的結(jié)束函數(shù)DoDragDrop()返回時(shí),拖放過(guò)程結(jié)束。函數(shù)DoDragDrop()的返回值,
表明了對(duì)象的拖放結(jié)果。
DROPEFFECT_MOVE:對(duì)象被放到他處,需刪除原對(duì)象
DROPEFFECT_COPY:對(duì)象被復(fù)制到他處,不刪除原對(duì)象
DROPEFFECT_NONE:未能實(shí)現(xiàn)拖放,無(wú)需刪除原對(duì)象
例如:
int DragEffect=pItemTracking->DoDragDrop(......);
switch(DragEffect)
case DROPEFFECT_MOVE:
delete pItemTracking;
GetDocument()->UpdateAllItems(NULL);
GetDocument()->UpdateAllViews(NULL);
break;
case DROPEFFECT_COPY:
case DROPEFFECT_NONE:
default:
break;
*********************
想構(gòu)建一個(gè)自己的粘貼版
需要Hook的函數(shù)
寫(xiě)粘貼板
EmptyClipboardData();//清空自己的粘貼板
SetClipboardData(CF_TEXT, hGMemText);
SetClipboardData(CF_BITMAP, hBitmap);

讀粘貼版
GetClipboardData(CF_TEXT,);
GetClipboardData(CF_BITMAP);

轉(zhuǎn)載于:https://www.cnblogs.com/bsoom/archive/2009/11/14/1603052.html

總結(jié)

以上是生活随笔為你收集整理的剪贴板所有api函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。