【引言】拖放操作在电脑中很常用,例如我们经常复制文件就可以按住ctrl键不放,然后再拖到另外一个窗口中,或者,可以把一个WORD文档直接拖动到WORD窗口即可打开,以前我使用过VB,里面直接有OleDragDrop事件,进行相应处理即可。那么如何在VC++中通过编程实现该功能呢,这就是本文要介绍的。

【实现】具体做法如下:用ClassWizard类向导新建一个类,取名为CMyListCtrl,基类为CListCtrl,然后在类向导中切换到Message Maps选项卡,选择刚才建立的CMyListCtrl类,为WM_DROPFILES添加消息处理函数(实现拖放的关键也就在这里)

然后在对话框中画一个ListCtrl,按alt+enter进入属性页,点击扩展样式选项卡,勾选“接受文件”,使用类向导添加成员变量,Varable Type变量类型选择刚才新建的CMyListCtrl类,这样,这个ListCtrl就具有了接受拖放文件的功能了。

要处理拖放事件,那么在此函数中处理: void CMyListCtrl::OnDropFiles(HDROP hDropInfo)

【附录】

支持文件拖放时,主要会涉及到以下三个API函数:DragQueryFile、DragQueryPoint、DragFinish

1.UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch)  

  1. 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,则函数将返回实际所需的缓冲区长度。

2.BOOL DragQueryPoint(HDROP hDrop, LPPOINT lppt);        

  1. BOOL DragQueryPoint(HDROP hDrop, LPPOINT lppt);  

  这个函数用来获取,当拖放操作正在进行时,鼠标指针的位置。第二个参数lppt是一个指向POINT结构体的指针,用来保存文件放下时,鼠标指针的位置。窗口可以调用该函数以查询文件是否落在自己的窗口矩形中。

3.void DragFinish(HDROP hDrop);     

  1. void DragFinish(HDROP hDrop);  

  当拖放操作处理完毕后需调用该函数释放系统分配来传输文件名的内存。   

 

  要处理WM_DROPFILES消息时,可以使用向导给对应的窗口添加消息处理函数,该消息处理函数原型是:void OnDropFiles(HDROP hDrop):

【示例】

  1. void CDialogDropFileDlg::OnDropFiles(HDROP hDropInfo)   
  2. {   
  3.     // TODO: 在此添加消息处理程序代码和/或调用默认值   
  4.     char szFilePathName[_MAX_PATH+1]    =    {0};      
  5.   
  6.         //得到文件个数      
  7.     UINT nNumOfFiles = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);   
  8.   
  9.     for (UINT nIndex=0 ; nIndex< nNumOfFiles; ++nIndex) {   
  10.         // 得到文件名   
  11.          DragQueryFile(hDropInfo, nIndex, (LPTSTR)szFilePathName, _MAX_PATH);   
  12.         // 有了文件名就可以想干嘛干嘛了 :P   
  13.          AfxMessageBox((LPCTSTR)szFilePathName);   
  14.      }      
  15.   
  16.      DragFinish(hDropInfo);     
  17.   
  18.      CDialog::OnDropFiles(hDropInfo);   
  19. }