窗口控件:CFileDialog
使用下面的代码进行初始化:
CFileDialog openDlg(TRUE,
NULL,
NULL,
6UL|OFN_ALLOWMULTISELECT,
"All Files|*.*||");
创建一个文件打开框对象,设置 OFN_ALLOWMULTISELECT(允许选择多个文件),6UL表示 OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY(隐藏只读,同时在覆盖现有文件前提示);
获取选择的内容:
IShellItemArray *lpResults = openDlg.GetResults();
if (NULL != lpResults)
{
HRESULT hr;
DWORD itemCount = 0;
hr = lpResults->GetCount(&itemCount);
if (FAILED(hr))
{
return vSelects;
}
for (DWORD index = 0; index < itemCount; index++)
{
IShellItem *ppsi = NULL;
hr = lpResults->GetItemAt(index, &ppsi);
if (FAILED(hr))
{
continue;
}
LPWSTR ppszName = NULL;
hr = ppsi->GetDisplayName(SIGDN_FILESYSPATH, &ppszName);
if (SUCCEEDED(hr))
{
vSelects.push_back(WcsToMbs(ppszName));
}
}
}
使用 GetResults返回一个迭代器,可以遍历选择内容;GetCount获取选择个数,GetItemAt获取指定的文件信息,内容以IShellItem类型指针返回;
GetDisplayName获取文件路径信息,SIGDN_FILESYSPATH表示要获取的信息类型,返回内容为LPWSTR(宽字符指针)类型,需要转换成多字节类型;
转换过程如下:
WcsToMbs(const LPWSTR _src)
{
if (NULL == _src)
{
return "";
}
size_t mulLen = 0;
size_t convLen = 0;
// 获取转换需要的空间大小
wcstombs_s(&mulLen, NULL, 0, _src, 0);
unique_ptr<char[]> upChar = unique_ptr<char[]>(new char[mulLen + 1]);
memset(upChar.get(), 0, mulLen + 1);
wcstombs_s(&convLen, upChar.get(), mulLen, _src, mulLen);
return string(upChar.get());
}
但是这种方法有一个问题,当路径中存在中文时就会转换失败,解决方法是使用下面的方法:
WcsToMbs(const LPWSTR _src)
{
if (NULL == _src)
{
return "";
}
size_t mulLen = 0;
size_t convLen = 0;
// 获取转换需要的空间大小
// wcstombs_s(&mulLen, NULL, 0, _src, 0);
mulLen = WideCharToMultiByte(CP_ACP, 0, _src, wcslen(_src), NULL, 0, NULL, NULL);
if (0 >= mulLen)
{
mulLen = MAX_PATH;
}
unique_ptr<char[]> upChar = unique_ptr<char[]>(new char[mulLen + 1]);
memset(upChar.get(), 0, mulLen + 1);
WideCharToMultiByte(CP_ACP, 0, _src, wcslen(_src), upChar.get(), mulLen, NULL, NULL);
// wcstombs_s(&convLen, upChar.get(), mulLen, _src, mulLen);
return string(upChar.get());
}