使用WebBrowser控件。
多线程环境。
主线程使用CoInitializeEx(NULL, COINIT_MULTITHREADED)初始化COM,之后创建Windows消息队列。然后创建一个子线程,同样用CoInitializeEx(NULL, COINIT_MULTITHREADED)初始化,然后在子线程内创建WebBroswer控件:
        hr = CoCreateInstance(CLSID_WebBrowser, NULL,
                              CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
                              IID_IUnknown, (LPVOID *)(&pUnk));
在该子线程函数内,由创建的WebBroswer对象QueryInterface到IOleWindow接口,调用WebBroswer对象的IOleWindow::GetWindow方法出错:0x8001010D: 因为应用程序正在发送一个输入同步呼叫,所以无法执行传出的呼叫。想来想去想不通,在同一个线程内创建的对象,怎么不能同步操作呢?怎么解决问题?

解决方案 »

  1.   

    在响应SendMessage时,直接或间接地调用了对自己的SendMessage就会报这个错。只要检查所有消息函数的响应就能查到错误的位置。
      

  2.   

    To superarhow(苏泊尔耗) :
    IOleWindow::GetWindow 是WebBrowser控件内部实现的接口函数,难道说IE控件有Bug? 那怎么解决?
    调用GetWindow时,主线程的消息循环并没有开始。
      

  3.   

    我估计你的IOleClientSite接口是在主线程实现的,当你调用IOleWindow::GetWindow的时候,主线程的消息循环处于阻塞中
      

  4.   

    To goodboyws(深夜不眠者(VCMVP)) :
    你的意思是这个时候WebBrowser控件会反过来调用主线程创建的某个对象?能否说具体一点?GetWindow到底做了什么事情?谢谢
      

  5.   

    how about IWebBrowser2::get_HWND?
      

  6.   

    To jiangsheng(蒋晟.Net[MVP]):
    你确信get_HWND的功能和IOleWindow::GetWindow是一样的?
    我调用了一下,直接返回E_FAIL,无法取到HWND
      

  7.   

    我不知道你代码是否完成,一般的做法是创建WebBrowser完成后,调用SetClientSite指定控件位置
      

  8.   

    To goodboyws(深夜不眠者(VCMVP)):
    是的,设置了主线程的对象传给了SetClientSite,难道这个时候GetWindow会立即调用主线程的对象吗?我把主线程的消息循环打开了,也还是一样的问题。不知道怎样才能获取到WebBrowser控件的HWND
      

  9.   

    All COM objects provided by the shdocvw and mshtml controls use the single- 
    threaded apartment model. To access them from a MTA you need to marshal the interfaces using CoMarshalInterThreadInterfaceInStream nad CoGetInterfaceAndReleaseStream
      

  10.   

    To jiangsheng(蒋晟.Net[MVP]):
    这份代码是WinCE中的,我拿到Windows上想不到出了这个问题,后来查注册表才发现shdocvw对象的ThreadingModel是Apartment。这一点似乎WinCE要强些阿。