在使用MFC(Microsoft Foundation Classes)中的`CFileDialog`时,默认情况下它不支持多选功能。但是,你可以通过自定义钩子函数(Hook Procedure)来修改对话框的行为,虽然这种方法比较复杂且不是直接支持的。然而,更常见且直接的方法是使用`IFileOpenDialog`接口,这是Windows Vista及以后版本中推荐的用于打开和保存文件对话框的接口,它支持多选。
以下是一个使用`IFileOpenDialog`接口实现文件多选的示例,而不是修改`CFileDialog`的DoModal方法(因为`CFileDialog`本身不直接支持多选):
#include <windows.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <iostream>
#include <vector>
// 辅助函数,用于从IShellItemArray获取文件路径
void GetFilesFromShellItemArray(IShellItemArray* psiItemArray, std::vector<std::wstring>& files)
{
DWORD dwNumItems = 0;
HRESULT hr = psiItemArray->GetCount(&dwNumItems);
if (SUCCEEDED(hr))
{
for (DWORD i = 0; i < dwNumItems; ++i)
{
IShellItem* psi;
hr = psiItemArray->GetItemAt(i, &psi);
if (SUCCEEDED(hr))
{
LPWSTR pszFilePath;
hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
if (SUCCEEDED(hr))
{
files.push_back(pszFilePath);
CoTaskMemFree(pszFilePath);
}
psi->Release();
}
}
}
}
// 函数用于打开文件对话框并支持多选
bool OpenFileDialogWithMultiSelect(HWND hwndOwner, std::vector<std::wstring>& files)
{
IFileOpenDialog* pFileOpen;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr))
{
pFileOpen->SetOptions(FOS_ALLOWMULTISELECT | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST);
if (hwndOwner)
{
pFileOpen->SetOwner(hwndOwner);
}
hr = pFileOpen->Show(NULL);
if (SUCCEEDED(hr))
{
IShellItemArray* psiResult;
hr = pFileOpen->GetResults(&psiResult);
if (SUCCEEDED(hr))
{
GetFilesFromShellItemArray(psiResult, files);
psiResult->Release();
}
}
pFileOpen->Release();
}
return SUCCEEDED(hr);
}
int main()
{
std::vector<std::wstring> selectedFiles;
if (OpenFileDialogWithMultiSelect(NULL, selectedFiles))
{
for (const auto& file : selectedFiles)
{
std::wcout << file << std::endl;
}
}
else
{
std::wcout << L"No files selected." << std::endl;
}
return 0;
}
在这个示例中,我们使用了`IFileOpenDialog`接口来创建一个支持多选的打开文件对话框。用户选择的文件路径会被存储在`std::vector