VC实现文件拖拽获取文件名

        假设在一个对话框程序中,有两个文本框(IDC_EDIT_FILE1IDC_EDIT_FILE2)和两个按钮(IDC_BTN_1IDC_BTN_2),这两个文本框中要输入两个不同的文件名称,从而完成相应的操作(如比较两个文件的差异),我们不得不通过两个按钮来实现两次打开文件的过程(相信我,这个功能经常会使用到的)。此时,我们可以使用OnDropFiles功能。

    以下从不同角度(对话框、文本框)来完成这个工作。不管从何种角度,让我们先来了解一下OnDropFiles到底是何物。OnDropFilesWINDOWS窗口的WM_DROPFILES消息的消息响应函数,值得注间的是,对于基于对话框的程序,默认是没有此消息项的(它隐身了),也就不能正确响应这个消息。在开始之前,我们先让这个消息对基于对话框的程序显现出来:类向导”->“类信息,在Message Filter选项中选择Window, 确认后,再在“Message Maps”中就会出现WM_DROPFILES了:

    既然提到了OnDropFiles,函数DragQueryFile()函数不得不提。通常,在OnDropFiles函数中,我们通常都会不止一次地使用到这个函数,它能获取拖曳到当前窗口(对话框、文本框)中的文件数量及文件名称,以下是此函数的简单说明:

UINT DragQueryFile(
                 HDROP hDrop,
                   
UINT iFile,
                   
LPTSTR lpszFile,
                   
UINT cch
              );
其中,参数说明如下:

hDrop  :用于区分包含被拖拽文件名称结构的句柄。 即存放所拖放文件名称的数据结构的句柄,也就是文件名缓冲区的句柄;
iFile  :文件索引编号(用于指明所要查询文件的序号, 如果拖进多个文件,则索引编号从零开始),如果iFile值为 0xFFFFFFFF 时,返回的是拖曳到窗体上的文件的个数。如果iFile值在0和拖拽文件总数之间时,DragQueryFile拷贝与文件名存储缓冲区大小适应的文件名称到缓冲区中;
lpszFile  函数返回时,用于存储拖拽文件名称的缓冲区指针。文件名称是一个以空终止“”结尾的字符串。如果此参数是NULLDragQueryFile函数返回拖拽的文件数目。函数DragQueryFile得到的文件名,是带完整路径的文件名;
    cch  
   存储拖拽文件名称缓冲区的大小,即lpszFile指针所指缓冲区的字符数。

返回值说明如下:

1、如果函数拷贝文件名称到缓冲区中,返回值就是拷贝的字符数,不包括终止的NULL字符; 
  2
、如果文件索引值是0xFFFFFFFF,则返回值是被拖拽的文件总数,注意文件索引变量的值将保持不变,依然为0xFFFFFFFF
  3
、如果文件索引值在0和拖拽文件总数之间时,并且lpszFile值为NULL ,返回值是存储此被拖拽文件的名称所需要的缓冲区大小值,此值是不包括终止NULL字符的字符数。(此种用法很少用,一般会直接用MAX_PATH宏定义就可以了,不必要知道文件名的真正字数)。

实际中常会用到以下两种情况:

1、获取文件数目:

UINT iFileCount;

iFileCount = ::DragQueryFile(hDropInfo, 0xffffffff, NULL, 0);

2、获取指定索引的文件名:

char file_name[MAX_PATH];

::DragQueryFile(hDropInfo, iFileCount - 1, file_name, MAX_PATH);

 

一、对话框实现WM_DROPFILES消息

1、打开对话框属性,选中接收文件选项(如此对话框才会响应WM_DROPFILES消息),如下图所示:



2
、为对话框增加WM_DROPFILES响应函数,即OnDropFiles(),如下图所示:



3
、为OnDropFiles添加代码(弹出消息框,逐个显示每个文件名)

void CAboutDlg::OnDropFiles(HDROP hDropInfo) 

{

// TODO: Add your message handler code here and/or call default

    UINT count;            

    char filePath[200];            

    count = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);            

    if(count)             

    {  

        for(UINT i=0; i<count; i++)                      

        {  

            int pathLen = DragQueryFile(hDropInfo, i, filePath, sizeof(filePath));   

            AfxMessageBox(filePath);   

        }  

    }  

    DragFinish(hDropInfo);  

    CDialog::OnDropFiles(hDropInfo);  

}

4、编译运行。

这样,将文件拖放到对话框的任何地方,都可以将该文件名显示在IDC_EDIT_FILE1对话框中了。当然了,只要再CDragFileDlg类中再增加一个计数变量,就可以为另一个对话框实现类似功能了。但是,在这里,我们会使用另外一种方法完成IDC_EDIT_FILE2的这种功能的添加。

二、文本框实现WM_DROPFILES消息

1、为IDC_EDIT_FILE2添加接收文件属性,此操作同对话框相应操作相同;

2、新建类CFileEdit,基类为CEdit,如下图所示:



3
、为新类CFileEdit定义WM_DROPFILES消息响应,此操作与对话框相应操作相同,只是在类向导中指定类为CFileEdit,而不是之前的CDragFileDlg

4、书写CFileEdit类的OnDropFiles函数,代码如下:



5
、为IDC_EDIT_FILE2指令Control型变量,并选定类型为CFileEdit,而不是CEdit,如下图所示:



6
、编译运行。

这样,第二个文本框的功能也完成了。

其实,这两种方法从原理上来说是相同的,只是对象不同而已,在实际应用中,你可以选择任意一种就可以了。对于我个人而言,可能会更偏爱第二种作法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值