控件是有窗口的,我只知道将控件添加到工程,此时控件被包装成了一个继承自CWnd的类,通过InvokeHelper函数来调用控件的接口,但这样好像效率不高,我试过用#import指令将控件导入到工程,可是CreateInstance后,调用控件的方法就出现非法操作,而ADO则不会,因为控件是双接口的,是不是这个原因而不能用#import加上CreateInstance这种方法呢?能不能像使用纯COM那样使用控件,即CoCreateInstance或者CoGetClassOjbect,如果能,应该如何使用。
我对COM的理解还可以,但对于IDispatch接口,非常的不熟悉,请说得详细一点,谢谢。

解决方案 »

  1.   

    我一般也是使用添加到工程的方法,响应消息,添加变量什么的很方便。
    双接口不会影响#import方式的使用。
    直接使用的话,你得有接口定义,clsid声明等。
      

  2.   

    有窗口的ActiveX控件貌似不可以用CreateInstance来直接创建,因为创建的对象需要一个窗口作为包容器。http://support.microsoft.com/kb/192560
      

  3.   

    如果有窗口的控件只能用CreateWindow来创建的话,那么创建好后,在调用控件的方法时,有没有不通过InvokeHelper函数的办法,InvokeHelper应该访问的是IDispatch接口吧,不是直接的真正的对控件接口的调用,这肯定会影响到速度的。
      

  4.   


    效率应该有影响,但应该不大。偶也不太懂这个,具体你倒是可以看看ATL中CAxWindow的实现。
    使用CAxWindow的例子:http://www.codeproject.com/KB/wtl/wtl4mfc6.aspx
      

  5.   

    to jameshooo 
    我不是指的智能指针,我记得双接口好像主要解决在脚本语言中的调用问题,不知道我记错没有:
    short result;
    static BYTE parms[] =
    VTS_I4 VTS_BSTR VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I2 VTS_I2 VTS_I2 VTS_I2 VTS_BOOL;
    InvokeHelper(0x1e, DISPATCH_METHOD, VT_I2, (void*)&result, parms,
    Address, pSign, PenColor, PenStyle, LineWidth, BrushColor, BrushStyle, CurveMode, NodeMode, Mask, bUpdate);
    return result;看看上面的调用,首先InvokeHelper是个参数不定的函数,所以编译后的代码会较大,而且传了一个类似于字符串的东西:
    static BYTE parms[] =
    VTS_I4 VTS_BSTR VTS_I4 VTS_I2 VTS_I2 VTS_I4 VTS_I2 VTS_I2 VTS_I2 VTS_I2 VTS_BOOL;
    看来是用来指定传入参数的类型,这样一来,在调用真正的接口之前,还要解析字符串,而且大家都知道,通过上面的调用,如果参数写错了,程序是不会崩溃的,反而会弹出一个友好的提示框,如此健壮的东西,后台的判断不会少!
    这些好像都不是智能指针的问题吧?
      

  6.   

    我以为你嫌Invoke麻烦,想直接调用虚表。
    没错,InvokeHelper确实会按照params指示的一系列类型标示来动态构造VARIANT数组作为Invoke的参数,但是相比列集散列的慢速度来说小巫见大巫。如果跨线程或者跨进程边界调用接口方法,即使使用的是虚表,那也是代理接口的虚表,列集散列的过程是少不了的。