MFC 实现拖动文件获取文件路径

参考文章:Edit Control实现文件拖拽
                  DragQueryFile

1.文件拖动到对话框

(1)添加消息映射

//CMyTestDlg.cpp
BEGIN_MESSAGE_MAP(CMYstaticTestDlg, CDialog)
	ON_WM_DROPFILES()
END_MESSAGE_MAP()

(2) 将对话框的属性 Accep Files 设置为TRUE
或者
在OnInitDialog()中添加

//CMyTestDlg.cpp
ModifyStyleEx(0,WS_EX_ACCEPTFILES,0);

(3)重写对话框 OnDropFiles 函数

//CMyTestDlg.cpp
void CMyTestDlg::OnDropFiles(HDROP hDropInfo){
	// 通过设置iFiles参数为0xFFFFFFFF,可以取得当前拖动的文件数量,
	// 当设置为0xFFFFFFFF,函数间忽略后面两个参数。
	int DropCount=DragQueryFile(hDropInfo,-1,NULL,0);//取得被拖动文件的数目
	// 循环依次取得拖动文件的File Name信息
	for(int i=0;i< DropCount;i++)
	{
		// 定义一个缓冲区来存放读取的文件名信息
		TCHAR filePath[MAX_PATH];
		DragQueryFile(hDropInfo,i,filePath,MAX_PATH);//获得拖曳的第i个文件的文件名
		//此时 filePath已经获取到了文件路径
		//do something...
	} 
	//拖放结束后,释放内存
	DragFinish(hDropInfo);  
	CDialog::OnDropFiles(hDropInfo);
}

(4)别忘了声明OnDropFiles 函数

//CMyTestDlg.h
afx_msg void OnDropFiles(HDROP hDropInfo);



2.文件拖动到Edit控件

CEdit对 WM_DROPFILES的响应需要在 CEdit的派生类中处理。
(1)创建自定义类MyEdit:

//MyEdit.h
#pragma once
class CMyEdit : public CEdit
{
	DECLARE_DYNAMIC(CMyEdit)

public:
	CMyEdit();
	virtual ~CMyEdit();

protected:
	DECLARE_MESSAGE_MAP()

public:
	afx_msg void OnDropFiles(HDROP hDropInfo);
	virtual void PreSubclassWindow();
};
// MyEdit.cpp : 实现文件
//
#include "stdafx.h"
#include "MyEdit.h"

IMPLEMENT_DYNAMIC(CMyEdit, CEdit)

CMyEdit::CMyEdit()
{
}

CMyEdit::~CMyEdit()
{
}

BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
	ON_WM_DROPFILES()
END_MESSAGE_MAP()

// CMyEdit 消息处理程序
void CMyEdit::OnDropFiles(HDROP hDropInfo)
{
	// 通过设置iFiles参数为0xFFFFFFFF,可以取得当前拖动的文件数量,
	// 当设置为0xFFFFFFFF,函数间忽略后面两个参数。
	int DropCount=DragQueryFile(hDropInfo,-1,NULL,0);//取得被拖动文件的数目
	// 循环依次取得拖动文件的File Name信息
	for(int i=0;i< DropCount;i++)
	{
		// 定义一个缓冲区来存放读取的文件名信息
		TCHAR filePath[MAX_PATH];
		DragQueryFile(hDropInfo,i,filePath,MAX_PATH);//获得拖曳的第i个文件的文件名
		//此时 filePath已经获取到了文件路径
		//do something...
	} 
	//拖放结束后,释放内存
	DragFinish(hDropInfo);  
	CDialog::OnDropFiles(hDropInfo);
}
void CMyEdit::PreSubclassWindow(){
	//也可以在资源视图修改Edit控件的Accep Files 为TRUE
	ModifyStyleEx(0,WS_EX_ACCEPTFILES,0);
	CEdit::PreSubclassWindow();
}

(2)关联自定义类到控件

//声明自定义类对象
//CMyTestDlg.h
CMyEdit m_edit;
//将类对象关联到资源
//CMyTestDlg.pp
void CMyTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT1,m_edit);
}



3.提升权限

win7以后 低权限进程向高权限进程发送消息时会被拒绝,即如果用管理员打开软件,资源管理器explorer是没法给该软件发消息的。
解决方法就是 使用 ChangeWindowMessageFilter 从用户界面权限隔离(UIPI)消息筛选器中添加消息。

另外:

[Using the ChangeWindowMessageFilter function is not recommended, as it has process-wide scope. Instead, use the ChangeWindowMessageFilterEx function to control access to specific windows as needed. ChangeWindowMessageFilter may not be supported in future versions of Windows.]

(ChangeWindowMessageFilter 已经不推荐使用 ,可以使用 ChangeWindowMessageFilterEx)

//CMyTestDlg.cpp
//OnInitDialog里
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
ChangeWindowMessageFilter(0x0049, MSGFLT_ADD);       // 0x0049 == WM_COPYGLOBALDATA

你可能感兴趣的:(WTL/MFC,MFC,文件拖动)