通过浏览器浏览器选择预览文件存储路径
在工作中遇到这个需求,需要选择文件的存储这里我列举两种方法供大家参考:
1、通过SHBrowseForFolder实现具体代码和讲解如下:
wchar_t szPath[MAX_PATH]; //存放选择的目录路径
ZeroMemory(szPath, sizeof(szPath));
BROWSEINFO bi;
memset(&bi, 0, sizeof(BROWSEINFO));
DWORD dwPid = GetPidByProcessName(_T("firefox.exe"));//这个更具不用设置不同父类句柄,我不想在任务栏中显示出来,所以我把他的父类句柄设置称浏览器
HWND hWnd = GetHwndByPid(dwPid);
bi.hwndOwner = hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName =szPath;
bi.lpszTitle = L"保存的目录:";
bi.ulFlags = 0;
bi.lpfn = NULL;
bi.lParam = 0;
bi.iImage = 0;
LPITEMIDLIST lp = SHBrowseForFolder(&bi);
if (lp)
{
bool list = SHGetPathFromIDList(lp, szPath);
//打开成功
}
else
{
//打开失败
}
2、通过GetOpenFileName函数实现,这个实现方法需要增加对话框和消息钩子进行处理
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_ENABLEHOOK
| OFN_HIDEREADONLY
| OFN_CREATEPROMPT
| OFN_SHAREAWARE
| OFN_ENABLESIZING;
openFile.hInstance = (HMODULE)GetCurrentProcess();
openFile.lpfnHook = MyFolderProc;
if (GetOpenFileName(&openFile))
{
strDir = wstring2string(szFileName);
}
else
{
DWORD ret = CommDlgExtendedError();
strDir = str;
}
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按钮等控件的消息在父窗口处理。
LogInfo("MyFolderProc\n");
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;
}
通过以上两种方式都可以浏览文件夹去保存文件