本文所用SOUI版本为1.0版本,在拖文件上与一般的消息略有不同。
1.添加拖文件消息响应
先与常规添加消息相同。
class CMainFrm : public SHostWnd { public: CMainFrm(void); ~CMainFrm(void); void OnDropFile(HDROP hDropInfo) { SetMsgHandled(FALSE); UINT nFileCount = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0); TCHAR szFileName[_MAX_PATH] = _T(""); DWORD dwAttribute; // 获取拖拽进来文件和文件夹 for (UINT i = 0; i < nFileCount; i++) { ::DragQueryFile(hDropInfo, i, szFileName, sizeof(szFileName)); dwAttribute = ::GetFileAttributes(szFileName); // 是否为文件夹 if ( dwAttribute & FILE_ATTRIBUTE_DIRECTORY ) { SMessageBox(m_hWnd, "注意:不支持拖拽添加文件夹", "系统提示", MB_OK|MB_ICONWARNING); } else { std::string file_path = szFileName; //添加代码........... } } ::DragFinish(hDropInfo); } void OnClose() ; protected: //soui消息 EVENT_MAP_BEGIN() EVENT_NAME_COMMAND(L"btn_close", OnClose) EVENT_MAP_END() //HostWnd真实窗口消息处理 BEGIN_MSG_MAP_EX(CMainFrm) MSG_WM_DROPFILES(OnDropFile) CHAIN_MSG_MAP(SHostWnd) REFLECT_NOTIFICATIONS_EX() END_MSG_MAP() }
到这里完成了SOUI添加消息的比较完整的过程。但是发现窗口并不响应拖文件。
2.使窗口可以拖文件
参考简单方法解决Vista/Win7 无法接收WM_DROPFILES问题 ,添加如下函数
BOOL ChangeWndMessageFilter(UINT uMessage, BOOL bAllow) { typedef BOOL (WINAPI* ChangeWindowMessageFilterFn)(UINT, DWORD); HMODULE hUserMod = NULL; BOOL bResult = FALSE; hUserMod = LoadLibrary( "user32.dll" ); if ( hUserMod == NULL ) { return FALSE; } // 获取ChangeWindowMessageFilter函数接口指针 ChangeWindowMessageFilterFn pfnChangeWindowMessageFilter = (ChangeWindowMessageFilterFn)GetProcAddress( hUserMod, "ChangeWindowMessageFilter" ); if ( pfnChangeWindowMessageFilter == NULL ) { FreeLibrary( hUserMod ); return FALSE; } bResult = pfnChangeWindowMessageFilter( uMessage, bAllow?1:2 ); // 1-MSGFLT_ADD, 2-MSGFLT_REMOVE FreeLibrary( hUserMod ); return bResult; }
然后在初始化函数中添加如下:
BOOL OnInitDialog(HWND wndFocus, LPARAM lInitParam) { SetMsgHandled(FALSE); shellNotifyIcon.Create(m_hWnd,GETRESPROVIDER->LoadIcon(_T("ICON_LOGO"),16)); shellNotifyIcon.Show(); m_bLayoutInited=TRUE; //拖文件相关 DragAcceptFiles(m_hWnd, TRUE); ChangeWndMessageFilter(0x0049, MSGFLT_ADD); ChangeWndMessageFilter(WM_DROPFILES, MSGFLT_ADD); return TRUE; }
这样就实现了文件拖曳。
完整代码如下:
class CMainFrm : public SHostWnd { public: CMainFrm(void); ~CMainFrm(void); BOOL ChangeWndMessageFilter(UINT uMessage, BOOL bAllow) { typedef BOOL (WINAPI* ChangeWindowMessageFilterFn)(UINT, DWORD); HMODULE hUserMod = NULL; BOOL bResult = FALSE; hUserMod = LoadLibrary( "user32.dll" ); if ( hUserMod == NULL ) { return FALSE; } // 获取ChangeWindowMessageFilter函数接口指针 ChangeWindowMessageFilterFn pfnChangeWindowMessageFilter = (ChangeWindowMessageFilterFn)GetProcAddress( hUserMod, "ChangeWindowMessageFilter" ); if ( pfnChangeWindowMessageFilter == NULL ) { FreeLibrary( hUserMod ); return FALSE; } bResult = pfnChangeWindowMessageFilter( uMessage, bAllow?1:2 ); // 1-MSGFLT_ADD, 2-MSGFLT_REMOVE FreeLibrary( hUserMod ); return bResult; } BOOL OnInitDialog(HWND wndFocus, LPARAM lInitParam) { SetMsgHandled(FALSE); m_bLayoutInited=TRUE; //拖文件相关 DragAcceptFiles(m_hWnd, TRUE); ChangeWndMessageFilter(0x0049, MSGFLT_ADD); ChangeWndMessageFilter(WM_DROPFILES, MSGFLT_ADD); return TRUE; } void OnDropFile(HDROP hDropInfo) { SetMsgHandled(FALSE); UINT nFileCount = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0); TCHAR szFileName[_MAX_PATH] = _T(""); DWORD dwAttribute; // 获取拖拽进来文件和文件夹 for (UINT i = 0; i < nFileCount; i++) { ::DragQueryFile(hDropInfo, i, szFileName, sizeof(szFileName)); dwAttribute = ::GetFileAttributes(szFileName); // 是否为文件夹 if ( dwAttribute & FILE_ATTRIBUTE_DIRECTORY ) { SMessageBox(m_hWnd, "注意:不支持拖拽添加文件夹", "系统提示", MB_OK|MB_ICONWARNING); } else { std::string file_path = szFileName; //添加代码........... } } ::DragFinish(hDropInfo); } void OnClose() ; protected: //soui消息 EVENT_MAP_BEGIN() EVENT_NAME_COMMAND(L"btn_close", OnClose) EVENT_MAP_END() //HostWnd真实窗口消息处理 BEGIN_MSG_MAP_EX(CMainFrm) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_DROPFILES(OnDropFile) CHAIN_MSG_MAP(SHostWnd) REFLECT_NOTIFICATIONS_EX() END_MSG_MAP() private: BOOL m_bLayoutInited;/**<UI完成布局标志 */ }