实现MFC拖拽文件步骤:
以多文档为例:
1.在应用程序类App的InitInstance()函数后面,添加以下代码:
m_pMainWnd->DragAcceptFiles(TRUE);
2.响应主框架类CMainFrame的WM_DROPFILES消息,添加如下代码:
void CMainFrame::OnDropFiles(HDROP hDropInfo)
{
SetActiveWindow(); // activate us first !
UINT nFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);
CWinApp* pApp = AfxGetApp();
ASSERT(pApp != NULL);
for (UINT iFile = 0; iFile < nFiles; iFile++)
{
TCHAR szFileName[_MAX_PATH];
::DragQueryFile(hDropInfo, iFile, szFileName, _MAX_PATH);
pApp->OpenDocumentFile(szFileName);
}
::DragFinish(hDropInfo);
}
注意事项:
当在Win7、Win10中以管理员权限运行程序时,默认情况下拖拽文件的消息会失效。具体原因可以查看这里
修改方法:
ChangeWindowMessageFilter (WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter (WM_COPYDATA, MSGFLT_ADD);
ChangeWindowMessageFilter (0x0049, MSGFLT_ADD);
将上述三行代码复制到应用程序类App的InitInstance()函数后面,即可解决!
//2019.04.28更新
添加上面的三个函数到工程中,在win7和win10中倒是解决了问题,但是在xp系统中,在程序结束后会报错。
原因是:WinXP 及 Win2003 系统用户库 USER32.dll 没有 ChangeWindowMessageFilter、ChangeWindowMessageFilterEx 这两个接口,而 Windows 7 系统下,则新增之。由于 WinXP、Win2003 系统安全机制不会拦截消息,因此也就没有必要运行上述新增的代码了。但若想该测试程序在 WinXP、Win2003 系统下运行正常,且要在 Win7 系统下能正常接收上述消息,可直接从 Win7 之 USER32.dll 库中获取上述 API 函数入口地址,在 Win7 系统下肯定是可以获取到入口地址的;而在 XP 系统下就肯定获取不到其入口地址,但没关系,不会影响程序运行,亦不会报错。
解决方法:
BOOL CJHDProjectApp::ChangeWndMessageFilterOk(UINT nMessage, BOOL bAllow)
{
typedef BOOL(WINAPI * ChangeWindowMessageFilterOkFn)(UINT, DWORD);
HMODULE hModUser32 = NULL;
hModUser32 = LoadLibrary(_T("user32.dll"));
if (hModUser32 == NULL) {
return FALSE;
}
ChangeWindowMessageFilterOkFn pfnChangeWindowMessageFilter = (ChangeWindowMessageFilterOkFn)GetProcAddress(hModUser32, "ChangeWindowMessageFilter");
if (pfnChangeWindowMessageFilter == NULL)
{
FreeLibrary(hModUser32);
return FALSE;
}
FreeLibrary(hModUser32);
return pfnChangeWindowMessageFilter(nMessage, bAllow ? MSGFLT_ADD : MSGFLT_REMOVE);
}
定义ChangeWndMessageFilterOk(UINT nMessage, BOOL bAllow)函数代替ChangeWindowMessageFilter即可