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