程序支持文件拖放會使程序使用起來更加方便。
當我們從shell(window的文件瀏覽器)中拖入一個文件到應用程序窗口時,windows會發生一個消息WM_DROPFILES給程序,支持文件拖放操作的本質就是程序要適當地處理這個消息。並不是所有程序都可以接受文件拖放消息,只有具有WS_EX_ACCEPTFILES窗口屬性的窗口,才能收到這條消息。當使用WIN32 API進行編程時,就要在創建這個窗口時加上這個擴展屬性。
如果是MFC程序,則可以在創建程序時,在嚮導中選擇窗口的Accept Files屬性,也可以在窗口創建的時候(比如OnCreate函數)調用窗口的成員函數DragAcceptFiles(TRUE),效果是一樣的。
支持文件拖放時,主要會涉及到以下三個API函數:DragQueryFile、DragQueryPoint、DragFinish。
它們的原型和註解分別如下:
UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch)
這個函數用來取得拖放的文件名。其中,hDrop是一個指向含有被拖放的文件名的結構體的句柄(WIN32 API編程時,這個句柄就是WM_DROPFILES消息的wParam參數,而MFC編程時,則可以從消息處理函數的參數直接得到);iFiles是要查詢的文件序號,因爲一次可能同時拖動很多個文件;lpszFiles是出口緩衝區指針,保存iFiles指定序號的文件的路徑名,cch指定該緩衝區的大小。注意,第一,如果我們在調用該函數的時候,指定iFile爲0xFFFFFFFF,則DragQueryFile將忽略lpszFile和cch參數,返回本次拖放操作的文件數目;第二,如果指定lpszFile爲NULL,則函數將返回實際所需的緩衝區長度。
BOOL DragQueryPoint(HDROP hDrop, LPPOINT lppt);
這個函數用來獲取,當拖放操作正在進行時,鼠標指針的位置。第二個參數lppt是一個指向POINT結構體的指針,用來保存文件放下時,鼠標指針的位置。窗口可以調用該函數以查詢文件是否落在自己的窗口矩形中。
void DragFinish(HDROP hDrop);
當拖放操作處理完畢後需調用該函數釋放系統分配來傳輸文件名的內存。
要處理WM_DROPFILES消息時,可以使用嚮導給對應的窗口添加消息處理函數,該消息處理函數原型是:void OnDropFiles(HDROP hDrop):
以下是該函數處理的示例代碼:
void CDialogDropFileDlg::OnDropFiles(HDROP hDropInfo)
{
// TODO: 在此添加消息處理程序代碼和/或調用默認值
char szFilePathName[_MAX_PATH+1] = {0};
//得到文件個數
UINT nNumOfFiles = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
for (UINT nIndex=0 ; nIndex< nNumOfFiles; ++nIndex) {
// 得到文件名
DragQueryFile(hDropInfo, nIndex, (LPTSTR)szFilePathName, _MAX_PATH);
// 有了文件名就可以想幹嘛幹嘛了 :P
AfxMessageBox((LPCTSTR)szFilePathName);
}
DragFinish(hDropInfo);
CDialog::OnDropFiles(hDropInfo);
}