程序支持文件拖放会使程序使用起来更加方便。
当我们从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); }