首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Win32应用程序中,如果文件夹未被选中且用户单击“确定”,则文件夹选择对话框将关闭。

在Win32应用程序中,如果文件夹未被选中且用户单击“确定”,则文件夹选择对话框将关闭。
EN

Stack Overflow用户
提问于 2019-11-24 15:05:40
回答 1查看 188关注 0票数 0

在我的C++ Win 32应用程序中,我正在创建一个对话框来选择一个使用IFileOpenDialog的文件夹。请参阅以下代码:

代码语言:javascript
运行
复制
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;
}

我应付不了以下问题。如果我没有选择一个文件夹(“文件夹”字段,在对话框中为空)并单击“选择文件夹”按钮(即确定),代码行

代码语言:javascript
运行
复制
hr = pPickedFolder->GetDisplayName(SIGDN_FILESYSPATH, &pszFolderPath);

将先前选择的路径写入pszFolderPath变量,对话框将关闭。但我想确保,在这种情况下,对话框仍然在屏幕上,并且pszFolderPath的值保持在0x00000000。因为只有当用户真正选择了文件夹,并且所选文件夹的名称显示在对话框的“文件夹”字段时,对话框才会关闭。(当然,如果要关闭对话框,用户单击“选择文件夹”按钮。(不用说。)如果没有选择文件夹,单击“确定”按钮时,如何防止对话框关闭?请帮帮我。

EN

Stack Overflow用户

回答已采纳

发布于 2019-11-25 06:30:18

在对话框即将返回之前调用的OnFileOk事件具有一个结果。它提供了一个保持对话保持开放的机会。如果认为文件夹路径无效,则返回S_FALSE以防止对话框关闭。

代码语言:javascript
运行
复制
    // 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的示例。

代码语言:javascript
运行
复制
#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方法:

代码语言:javascript
运行
复制
    // 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; 
    };
票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59019061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档