Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在对话框中宿主预览处理程序_C++_Excel_Winapi_Com_Ipreviewhandler - Fatal编程技术网

C++ 如何在对话框中宿主预览处理程序

C++ 如何在对话框中宿主预览处理程序,c++,excel,winapi,com,ipreviewhandler,C++,Excel,Winapi,Com,Ipreviewhandler,我正试图在对话框中托管一个文件预览处理程序。我已经为资源管理器中的选择更改设置了事件接收器。当选择发生更改时,我将所选的shell项提供给对话框,而对话框又将其提供给准备预览帧的函数 通常,它会成功加载正确的处理程序并显示文件内容,但对于某些文件类型(即Excel和Word文件),它会遇到各种问题,如焦点丢失或闪烁。下面是Excel预览处理程序弄乱焦点的演示(我所说的弄乱是指它错误地从资源管理器中窃取了焦点,我希望保持焦点): Word文件可能会成功加载一次,但随后会失败,尤其是在打开Word

我正试图在对话框中托管一个文件预览处理程序。我已经为资源管理器中的选择更改设置了事件接收器。当选择发生更改时,我将所选的shell项提供给对话框,而对话框又将其提供给准备预览帧的函数

通常,它会成功加载正确的处理程序并显示文件内容,但对于某些文件类型(即Excel和Word文件),它会遇到各种问题,如焦点丢失或闪烁。下面是Excel预览处理程序弄乱焦点的演示(我所说的弄乱是指它错误地从资源管理器中窃取了焦点,我希望保持焦点):

Word文件可能会成功加载一次,但随后会失败,尤其是在打开Word时

至于守则:

对于初学者,这里是我从文件扩展名获取预览处理程序的函数。这似乎很管用:

HRESULT PreviewHandlerFromExt(LPCWSTR pszExt, IPreviewHandler** ppph)
{
    WCHAR szCLSID[CLSID_LEN] = { 0 };
    DWORD cchOut = CLSID_LEN;
    HRESULT hr = AssocQueryString(  ASSOCF_INIT_DEFAULTTOSTAR,
                                    ASSOCSTR_SHELLEXTENSION,
                                    pszExt,
                                    L"{8895b1c6-b41f-4c1c-a562-0d564250836f}",
                                    szCLSID,
                                    &cchOut );
    if (FAILED(hr))
    {
        return hr;
    }

    CLSID clsid;
    hr = CLSIDFromString(szCLSID, &clsid);
    if (FAILED(hr))
    {
        return hr;
    }

    CComPtr<IUnknown> punk;
    hr = punk.CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER);
    if (FAILED(hr))
    {
        return hr;
    }

    CComPtr<IPreviewHandler> pPrevHandler;
    hr = punk->QueryInterface(&pPrevHandler);
    if (FAILED(hr) || !pPrevHandler)
    {
        return hr;
    }

    return pPrevHandler.CopyTo(ppph);
}
有人知道我做错了什么,或者什么可以解决这些焦点问题吗

我还尝试在不同的位置放置
locksetforegroundindow
,但没有锁

此外,这是对话框资源的外观:


不是你,是Excel预览处理程序不符合标准(即预览处理程序不得窃取焦点)。你对解决方法有什么想法吗?资源管理器的预览窗格能够在不更改焦点的情况下托管Excel预览处理程序,因此它可能还执行了其他操作来保持焦点?预览窗口是文件资源管理器中的子窗口()。下面是一个例子:“你可以检查一下它是否有用。你有完整的复制项目吗?”?魔鬼有时躲在里面details@loop123123您是否尝试过在子窗口而不是对话框中显示预览?或者你可以展示一个小的,完整的,可复制的样品,这样我们可以做进一步的调查。
void CMyDialog::ShowPreview(IShellItem* pShItem)
{
    HRESULT hr;

    if (m_pPreviewHandler)
    {
        m_pPreviewHandler->Unload();
        m_pPreviewHandler.Release();
    }

    CComHeapPtr<WCHAR> pszPath;
    hr = pShItem->GetDisplayName(SIGDN_FILESYSPATH, &pszPath);
    if (FAILED(hr))
    {
        return;
    }

    LPWSTR pszExt = CharLower(PathFindExtension(pszPath));

    auto it = m_mapExtsToPreviewHandlers.find(pszExt);
    if (it == m_mapExtsToPreviewHandlers.end())
    {
        hr = PreviewHandlerFromExt(pszExt, &m_pPreviewHandler);
        if (FAILED(hr) || !m_pPreviewHandler)
        {
            return;
        }

        m_mapExtsToPreviewHandlers[pszExt] = m_pPreviewHandler;
    }

    else
    {
        m_pPreviewHandler = m_mapExtsToPreviewHandlers[pszExt];
    }

    CComPtr<IInitializeWithFile> pInitWithFile;
    hr = m_pPreviewHandler->QueryInterface(&pInitWithFile);
    if (SUCCEEDED(hr))
    {
        hr = pInitWithFile->Initialize(pszPath, STGM_READ);
        if (FAILED(hr))
        {
            return;
        }
    }

    else
    {
        CComPtr<IInitializeWithStream> pInitWithStream;
        hr = m_pPreviewHandler->QueryInterface(&pInitWithStream);
        if (SUCCEEDED(hr))
        {
            CComPtr<IStream> pStream;
            hr = SHCreateStreamOnFile(pszPath, STGM_READ, &pStream);
            if (FAILED(hr) || !pStream)
            {
                return;
            }

            hr = pInitWithStream->Initialize(pStream, STGM_READ);
            if (FAILED(hr))
            {
                return;
            }
        }
    }

    CWindow wndPreviewFrame( GetDlgItem(IDC_PREVIEWFRAME) );
    CRect rectPreviewFrame;
    wndPreviewFrame.GetClientRect(&rectPreviewFrame);

    hr = m_pPreviewHandler->SetWindow(wndPreviewFrame, &rectPreviewFrame);
    if (FAILED(hr))
    {
        return;
    }

    hr = m_pPreviewHandler->DoPreview();
    if (FAILED(hr))
    {
        return;
    }

    hr = m_pPreviewHandler->SetRect(&rectPreviewFrame);
    if (FAILED(hr))
    {
        return;
    }
}