PS:本文中所有线程均使用CoInitialize(NULL)进行COM初始化。跨套间如何使用ActiveX控件?COM跨套间使用时需要列集和散集(书上都是这么说的),但是不知道如何操作。比如像使用ADO访问数据库(通过import导入msado15.dll,形成了IConnectionPtr智能指针)。
在主线程中定义了一个IConnectionPtr的变量m_conn,访问属性设为public,并CreateInstance然后连接数据库。
然后创建工作线程,在工作线程中直接通过((CMain*)AfxGetMainWnd())->m_conn来使用此数据库连接(使用了很长时间),没有出现过错误,为何?更棘手的问题:
在基于对话框的应用程序的主对话框(肯定是主线程喽)上通过右键菜单中的“插入ActiveX控件”,插入了一个ActiveX控件在主对话框上。然后通过类向导为该ActiveX控件关联到一个成员变量,例如将一个MSComm控件关联到m_comm。
然后创建工作线程,将主对话框的指针当作线程参数传递到工作线程,在工作线程中直接通过此参数来访问其m_comm变量来使用MSComm控件,也是正常的。
这种方法有问题吗?如果有问题的话,正确的方法应该怎么操作?

解决方案 »

  1.   

    使用CoInitializeEx(NULL,COINIT_MULTITHREADED)代替CoInitialize(NULL)
      

  2.   

    用GIT吧,搜索一下,用着方便
      

  3.   

    这样肯定是不安全的,控件都是Apartment的。问题是要在线程中使用该控件的所有功能,我该把哪个接口放到GIT中去呢?接口的IID呢?
      

  4.   

    是否能不用列集而跨线程传递指针,取决于组件的设计,对于组件被设计成free或者both类型的,说明组件内部实现了同步控制,这样的组件可以直接跨线程调用而不会造成冲突,检查一下注册表中组件登记的套间类型。
    对于只支持apartment的组件,它内部并未进行同步控制,直接跨线程调用会产生不可预知的后果,尤其是组件方法中需要传递其他接口指针时几乎百分百出错。
    如果一个组件支持free或both,那么它的方法里需要传递的其他组件也必须实现成free或both类型,否则就失去了free的意义。
      

  5.   

    to jameshooo:
    您说的这些我倒是明白。我不明白的地方:
    类似于MSCOMM控件,既然是一个ActiveX控件,那么它一定是Apartment的,不可能是Free或者Both。我是使用IDE的右键菜单中的“插入ActiveX控件...”将MSCOMM插入到主对话框(程序基于对话框,MFC)上的。
    然后我需要在工作线程中使用此控件,应该怎么办?
    1、通过CoMarshalInterThreadInterfaceIntoStream和CoGetInterfaceAndReleasStream?如果可行的话,是否工作线程对MSCOMM控件调用的所有方法实际上都是在主线程中执行的?如果MSCOMM有一个方法是一个长时间的操作,那是不是会引起主线程界面无响应?
    2、直接在工作线程中创建MSCOMM控件的实例。对于MFC程序,是否需要在每一个工作线程中调用AfxEnableControlContainer函数?还是只需要在APP类中调用此函数?还是有其它的解决方法?
      

  6.   

    谢谢楼上的热心回复。我是使用IDE的右键菜单中的“插入ActiveX控件...”将MSCOMM插入到主对话框(程序基于对话框,MFC)上的。 
    然后我需要在工作线程中使用此控件,应该怎么办? 
    1、通过CoMarshalInterThreadInterfaceIntoStream和CoGetInterfaceAndReleasStream?如果可行的话,是否工作线程对MSCOMM控件调用的所有方法实际上都是在主线程中执行的?如果MSCOMM有一个方法是一个长时间的操作,那是不是会引起主线程界面无响应? 
    2、直接在工作线程中创建MSCOMM控件的实例。对于MFC程序,是否需要在每一个工作线程中调用AfxEnableControlContainer函数?还是只需要在APP类中调用此函数?还是有其它的解决方法?期待对第一个问题的更肯定的答复以及第二个问题的回答。
      

  7.   

    1、理解完全正确。
    2、一个组件如果设计得好,每个方法调用都不会占用很长时间,如果真的有耗时操作,应该在组件内部实现多线程,然后使用连接点的方式通知客户端操作状态和结果。
    另外,不要被ActiveX这个词给迷惑了,老实说MFC中用ActiveX这个词就不对,_ConnectionPtr和mscomm组件都是普通的组件,即创建即用,真正的ActiveX组件是必须存活在容器中的。