MFC OCX多线程问题

来源:互联网 发布:产品经理mac软件 编辑:程序博客网 时间:2024/05/16 16:39

出现了一个问题,测试明白是什么情况,就是不知道为什么,搜也搜不到原因。


更新::结果又测试了一下,网上又找了下。。。找到原因了,写到后面


前提:

   新建ocx开发的工程,生成的主类叫 CTestOcxCtrl ,添加一个外部接口:TestInterface()

   然后添加一个事件:TestWrongEvent(long result)

现象:

  1、就在CTestOcxCtrl下,如果直接在接口函数TestInterface里,发送事件TestWrongEvent(123);

  外部容器是能收到这个事件的。

  2、在外部接口TestInterface里创建个线程,我用的AfxBeginThread,然后在这个线程里发送事件TestWrongEvent(123)

   外部容器就是收不到。。。

  3、然后我在线程里给CTestOcxCtrl发送个自定义消息,在自定义消息里我在发送事件TestWrongEvent(123),

    这时的结果是,用非阻塞的PostMessage发送,外部容器就能收到;这时相当于不是原来这个线程里发送Event了。

     用阻塞的SendMessage发送,外部容器就收不到。这时相当于还是在这个县城里发送Event。


结论:

  通过现象,就是,在我自己创建一个线程里发送Event,外部容器收不到。。。但是postmessage其实也相当于另一个线程里了呀,外部容器就能收到。


原因:

开始以为我用AfxBeginThread开线程有影响,就用CreateThread重新试了下在线程里发送事件,结果。。直接崩溃了。。。

看了堆栈,发现是fireevent那里的问题,就搜了下 filreevent 线程,结果果然有人碰见过!!还有人给了答案!!


答案就是:

首先 不要在内部创建的线程调用FireEvent,postmessage到ActiveX控件窗口,由那里调用FireEvent

    你必须在主线程中激发事件,你在工作线程中投递一个消息到主线程中,然后再激发事件,但你最好不要用窗口类的指针,应该用窗口句柄发送,就像这样::PostMessag(hWndDlg,...);

那是因为FireEvent实际上是调用客户端实现的一个接口(在这就是IE实现的IDispatch接口)的方法,而ActiveX控件一定是放在STA套间(虽然也可以,但应该没人实现为放在MTA)的,因此工作线程调用IE的IDispatch接口一定且必须是代理接口,这个接口必须通过汇集得到(以创建代理对象)。
即需要在主线程调用CoMarshalInterface来列集IE的那个IDispatch接口,再在工作线程调用CoUnmarshalInterface来散集IDispatch接口,进而在工作线程中通过散集的IDispatch接口发起事件



总之。。。反正是多线程引起的,控件和外部容器的主线程,有影响吧,这里有详细的建议什么的:

http://support.microsoft.com/kb/157437

反正这种情况,还是用发送消息好,postmessage过去。

0 0