在win32桌面开发时,经常需要打开选择路径选择对话框,拿本地录像功能来说,比如第一次选择了c:\record目录,则第二次,打开路径选择对话框时,希望直接定位到上一次选择的路径,如下所示:
直接定位到c:\record。
大致代码如下:
// BrowserDirectoryTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <Windows.h>
#include <Shlobj.h>
#pragma comment(lib, "Shell32.lib")
// 此回调函数为全局函数或静态函数;
int CALLBACK BrowseCallbackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
{
std::string strInitDir = "c:\\record";
switch(uMsg)
{
case BFFM_INITIALIZED:
{
::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)strInitDir.c_str());
}
break;
default:
break;
}
return 0;
}
bool SelectFilePath(std::string& strFilePath)
{
char szPathName[MAX_PATH] = { 0 };
BROWSEINFOA bInfo = { 0 };
bInfo.hwndOwner = GetForegroundWindow(); // 父窗口;
bInfo.lpszTitle = "选择目录";
bInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI /*包含一个编辑框 用户可以手动填写路径 对话框可以调整大小之类的..;*/
| BIF_UAHINT /*带TIPS提示*/ /*| BIF_NONEWFOLDERBUTTON 不带新建文件夹按钮*/;
// 关于更多的 ulFlags 参考 http://msdn.microsoft.com/en-us/library/bb773205(v=vs.85).aspx;
bInfo.lpfn = BrowseCallbackProc;
std::string strInitDir = "c:\\record";
bInfo.lParam = NULL;
LPITEMIDLIST lpDlist;
lpDlist = SHBrowseForFolderA(&bInfo);
if (nullptr == lpDlist) // 单击了确定按钮;
{
strFilePath.clear();
return false;
}
SHGetPathFromIDListA(lpDlist, szPathName);
strFilePath = szPathName;
return true;
}
int main()
{
std::cout << "Hello World!\n";
std::string strSelectDir;
SelectFilePath(strSelectDir);
return 0;
}
我的工程是“使用 Unicode 字符集”,如下所示:
运行的时候,发现路径选择对话框弹出的时候,并未定位到c:\record目录。
经过分析,可以通过如下修改解决此问题:
将原来的std::string变成宽字节std::wstring,由于本人对宽字节操作不熟,更习惯使用std::string,无意中发现,可以通过如下修改实现。
红色方框的宏定义后面比之前多个A。