IAxWinHostWindow CreateControl 在尝试在 CAxWindow 中托管 WMP 时返回E_N

IAxWinHostWindow CreateControl returns E_NOINTERFACE when trying to host WMP within a CAxWindow

本文关键字:WMP 返回 CreateControl CAxWindow IAxWinHostWindow      更新时间:2023-10-16

我正在尝试在我的 Win32 应用程序中嵌入一个 WMP 控件。我遵循了此处的示例代码:在Windows应用程序中托管Windows Media Player控件

但是,当我逐步完成此示例时,该行:

hr = spHost->CreateControl(CComBSTR(_T("{6BF52A52-394A-11d3-B153-00C04F79FAA6}")), m_wndView, 0);

返回E_NOINTERFACE;

该行:

hr = m_wndView.QueryHost(&spHost);

成功并且似乎正确填充了 sphost。

代码如下:

CAxWindow m_wndView;
CComPtr<IObjectWithSite> spHostObject;
CComPtr<IAxWinHostWindow>  spHost;
CComBSTR classID = __uuidof(WindowsMediaPlayer);
RECT rcClient = { 0, 0, 560, 335 };
m_wndView.Create(m_hWnd, rcClient, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
hr = m_wndView.QueryHost(&spHost);
if( SUCCEEDED(hr) )
{
    hr = spHost->CreateControl(classID, m_wndView, 0);  //E_NOINTERFACE
}
hr = m_wndView.QueryControl(&m_spPlayer);   //E_FAIL

谁能告诉我为什么会这样?谢谢。

编辑:实际失败的行是 ActivateAx() 函数中的这一行:

hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, m_hWnd, &m_rcPos);

如果有人能对此有更多的了解,那就太好了。

编辑2:刚刚注意到我在单步执行此代码时在输出窗口中收到此垃圾邮件:

"无法进行传出调用,因为应用程序正在调度输入同步调用"有什么想法吗?

代码是正确的,按原样工作,并且按照 MSDN 页面上的建议。

如果您的 UI 窗口位于 MTA 单元中,可能会出现与描述完全相同的问题,即您正在运行的线程已使用 CoInitializeEx(NULL, COINIT_MULTITHREADED) 初始化。

然后发生了什么,您的 WMP 在侧 STA 线程上实例化,其接口封送到您的线程/单元中。并非每个必需的接口都可以以这种方式传输,因此一旦您继续初始化它,就会缺少一些必需的接口......

WMP 正在使用"公寓"线程模型,在 STA 线程上使用它。