程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> MFC單文檔實現文件拖拽功能

MFC單文檔實現文件拖拽功能

編輯:C++入門知識

其實實現的原理很簡單,就是讓程序響應和處理WM_DROPFILES消息。主要用到三個函數:


VOID DragAcceptFiles(     
    HWND hWnd,
    BOOL fAccept
);UINT DragQueryFile(     
    HDROP hDrop,
    UINT iFile,
    LPTSTR lpszFile,
    UINT cch
);VOID DragFinish(     
    HDROP hDrop
);
首先我們建立一個MFC的單文檔程序,命名為DragFiles

在生成的CDragFilesView類的OnCreate函數的末尾添加一條函數調用


[cpp]
DragAcceptFiles(TRUE);//支持文件拖拽 

DragAcceptFiles(TRUE);//支持文件拖拽在MSDN中DragAcceptFiles的描述是這樣的


DragAcceptFiles Function

--------------------------------------------------------------------------------


Registers whether a window accepts dropped files.

//注冊一個窗口,是否支持拖拽文件

Syntax

VOID DragAcceptFiles(     
    HWND hWnd,
    BOOL fAccept
);Parameters

hWnd
The identifier of the window that is registering whether it will accept dropped files.
//需要支持拖拽操作的窗口句柄
fAccept
A value that indicates if the window identified by the hWnd parameter accepts dropped files. This value is TRUE to accept dropped files or FALSE to discontinue accepting dropped files.
一個布爾值,指示是否支持拖拽
Return Value

No return value.

Remarks

An application that calls DragAcceptFiles with the fAccept parameter set to TRUE has identified itself as able to process the WM_DROPFILES message from File Manager.

如果一個應用程序調用了DragAcceptFiles函數並將fAccept參數設置成了TRUE,那麼它就指定了自己可以處理來自文件管理器的WM_DROPFILES消息。

Function Information

Minimum DLL Version shell32.dll version 4.0 or later
Custom Implementation No
Header shellapi.h
Import library shell32.lib
Minimum operating systems Windows NT 3.1, Windows 95
可以看到在調用這個API函數的時候需要包含shellapi.h頭文件,並且導入lib文件
#pragma comment(lib,"shell32.lib")
但是我們上面調用的函數只有一個參數,這是因為我們調用的那個函數時MFC封裝過得函數,是CWnd類的一個成員函數。包含在atlwin.h 中,底層還是調用上面的那個API函數實現的。
由於文檔是覆蓋在主窗體上的,所以必須用文檔類來處理WM_DROPFILES消息。
接下來我們給文檔類添加WM_DROPFILES的消息處理函數:
[cpp]
void CDragFilesView::OnDropFiles(HDROP hDropInfo) 

    // TODO: Add your message handler code here and/or call default  
    UINT nFileNum = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0); // 拖拽文件個數    
    TCHAR strFileName[MAX_PATH]; //定義一個緩沖區,接收文件名字  
    for (int i = 0; i < nFileNum; i++)  //支持同時拖拽多個文件  
    {   
        DragQueryFile(hDropInfo, i, strFileName, MAX_PATH);//獲得拖曳的文件名    
        m_vetFileNames.push_back(strFileName); //m_vetFileNames是一個文檔類中的成員變量,std::vector<CString> 保存文件名   
    }   
    DragFinish(hDropInfo);      //釋放hDrop ,銷毀系統為存儲拖拽文件的文件名所開辟的內存塊  
 
    Invalidate(TRUE);//讓窗口無效,重繪  
    CView::OnDropFiles(hDropInfo); 

void CDragFilesView::OnDropFiles(HDROP hDropInfo)
{
 // TODO: Add your message handler code here and/or call default
 UINT nFileNum = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0); // 拖拽文件個數 
 TCHAR strFileName[MAX_PATH]; //定義一個緩沖區,接收文件名字
 for (int i = 0; i < nFileNum; i++)  //支持同時拖拽多個文件
 { 
  DragQueryFile(hDropInfo, i, strFileName, MAX_PATH);//獲得拖曳的文件名 
  m_vetFileNames.push_back(strFileName); //m_vetFileNames是一個文檔類中的成員變量,std::vector<CString> 保存文件名
 } 
 DragFinish(hDropInfo);      //釋放hDrop ,銷毀系統為存儲拖拽文件的文件名所開辟的內存塊

 Invalidate(TRUE);//讓窗口無效,重繪
 CView::OnDropFiles(hDropInfo);
}在啟動拖拽動作時,操作系統會分配一塊內存存儲拖拽的文件的信息,並通過一個HDROP類型的句柄把該塊內存的地址傳遞給函數OnDropFiles函數。
然後我們調用DragQueryFile。這個函數的原型是:
UINT DragQueryFile(     
    HDROP hDrop, //包含拖拽文件的文件名的結構標識
    UINT iFile, //拖拽的文件索引,如果是0xFFFFFFFF,那麼函數返回拖拽的文件的個數,否則根據索引將文件名字拷貝到lpszFile緩沖區中
    LPTSTR lpszFile, //接收文件名的緩沖區,如果是NULL,函數返回緩沖區需要的大小
    UINT cch  //lpszFile buffer的大小
);如果iFile設置了0xFFFFFFFF返回拖拽文件的個數,否則返回拷貝文件名的字符數//為了驗證拖拽效果,我們將文件名輸出到文檔中//在OnDrow中處理[cpp] view plaincopyprint?void CDragFilesView::OnDraw(CDC* pDC)     void CDragFilesView::OnDraw(CDC* pDC) [cpp] view plaincopyprint?{  {[cpp] view plaincopyprint?    CDragFilesDoc* pDoc = GetDocument();      ASSERT_VALID(pDoc);      if (!pDoc)          return;        // TODO: 在此處為本機數據添加繪制代碼       std::vector<CString>::iterator pos;      int y=0;      TEXTMETRIC tm;//系統字體信息結構體       pDC->GetTextMetrics(&tm);//獲得系統字體信息,為了得到字體高度       for(pos=m_vetFileNames.begin();pos!=m_vetFileNames.end();pos++)//將文件名輸出       {          pDC->TextOut(0,y,*pos);          y+=tm.tmHeight;      }  }   CDragFilesDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 if (!pDoc)
  return;

 // TODO: 在此處為本機數據添加繪制代碼
 std::vector<CString>::iterator pos;
 int y=0;
 TEXTMETRIC tm;//系統字體信息結構體
 pDC->GetTextMetrics(&tm);//獲得系統字體信息,為了得到字體高度
 for(pos=m_vetFileNames.begin();pos!=m_vetFileNames.end();pos++)//將文件名輸出
 {
  pDC->TextOut(0,y,*pos);
  y+=tm.tmHeight;
 }
}最後執行效果:


\

 
  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved