在我的C++ Win 32应用程序中,我正在创建一个对话框来选择一个使用IFileOpenDialog的文件夹。请参阅以下代码:
HRESULT DialogService::CreateDialogToPickFolder(HWND hWnd)
{
IFileOpenDialog* pPickFolderDialog = NULL;
IShellItem* pPickedFolder = NULL;
HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pPickFolderDialog));
if (SUCCEEDED(hr))
{
DWORD dialogOptions;
hr = pPickFolderDialog->GetOptions(&dialogOptions);
if (SUCCEEDED(hr))
{
hr = pPickFolderDialog->SetOptions(dialogOptions | FOS_PICKFOLDERS);
if (SUCCEEDED(hr))
{
hr = pPickFolderDialog->Show(hWnd);
if (SUCCEEDED(hr))
{
hr = pPickFolderDialog->GetResult(&pPickedFolder);
if (SUCCEEDED(hr))
{
PWSTR pszFolderPath = NULL;
hr = pPickedFolder->GetDisplayName(SIGDN_FILESYSPATH, &pszFolderPath);
if (SUCCEEDED(hr))
{
// Some code...
}
}
pPickedFolder->Release();
}
}
}
pPickFolderDialog->Release();
}
return hr;
}我应付不了以下问题。如果我没有选择一个文件夹(“文件夹”字段,在对话框中为空)并单击“选择文件夹”按钮(即确定),代码行
hr = pPickedFolder->GetDisplayName(SIGDN_FILESYSPATH, &pszFolderPath);将先前选择的路径写入pszFolderPath变量,对话框将关闭。但我想确保,在这种情况下,对话框仍然在屏幕上,并且pszFolderPath的值保持在0x00000000。因为只有当用户真正选择了文件夹,并且所选文件夹的名称显示在对话框的“文件夹”字段时,对话框才会关闭。(当然,如果要关闭对话框,用户单击“选择文件夹”按钮。(不用说。)如果没有选择文件夹,单击“确定”按钮时,如何防止对话框关闭?请帮帮我。
发布于 2019-11-25 06:30:18
在对话框即将返回之前调用的OnFileOk事件具有一个结果。它提供了一个保持对话保持开放的机会。如果认为文件夹路径无效,则返回S_FALSE以防止对话框关闭。
// 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 = pPickFolderDialog->Advise(pfde, &dwCookie);
if (SUCCEEDED(hr))
{
// ...
hr = pPickFolderDialog->GetOptions(&dialogOptions);
// ...
// Unhook the event handler.
pfd->Unadvise(dwCookie);
}
pfde->Release();
}
// IFileDialogEvents methods
IFACEMETHODIMP OnFileOk(IFileDialog * pfd)
{
// If the folder field is empty, return S_FALSE, the dialog should remain open.
// Check folder is selected or not here.
//return S_FALSE;
return S_OK;
};它可能需要OnFileOk方法中的解析操作来确认“文件夹:”字段是否为空。
请参阅"公用项对话框。
更新:添加代码行以检查“文件夹:”中的路径是否为空。下面是一个可以参考的使用UIAutomation的示例。
#include <UIAutomation.h>
IUIAutomation *pClientUIA;
IUIAutomationElement *pRootElement;
BOOL IsPathEmpty(HWND hwnd)
{
HRESULT hr;
hr = CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER, IID_IUIAutomation, reinterpret_cast<void**>(&pClientUIA));
if (S_OK != hr)
{
printf("CoCreateInstance error: %d\n", GetLastError());
return FALSE;
}
hr = pClientUIA->ElementFromHandle(hwnd, &pRootElement);
if (S_OK != hr)
{
printf("ElementFromHandle error: %d\n", GetLastError());
return FALSE;
}
BSTR name;
hr = pRootElement->get_CurrentClassName(&name);
if (S_OK != hr)
{
printf("get_CurrentClassName error: %d\n", GetLastError());
return FALSE;
}
wprintf(L"Class Name: %s\n", name);
IUIAutomationCondition *pCondition;
VARIANT varProp;
varProp.vt = VT_I4;
varProp.uintVal = UIA_EditControlTypeId;
hr = pClientUIA->CreatePropertyCondition(UIA_ControlTypePropertyId, varProp, &pCondition);
if (S_OK != hr)
{
printf("CreatePropertyCondition error: %d\n", GetLastError());
return FALSE;
}
IUIAutomationElementArray *pElementFound;
hr = pRootElement->FindAll(TreeScope_Descendants, pCondition, &pElementFound);
if (S_OK != hr)
{
printf("CreatePropertyCondition error: %d\n", GetLastError());
return FALSE;
}
int eleCount;
pElementFound->get_Length(&eleCount);
for (int i = 0; i < eleCount; i++)
{
IUIAutomationElement *pElement;
hr = pElementFound->GetElement(i, &pElement);
if (S_OK != hr)
{
printf("CreatePropertyCondition error: %d\n", GetLastError());
return FALSE;
}
hr = pElement->get_CurrentName(&name);
if (S_OK != hr)
{
printf("CreatePropertyCondition error: %d\n", GetLastError());
return FALSE;
}
wprintf(L"Control Name: %s\n", name);
OutputDebugString(name);
if (0 == wcscmp(name, L"Folder:"))
{
VARIANT varPropText;
hr = pElement->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &varPropText);
if (S_OK != hr)
{
printf("CreatePropertyCondition error: %d\n", GetLastError());
return FALSE;
}
if (0 == wcscmp(varPropText.bstrVal, L""))
{
return TRUE;
}
}
}
return FALSE;
}OnFileOk方法可以如下所示的所有IsPathEmpty方法:
// IFileDialogEvents methods
IFACEMETHODIMP OnFileOk(IFileDialog * pfd)
{
// If the folder field is empty, return S_FALSE, the dialog should remain open.
// Check folder is selected or not here.
//return S_FALSE;
IOleWindow *pWindow;
HRESULT hr = pfd->QueryInterface(IID_PPV_ARGS(&pWindow));
if (SUCCEEDED(hr))
{
HWND hwndDialog;
hr = pWindow->GetWindow(&hwndDialog);
if (SUCCEEDED(hr))
{
if (IsPathEmpty(hwndDialog))
return S_FALSE;
}
pWindow->Release();
}
return S_OK;
};https://stackoverflow.com/questions/59019061
复制相似问题