您的位置:首页 > 运维架构

GetOpenFileName 选择文件夹的解决方法

2016-04-03 11:27 363 查看
某些环境下(如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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: