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