我正在尝试在我的Win32应用程序中嵌入一个WMP控件。 我在这里遵循了示例代码:Hosting the Windows Media Player Control in a Windows Application
然而,当我单步执行此示例时,行:
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);
如果有人能够更好地阐明这一点,那就太棒了。
Edit2 :刚刚注意到我在输出窗口中收到了垃圾邮件,而我正在逐步完成此代码:
“由于应用程序正在调度输入同步调用,因此无法拨打电话” 任何想法?
答案 0 :(得分:1)
代码是正确的,并且按照MSDN页面上的建议工作。
如果您的UI窗口位于MTA单元中,则可能会出现完全如上所述的问题,即您运行的线程已使用CoInitializeEx(NULL, COINIT_MULTITHREADED)
初始化。
然后发生了什么,你的WMP在一个侧面STA线程上被实例化,它的接口被编组到你的线程/公寓中。并非每个必需的接口都可以这种方式传输,所以一旦你继续初始化它就会丢失一些强制接口......
WMP正在使用“Apartment”线程模型,在STA线程上使用它。