?? window下拖放操作drag & drop 全解析.txt
字號:
Window下拖放操作Drag & Drop 全解析
作者:未知 文章來源:Internet 點擊數:5961 更新時間:2005-5-31
一、基本概念
拖放,是指用鼠標拖動的方法,在不同程序的窗口之間、同一個程序的不同窗口之間或同一程序同一窗口的不同控件之間,進行移動、復制和粘貼等操作的技術。拖放操作是在操作系統的幫助下完成的。被拖動的對象首先向操作系統注冊它使用的數據格式,并按指定的數據格式提供數據,拖放操作結束時,接收拖放的窗口按指定的數據格式提取有關數據,并根據提取的數據生成相應的對象。
二、兩種拖放方式
拖放有兩種類型:OLE拖放和文件管理器拖放。這兩種方式是完全不同的機制。文件管理器拖放只能處理文件名,通過映射目的窗口的WM_DROPFILES消息,窗口就可以收到拖放進來的文件名。OLE拖放則更加通用一些,它允許你拖放可同時被保存在剪貼板上的任何數據。本文首先介紹文件管理器拖放,然后再介紹OLE拖放,最后給出一個用OLE實現的,支持文件拖放操作的增強列表控件CListCtrlEx。
三、文件管理器拖放原理及實例
這種方式的實質就是產生一個消息WM_DROPFILES。技術上沒有什么難點,主要用到下面幾個API函數:DragQueryFile、DragQueryPoint、DragFinish。它們的原型和注解分別如下:
UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch)
本函數用來取得拖放的文件名。其中,hDrop是一個指向含有被拖放的文件名的結構體的句柄;iFiles是要查詢的文件序號,因為一次可能同時拖動很多個文件;lpszFiles是出口緩沖區指針,保存iFiles指定序號的文件的路徑名,cch指定該緩沖區的大小。有兩點值得注意,第一,如果我們在調用該函數的時候,指定iFile為0xFFFFFFFF,則DragQueryFile將忽略lpszFile和cch參數,返回本次拖放操作的文件數目;第二,如果指定lpszFile為NULL,則函數將返回實際所需的緩沖區長度。
BOOL DragQueryPoint(HDROP hDrop, LPPOINT lppt);
本函數用來獲取,當拖放操作正在進行時,鼠標指針的位置。第二個參數lppt是一個指向POINT結構體的指針,用來保存文件放下時,鼠標指針的位置。窗口可以調用該函數以查詢文件是否落在自己的窗口矩形中。
void DragFinish(HDROP hDrop);
當拖放操作處理完畢后需調用該函數釋放系統分配來傳輸文件名的內存。
首先,建立一個對話框工程,確保選中對話框的Accept Files屬性。如果不選,也可以在窗口創建的時候(譬如OnCreate函數中)調用DragAcceptFiles(TRUE),效果是一樣的。
然后映射WM_DROPFILES消息。該消息處理函數原型如下:void OnDropFiles(HDROP hDrop),注意入口參數為HDROP型,它是一個結構體指針,所指向的結構體中包含了被拖放的文件的名稱。接下來我們主要要完成兩個動作:第一,通過調用DragQueryFile并指定其iFile參數為0xFFFFFFFF,得到本次拖放操作的文件數目;第二步,用一個循環依次取出各個文件名。示例如下:
void CListCtrlEx::OnDropFiles(HDROP hDrop)
{
char szFilePathName[_MAX_PATH+1] = {0};
UINT nNumOfFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); //得到文件個數
for (UINT nIndex=0 ; nIndex< nFileCount; ++nIndex)
{
DragQueryFile(hDrop, nIndex, szFilePathName, _MAX_PATH); //得到文件名
}
DragFinish(hDrop);
}
四、OLE拖放原理
MFC為實現對象拖放提供了如下類:COleDataSource、COleDataObject、COleDropTarget、COleDropSource。下面分別介紹它們,然后通過一個實例講述實現的具體步驟。
· COleDataSource
啟動一次拖放操作,保存拖放的數據,并向系統提供拖放對象的數據。類中重要的成員函數根據用途分為如下三種:
1. 用于設定提供數據的方式和使用的數據格式。
提供數據的方式有兩種,一種是即時方式,另一種是延遲方式。延遲方式不需要立即提供數據,當需要提供數據時,系統將調用對應的函數來獲得數據,一般都是重載OnRenderData函數或其他虛函數,以響應數據請求。數據格式可以是CF_TEXT等常用的剪貼板格式,也可以是自己利用函數RegisterClipboardFormat函數注冊的特定格式。
CacheData:提供指定格式的數據,格式由結構STGMEDIUM指定,即時方式;
CacheGlobalData:利用全局句柄HGLOBAL,為指定格式提供數據,即時方式,適用小數據量;
DelayRenderData:使用延遲方式按指定格式提供數據,當系統需要數據時,會調用函數OnRenderGlobalData/OnRenderData來取得數據;
DelayRenderFileData:使用延遲方式利用CFile為指定格式提供數據,當需要數據時,會調用函數OnRenderFileData來取得數據;
2. 響應請求,提供數據
OnRenderFileData:為延遲方式提供CFile型數據。
OnRenderGlobalData:為延遲方式提供HGLOBAL數據。
OnRenerData:為延遲方式提供各種所支持的類型的數據。
3. 實施拖放操作
DoDragDrop:開始實施拖放操作
· COleDataObject
用于代表拖放的數據,它是作為COleDataSource類的成員,類中主要成員函數有:
BeginEnumFormat:為枚舉數據格式作準備;
GetNextFormat:返回下一個數據格式;
IsDataAvailable: 檢查指定的數據格式是否可用;
GetData:按指定數據格式,獲得數據;
GetFileData:按指定數據格式,獲得CFile型數據;
GetGlobalData:按指定數據格式,獲得HGLOBAL型數據;
· COleDropTarget
用于在窗口和OLE庫之間提供通訊機制。任何一個窗口,要想能夠接收拖放,必須包含一個COleDropTarget對象,并注冊之。其中的成員函數可分為兩大類:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -