Windows 通过拖拽得到文件路径

    主要用到两个函数,DragAcceptFiles() 与 DragQueryFile。

DragQueryFile原型如下:

UINT DragQueryFile(      
  HDROP hDrop, 
  UINT iFile,
  LPTSTR lpszFile,
  UINT cch
  );

hDrop
  Identifier of the structure containing the file names of the dropped files.

iFile
  Index of the file to query. If the value of the iFile parameter is 0xFFFFFFFF,
DragQueryFile returns a count of the files dropped. If the value of the iFile
parameter is between zero and the total number of files dropped, DragQueryFile
copies the file name with the corresponding value to the buffer pointed to by
the lpszFile parameter.

lpszFile
  Address of a buffer to receive the file name of a dropped file when the
function returns. This file name is a null-terminated string. If this parameter
is NULL, DragQueryFile returns the required size, in characters, of the buffer.

cch
  Size, in characters, of the lpszFile buffer.

Return Value
  
  When the function copies a file name to the buffer, the return value is a
count of the characters copied, not including the terminating null character.

用Windows API方式实现,很古老,但是从根本上讲清楚了MFC的调用过程:

  1 // Win32App.cpp : Defines the entry point for the application.
  2 //
  3 
  4 // 文件拖拽
  5 // http://blog.csdn.net/morewindows/article/details/8634451
  6 //By MoreWindows-(http://blog.csdn.net/MoreWindows) 
  7 // 第一步 #include <shellapi.h> #pragma comment(lib, "shell32.lib")
  8 // 第二步 DragAcceptFiles(hwnd, TRUE);
  9 // 第三步 UINT nFileNum = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);拖曳文件个数
 10 // 第四步 DragQueryFile(hDrop, i, strFileName, MAX_PATH);获得拖曳的文件名
 11 #include "stdafx.h"
 12 #include <vector>
 13 #include <cstring>
 14 using namespace std;
 15 
 16 // 文件拖拽第一步  
 17 #include <shellapi.h>
 18 #pragma comment(lib, "shell32.lib")
 19 
 20 const char szAppName[] = "文件拖拽_MoreWindows(http://blog.csdn.net/MoreWindows)";
 21 
 22 BOOL InitApplication(HINSTANCE hinstance, int nCmdShow);
 23 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 24 
 25 
 26 int APIENTRY WinMain(HINSTANCE hInstance,
 27                      HINSTANCE hPrevInstance,
 28                      LPSTR     lpCmdLine,
 29                      int       nCmdShow)
 30 {
 31      // TODO: Place code here.
 32     MSG     msg;
 33     
 34     if (!InitApplication(hInstance, nCmdShow))
 35     {
 36         return 0;
 37     }
 38     
 39     while (GetMessage(&msg, NULL, 0, 0))
 40     {
 41         TranslateMessage(&msg);
 42         DispatchMessage(&msg);
 43     }
 44     return msg.wParam;
 45     return 0;
 46 }
 47 
 48 
 49 BOOL InitApplication(HINSTANCE hinstance, int nCmdShow)
 50 {
 51     HWND      hwnd;
 52     WNDCLASS  wndclass;
 53     
 54     
 55     wndclass.style       = CS_HREDRAW | CS_VREDRAW;
 56     wndclass.lpfnWndProc = WndProc;
 57     wndclass.cbClsExtra  = 0;
 58     wndclass.cbWndExtra  = 0;
 59     wndclass.hInstance   = 0;
 60     wndclass.hIcon       = LoadIcon(NULL, IDI_APPLICATION);
 61     wndclass.hCursor     = LoadCursor(NULL, IDC_ARROW);
 62     wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
 63     wndclass.lpszMenuName  = NULL;
 64     wndclass.lpszClassName = szAppName;
 65     
 66     if (!RegisterClass(&wndclass))
 67     {
 68         MessageBox(NULL, "Program Need Windows NT!", szAppName, MB_ICONERROR);
 69         return FALSE;
 70     }
 71     
 72     hwnd = CreateWindow(szAppName, 
 73         szAppName,
 74         WS_OVERLAPPEDWINDOW,
 75         CW_USEDEFAULT,
 76         CW_USEDEFAULT,
 77         CW_USEDEFAULT,
 78         CW_USEDEFAULT,
 79         NULL, 
 80         NULL,
 81         hinstance,
 82         NULL);
 83     
 84     if (hwnd == NULL)
 85         return FALSE;
 86     
 87     ShowWindow(hwnd, nCmdShow);
 88     UpdateWindow(hwnd);
 89     
 90     return TRUE;
 91 }
 92 
 93 
 94 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 95 {
 96     static vector<string> s_vetFileNames;
 97 
 98 
 99     switch (message)
100     {
101     case WM_CREATE:
102         // 文件拖拽第二步   DragAcceptFiles
103         DragAcceptFiles(hwnd, TRUE);
104         return 0;
105 
106 
107         // 文件拖拽第三步 DragQueryFile and DragQueryFile
108     case WM_DROPFILES:
109         {
110             HDROP hDrop = (HDROP)wParam;
111             UINT nFileNum = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); // 拖拽文件个数
112             char strFileName[MAX_PATH];
113             for (int i = 0; i < nFileNum; i++)  
114             {
115                 DragQueryFile(hDrop, i, strFileName, MAX_PATH);//获得拖曳的文件名
116                 s_vetFileNames.push_back(strFileName);
117                 
118             }
119             DragFinish(hDrop);      //释放hDrop
120     
121             InvalidateRect(hwnd, NULL, TRUE);
122         }
123         return 0;
124 
125 
126     case WM_PAINT:
127         {
128             HDC             hdc;
129             PAINTSTRUCT     ps;
130             vector<string>::iterator pos;
131             int i, y;
132             hdc = BeginPaint(hwnd, &ps);
133         
134             // 显示拖拽的文件名
135             y = 0;
136             for (pos = s_vetFileNames.begin(); pos != s_vetFileNames.end(); pos++)
137             {
138                 TextOut(hdc, 20, y, pos->c_str(), strlen(pos->c_str()));
139                 y += 30;
140             }
141             EndPaint(hwnd, &ps);
142         }
143         return 0;
144 
145     case WM_DESTROY:
146         PostQuitMessage(0);
147         return 0;
148     }
149     return DefWindowProc(hwnd, message, wParam, lParam);
150 }

MFC方式,基于对话框的:

 1 int CDragFilesMFCDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
 2 {
 3     if (CDialogEx::OnCreate(lpCreateStruct) == -1)
 4         return -1;
 5 
 6     // TODO:  在此添加您专用的创建代码
 7     DragAcceptFiles();
 8 
 9     return 0;
10 }
11 
12 
13 void CDragFilesMFCDlg::OnDropFiles(HDROP hDropInfo)
14 {
15     // TODO:  在此添加消息处理程序代码和/或调用默认值
16     
17     int nFileNum = DragQueryFile(hDropInfo, -1, NULL, 0); // 拖拽文件个数
18     std::list<std::string> s_vetFileNames;
19     char strFileName[MAX_PATH];
20     for (int i = 0; i < nFileNum; i++)
21     {
22         DragQueryFile(hDropInfo, i, strFileName, MAX_PATH);//获得拖曳的文件名
23         s_vetFileNames.push_back(strFileName);
24 
25     }
26     DragFinish(hDropInfo);      //释放hDrop
27     std::list<std::string>::iterator it;
28     for (it = s_vetFileNames.begin(); it != s_vetFileNames.end(); ++it)
29     {
30         TRACE(it->c_str());
31         TRACE("\n");
32     }
33     CDialogEx::OnDropFiles(hDropInfo);
34 }

文件拖拽获取其文件名的过程还是比较简单的,后期会实现文件被拖拽到应用程序指定区域才触发过程。

boyang987

 

posted @ 2015-01-20 10:12  boyang987  阅读(907)  评论(0编辑  收藏  举报