本文所用SOUI版本爲1.0版本,在拖文件上與通常的消息略有不一樣。html
先與常規添加消息相同。shell
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添加消息的比較完整的過程。可是發現窗口並不響應拖文件。函數
參考簡單方法解決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; }
而後在初始化函數中添加以下:ui
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; }
這樣就實現了文件拖曳。spa
完整代碼以下:指針
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完成佈局標誌 */ }