GetOpenFileName 选择文件夹的解决方法
Posted kocpp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GetOpenFileName 选择文件夹的解决方法相关的知识,希望对你有一定的参考价值。
某些环境下(如WIN PE)windows自带的选择文件夹api不能使用或者体验不佳。现在利用GetOpenFileName的回掉参数实现了选择文件夹选择功能。
#include <Windows.h> #include <CommCtrl.h> #include <locale.h> #include <shlwapi.h> LONG g_lOriWndProc = NULL; #define ID_COMBO_ADDR 0x47c #define ID_LEFT_TOOBAR 0x4A0 LRESULT static __stdcall _WndProc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg) { case WM_COMMAND: { if( wParam == IDOK ) { wchar_t wcDirPath[MAX_PATH] = {0}; HWND hComboAddr = GetDlgItem(hwnd, ID_COMBO_ADDR); if (hComboAddr != NULL) { GetWindowText(hComboAddr, wcDirPath, MAX_PATH); } if (!wcslen(wcDirPath)) { break; } DWORD dwAttr = GetFileAttributes(wcDirPath); if(dwAttr != -1 && (FILE_ATTRIBUTE_DIRECTORY & dwAttr)) { LPOPENFILENAMEW oFn = (LPOPENFILENAME)GetProp(hwnd, L"OPENFILENAME"); if (oFn) { int size = oFn->nMaxFile > MAX_PATH?MAX_PATH: oFn->nMaxFile; memcpy(oFn->lpstrFile, wcDirPath, size * sizeof(wchar_t)); RemoveProp(hwnd, L"OPENFILENAME"); EndDialog(hwnd, 1); } else { EndDialog(hwnd, 0); } } break; } ////////////////////////////////////////////////////////////////////////// //如果是左边toolbar发出的WM_COMMOND消息(即点击左边的toolbar), 则清空OK按钮旁的组合框。 HWND hCtrl = (HWND)lParam; if (hCtrl == NULL) { break; } int ctrlId = GetDlgCtrlID(hCtrl); if (ctrlId == ID_LEFT_TOOBAR) { HWND hComboAddr = GetDlgItem(hwnd, ID_COMBO_ADDR); if (hComboAddr != NULL) { SetWindowTextW(hComboAddr, L""); } } } break; } int i = CallWindowProc( (WNDPROC) g_lOriWndProc , hwnd, uMsg, wParam ,lParam ); return i; } UINT_PTR static __stdcall MyFolderProc( HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam ) { //参考reactos可知,hdlg 是一个隐藏的对话框,其父窗口为打开文件对话框, OK,CANCEL按钮等控件的消息在父窗口处理。 if(uiMsg == WM_NOTIFY) { LPOFNOTIFY lpOfNotify = (LPOFNOTIFY)lParam; if (lpOfNotify->hdr.code == CDN_INITDONE ) { SetPropW(GetParent(hdlg), L"OPENFILENAME", (HANDLE)(lpOfNotify->lpOFN)); g_lOriWndProc = ::SetWindowLongW( ::GetParent( hdlg ), GWL_WNDPROC , (LONG)_WndProc ); } if (lpOfNotify->hdr.code == CDN_SELCHANGE) { wchar_t wcDirPath[MAX_PATH] = {0}; CommDlg_OpenSave_GetFilePathW(GetParent( hdlg ), wcDirPath, sizeof(wcDirPath)); HWND hComboAddr = GetDlgItem(GetParent(hdlg), ID_COMBO_ADDR); if (hComboAddr != NULL) { if (wcslen(wcDirPath)) { //去掉文件夹快捷方式的后缀名。 int pathSize = wcslen(wcDirPath); if (pathSize >= 4) { wchar_t* wcExtension = PathFindExtensionW(wcDirPath); if (wcslen(wcExtension)) { wcExtension = CharLowerW(wcExtension); if(!wcscmp(wcExtension, L".lnk")) { wcDirPath[pathSize - 4] = L‘\0‘; } } } SetWindowTextW(hComboAddr, wcDirPath); } else { SetWindowTextW(hComboAddr, L""); } } } } return 1; } int _tmain(int argc, _TCHAR* argv[]) { setlocale(LC_ALL,"chs"); OPENFILENAMEW openFile; memset(&openFile, 0, sizeof(openFile)); openFile.lStructSize = sizeof(openFile); wchar_t szFileName[MAX_PATH]={0}; OPENFILENAME openFileName = {0}; openFile.lStructSize = sizeof(OPENFILENAME); openFile.nMaxFile = MAX_PATH; openFile.lpstrFilter = L"文件夹\0..\0\0"; openFile.lpstrFile = szFileName; openFile.nFilterIndex = 1; openFile.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST |OFN_ENABLEHOOK | OFN_HIDEREADONLY; openFile.hInstance = (HMODULE)GetCurrentProcess(); openFile.lpfnHook = MyFolderProc; BOOL b = GetOpenFileNameW(&openFile); wprintf(L"%d %s\n", b,szFileName); system("pause"); return 0; }
参考:http://blog.csdn.net/norsd/article/details/3476606
以上是关于GetOpenFileName 选择文件夹的解决方法的主要内容,如果未能解决你的问题,请参考以下文章
GetOpenFileName 可以将文件选择限制为与过滤器匹配的文件吗?
关于GetOpenFileName和GetSaveFileName的问题
OFN_ALLOWMULTISELECT 时 Windows API 函数 GetOpenFileName() 的字符限制是不是有解决方法?