你的位置:首页 > 操作系统

[操作系统]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 0x4A0LRESULT 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