MFC窗口拖拽文件功能指的是用鼠标将文件拖拽入窗口后,在窗口中可以获取拖拽文件的绝对路径,如图1所示。
图1 文件拖拽功能
实现窗口的拖拽文件功能,首先要将窗口注册为放置拖拽文件的目标,之后在窗口中响应拖拽消息,获取拖拽文件的绝对路径。
1将窗口注册为放置文件的目标
将窗口注册为放置文件目标的方法有两种:一种是通过MFC资源编辑器实现,另一种方法是通过代码实现。
1.1通过MFC资源编辑器实现
在VS2015中创建一个基于对话框的MFC程序。接下来在VS2015的资源视图中,选择MFC程序的主对话框,然后在右侧的“属性”选项中将对话框的“Accept Files”属性设置为True,表示将对话框注册为放置拖放文件的目标,如图2所示。
图2 修改对话框Accept Files属性
1.2通过代码实现
在对话框的OnInitDialog()函数中通过CWnd类的DragAcceptFiles()函数将对话框注册为放置拖放文件的目标。该函数的格式为
void DragAcceptFiles( BOOL bAccept = TRUE );
该函数的参数bAccept
为
TRUE
时表示对话框接收拖拽的文件,
bAccept
是
FALSE
时表示不接受拖拽的文件。
2.文件拖拽消息的响应函数
在将窗口注册为放置文件的目标后,该窗口就可以接收文件拖拽的消息了,该消息为WM_DROPFILES。
2.1 添加消息响应函数
在VS2015资源管理器中选中窗口,之后在右侧的“属性”中选择“消息”,为WM_DROPFILES消息添加响应函数OnDropFiles(),如图3所示。当将文件拖拽入对话框时,OnDropFiles()函数就会被调用。
图3 添加WM_DROPFILES消息响应函数
2.2 定义消息响应函数
在OnDropFiles()函数中,获取拖拽文件的绝对路径,并在编辑框中显示出来。通过DragQueryFile()函数获取文件的绝对路径,该函数的格式为
UINT DragQueryFile(
_In_ HDROP hDrop,
_In_ UINT iFile,
_Out_ LPTSTR lpszFile,
UINT cch
);
其中,参数hDrop
包含了拖拽文件的信息;
iFile
指定了查询文件的索引号;
lpszFile
是保存文件绝对路径的缓冲区;
cch
是缓冲区的大小。如果成功获取拖拽文件的信息,则返回非零值。
在使用DragQueryFile()函数时,首先通过该函数获取拖拽文件的数量,之后遍历每个拖拽文件。一般来说,每次只拖拽一个文件。
2.2.1 获取拖拽文件的数量
通过DragQueryFile()函数获取拖拽到窗口上的文件的数量。
int count_droppedfile = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
其中,DragQueryFile()
函数的第二个参数设置为
0xFFFFFFFF
即
-1
时,该函数的返回值即为拖拽文件的数量。
2.2.2 拖拽文件绝对路径的显示
在“2.2.1 获取拖拽文件的数量”中获取了拖拽文件的数量之后,接下来遍历拖拽到窗口的文件,获取文件的绝对路径,并且在窗口的Edit控件中显示出来。
(1)为Edit控件添加成员变量
要想在Edit控件中显示拖拽文件的绝对路径,就要为该控件添加成员变量。如图4所示。
图4 为Edit控件添加变量
以上方法为窗口的编辑框控件添加了一个名为m_EditCtrl_FilePath的变量,该变量的类别为Control。
(2)显示绝对路径
在对话框类的OnDropFiles()函数中,有如下代码
for (int i = 0; i < count_droppedfile; ++i)
{
wchar_t filepath[MAX_PATH] = { 0 };
if (DragQueryFile(hDropInfo, i, filepath, MAX_PATH)>0)
{
m_EditCtrl_FilePath.SetWindowTextW(filepath);
}
}
其中,for
循环的作用是遍历所有的拖拽文件,
count_droppedfile
是在“
2.2.1
获取拖拽文件的数量”中获取的拖拽文件数量;通过
DragQueryFile()
函数获取文件的绝对路径,并且保存在
filepath
中,最后,通过编辑框控件的变量
m_EditCtrl_FilePath
调用
SetWindowTextW()
函数将绝对路径显示出来。