VC实现文件拖拽功能
我们使用的好多软件,只要把文件拖拽到消息框中就可以打开文件了。那么这种功能是如何实现的呢?在VC中其实很简单,只需要响应一个WM_DROPFILES消息就可以了。下面我用VC6.0给出个例子。
具体步骤为:在基于对话框的程序中,默认是没有这个消息的,按下Ctrl+W,弹出类向导对话框,选择Class Info标签,在Message fileter下拉列表中选择Window,如图1:
图1
然后再点击Message Maps标签,选择WM_DROPFILES消息,如图2:
图2
添加该消息的响应函数,在.h文件中的声明为:
afx_msg void OnDropFiles(HDROP hDropInfo);//实现文件的托拽功能,添加WM_DROPFILES消息
另外,要让对话框能够接受文件拖拽,还需要设置对话框属性。在对话框上点击右键,选择Properties->Extended Styles,点选Accept files选项,如图3:
图3
要获得当前拖拽的文件的完整文件名(含路径),需要用到一个函数:
UINT DragQueryFile(
HDROP hDrop,
UINT iFile,
LPTSTR lpszFile,
UINT cch
);
参数解释:hDrop: HDROP标识符,即响应函数中的hDropInfo参数
iFile: 待查询的文件索引号,从0开始。可以同时拖拽多个文件,因此就需要一个索引号来进行区分。如果该参数为0xFFFFFFFF,则该函数返回拖拽的文件的个数
lpszFile: 用于存放文件名的缓冲区首地址
cch: 缓冲区长度
返回值:文件名长度
另外,查询完成后需要释放系统分配内存,需要用到下面这个函数:
VOID DragFinish(
HDROP hDrop
);
下面是一个完整的代码示例,将文件拖拽到对话框上后会弹出消息框显示完整文件名:
//实现文件的托拽功能,添加WM_DROPFILES消息
void CDirTreeCtrl::OnDropFiles(HDROP hDropInfo)
{
// TODO: Add your message handler code here and/or call default
char szFileName[MAX_PATH + 1] = {0};//被拖拽文件的绝对路径
UINT nFiles = DragQueryFile(hDropInfo,0xFFFFFFFF,NULL,0);//被拖拽的文件的个数
for (UINT i = 0;i < nFiles ; i++)
{
DragQueryFile(hDropInfo,i,szFileName,MAX_PATH);//托拽的文件名
AfxMessageBox(szFileName);
}
DragFinish(hDropInfo);//完成拖拽
CTreeCtrl::OnDropFiles(hDropInfo);
}
接下来就可以做后续处理了。同理,如果只有把文件拖拽到某一特定的控件中时才有响应,只需要把该控件的Accept files样式勾选上即可。