您的位置:首页 > 其它

Windows 通过拖拽得到文件路径

2015-01-20 10:12 190 查看
主要用到两个函数,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的调用过程:

// Win32App.cpp : Defines the entry point for the application.
//

// 文件拖拽
// http://blog.csdn.net/morewindows/article/details/8634451 //By MoreWindows-(http://blog.csdn.net/MoreWindows)
// 第一步 #include <shellapi.h> #pragma comment(lib, "shell32.lib")
// 第二步 DragAcceptFiles(hwnd, TRUE);
// 第三步 UINT nFileNum = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);拖曳文件个数
// 第四步 DragQueryFile(hDrop, i, strFileName, MAX_PATH);获得拖曳的文件名
#include "stdafx.h"
#include <vector>
#include <cstring>
using namespace std;

// 文件拖拽第一步
#include <shellapi.h>
#pragma comment(lib, "shell32.lib")

const char szAppName[] = "文件拖拽_MoreWindows(http://blog.csdn.net/MoreWindows)";

BOOL InitApplication(HINSTANCE hinstance, int nCmdShow);
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR     lpCmdLine,
int       nCmdShow)
{
// TODO: Place code here.
MSG     msg;

if (!InitApplication(hInstance, nCmdShow))
{
return 0;
}

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
return 0;
}

BOOL InitApplication(HINSTANCE hinstance, int nCmdShow)
{
HWND      hwnd;
WNDCLASS  wndclass;

wndclass.style       = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra  = 0;
wndclass.cbWndExtra  = 0;
wndclass.hInstance   = 0;
wndclass.hIcon       = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor     = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszMenuName  = NULL;
wndclass.lpszClassName = szAppName;

if (!RegisterClass(&wndclass))
{
MessageBox(NULL, "Program Need Windows NT!", szAppName, MB_ICONERROR);
return FALSE;
}

hwnd = CreateWindow(szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hinstance,
NULL);

if (hwnd == NULL)
return FALSE;

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

return TRUE;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static vector<string> s_vetFileNames;

switch (message)
{
case WM_CREATE:
// 文件拖拽第二步   DragAcceptFiles
DragAcceptFiles(hwnd, TRUE);
return 0;

// 文件拖拽第三步 DragQueryFile and DragQueryFile
case WM_DROPFILES:
{
HDROP hDrop = (HDROP)wParam;
UINT nFileNum = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); // 拖拽文件个数
char strFileName[MAX_PATH];
for (int i = 0; i < nFileNum; i++)
{
DragQueryFile(hDrop, i, strFileName, MAX_PATH);//获得拖曳的文件名
s_vetFileNames.push_back(strFileName);

}
DragFinish(hDrop);      //释放hDrop

InvalidateRect(hwnd, NULL, TRUE);
}
return 0;

case WM_PAINT:
{
HDC             hdc;
PAINTSTRUCT     ps;
vector<string>::iterator pos;
int i, y;
hdc = BeginPaint(hwnd, &ps);

// 显示拖拽的文件名
y = 0;
for (pos = s_vetFileNames.begin(); pos != s_vetFileNames.end(); pos++)
{
TextOut(hdc, 20, y, pos->c_str(), strlen(pos->c_str()));
y += 30;
}
EndPaint(hwnd, &ps);
}
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}


MFC方式,基于对话框的:

int CDragFilesMFCDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialogEx::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO:  在此添加您专用的创建代码
DragAcceptFiles();

return 0;
}

void CDragFilesMFCDlg::OnDropFiles(HDROP hDropInfo)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值

int nFileNum = DragQueryFile(hDropInfo, -1, NULL, 0); // 拖拽文件个数
std::list<std::string> s_vetFileNames;
char strFileName[MAX_PATH];
for (int i = 0; i < nFileNum; i++)
{
DragQueryFile(hDropInfo, i, strFileName, MAX_PATH);//获得拖曳的文件名
s_vetFileNames.push_back(strFileName);

}
DragFinish(hDropInfo);      //释放hDrop
std::list<std::string>::iterator it;
for (it = s_vetFileNames.begin(); it != s_vetFileNames.end(); ++it)
{
TRACE(it->c_str());
TRACE("\n");
}
CDialogEx::OnDropFiles(hDropInfo);
}


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

boyang987
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: