官方示例: CommonFileDialogModes.cpp
如果我们想要自己创建一个通用的文件对话框,则可以使用IFileOpenDialog接口,代码参考:
HRESULT BasicFileOpen() { // CoCreate the File Open Dialog object. IFileDialog *pfd = NULL; HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd)); if (SUCCEEDED(hr)) { // Create an event handling object, and hook it up to the dialog. IFileDialogEvents *pfde = NULL; hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde)); if (SUCCEEDED(hr)) { // Hook up the event handler. DWORD dwCookie; hr = pfd->Advise(pfde, &dwCookie); if (SUCCEEDED(hr)) { // Set the options on the dialog. DWORD dwFlags; // Before setting, always get the options first in order not to override existing options. hr = pfd->GetOptions(&dwFlags); if (SUCCEEDED(hr)) { // In this case, get shell items only for file system items. hr = pfd->SetOptions(dwFlags | FOS_PICKFOLDERS); //默认选择文件夹,如果你想要选择文件,可以remove PICKFOLDERS样式,具体参考github中的BasicFile_Open示例 if (SUCCEEDED(hr)) {
// Show the dialog
hr = pfd->Show(NULL);
...
在官方示例中还添加了很多方法,比如OnFileOk,OnSelectionChange,OnOverwrite
我们可以在方法中添加我们自定义的代码来完成我们的需求,比如使用OnSelectionChange方法,在选择文件夹之后,我们需要将对话框重新移动到一个新的位置
IFACEMETHODIMP OnSelectionChange(IFileDialog* pfd) { IOleWindow* window; if (SUCCEEDED(pfd->QueryInterface(&window))) { HWND hwnd; if (SUCCEEDED(window->GetWindow(&hwnd))) { MoveWindow(hwnd, 0, 0, 600, 600, FALSE); } window->Release(); } return S_OK; }
还有OnOverwrite方法,我们在创建一个通用的文件对话框后,在save as的时候,如果存在同名的文件会触发这个方法,提醒我们是否需要覆盖该文件,那我们新建一个对话框来改变默认的选项
IFACEMETHODIMP OnOverwrite(IFileDialog* , IShellItem*psi, FDE_OVERWRITE_RESPONSE* response) { int msgboxID = MessageBox( NULL, (LPCWSTR)L"Windows already exists, Do you want to replace it?", (LPCWSTR)L"Confirm Save As", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1 ); switch (msgboxID) { case IDYES: *response = FDEOR_ACCEPT; break; case IDNO: *response = FDEOR_REFUSE; break; } return S_OK; }