转自:http://blog.const.net.cn/a/10271.htm
QaxContainer模块是访问ActiveX控件和COM对象的一个Windows扩展。QAxContainer模块是ActiveQt构架的一部分。它提供一个库,由担当ActiveX控件容器角色的QWidget的子类Q...
QaxContainer模块是访问ActiveX控件和COM对象的一个Windows扩展。 QAxContainer模块是ActiveQt构架的一部分。它提供一个库,由担当ActiveX控件容器角色的QWidget的子类QAxWidget 和 用来简化访问非可视化COM对象的QObject的子类QAxWidget 实现。通过类QAxScript, QAxScriptManager和QAxScriptEngine可以解释嵌入的COM对象,还有一个工具集使得编程访问COM对象更容易。 模块由6个类构成: 1. QAxBase 是一个提供用来初始化和访问一个COM对象及ActiveX控件的API的抽象类。 2. QAxObject是一个包装了COM对象的QObject。 3. QAxWidget 是一个包装了ActiveX控件的QWidget。 4. QAxScriptManager, QAxScript 和 QAxScriptEngine provide an interface to the Windows Script Host. Some example applications that use standard ActiveX controls to provide high-level user interface functionality are provided. 提供了一些使用标准ActiveX控件来提供高级用户界面功能的示例。 The QAxContainer module is part of the Qt Desktop Edition for Windows. It is not part of the Qt Open Source Edition. ===================================================== 1. 使用库 构造使用COM对象和ActiveX控件的Qt应用程序,需要向.pro文件中加入 CONFIG += qaxcontainer 来连接到QAxContainer模块 1.1. 配置QAxContainer应用程序 QaxContainer库是静态的,因此使用这个模块的时候不需要重新分配任何额外的文件。但要注意,你所使用的提供ActiveX服务的二进制文件必须被安装在目标系统中,因此你需要把它们装在你的发布包中并在你的应用程序安装过程中为它们注册。 2. 初始化COM对象 可以通过使用QAxBase::setControl() 或 直接把对象的名字传到QAxBase子类的构造器中 来初始化一个COM对象。 控件能通过多种格式指定,但最快且功能最强的格式是直接使用对象的Class ID(CLSID)。 Class ID能考虑到这个对象涉及别的机器时信息的变化,而且能为需要license的控件包括一个license key。 2.1. 典型的错误信息 ActiveQt在运行中遇到错误时会向debug output显示错误信息。通常要在调试器下运行你的程序来查看这些信息(e.g. in Visual Studio's Debug output)。 -- Requested control could not be instantiated The control requested in QAxBase::setControl() is not installed on this system, or is not accessible for the current user. The control might require administrator rights, or a license key. If the control is licensed, pass the license key to QAxBase::setControl as documented. 3. 访问对象API 模块提供了访问COM对象的Qt API来取代COM的数据类型。 有4种方法去调用访问COM对象的API: • Generating a C++ namespace • Call-by-name • Through a script engine • Using the native COM interfaces 3.1. 生成 C++ Namespace 用dumpcpp 工具可以为想要访问的类型库生成一个C++名空间。需要手动对你要用的类型库使用这个工具, 或者也可以通过向.pro文件中的变量TYPELIBS添加类型库来把它整合到编译系统中: TYPELIBS = file.tlb 注意,dumpcpp不一定能列出类型库中所有的API。 把生成的头文件包含进你的代码中,通过生成的C++类来访问对象API。 更多信息可以参考示例Qutlook。 3.2. Call-by-Name 用QAxBase::dynamicCall()、QAxBase::querySubObject() 和QObject::setProperty()、QObject::property() 能通过名字调用COM对象的方法和属性。用dumpdoc工具能获得COM对象和他的字对象的Qt API文档。注意不是所有的COM对象的API是可用的。 更多请参看示例Webbrowser。 3.3. Calling Function Through a Script Engine Qt应用程序能使用安装在系统上的任何ActiveScript engine。Script engine能运行脚本代码去访问COM对象。 使用script engine时,用QAxScriptManager::addObject()注册你想通过脚本访问的COM对象,用QAxScriptManager::load()把script代码装入引擎。接着就可以用QAxScriptManager::call() 或 QAxScript::call()来调用script函数。 COM对象的API结束了脚本对所使用的脚本语言的依赖。 ActiveX Test Container 示范了如何装载脚本文件。 3.4. Calling a Function Using the Native COM Interfaces 上面的方法都不能访问的COM对象函数,可以直接用QAxBase::queryInterface()去查询COM接口。它可以获得控件的类型库中用#import标示的各个接口类的C++定义;更多的细节请看你的编译器手册。 3.5. 典型的错误信息 ActiveQt在运行中遇到错误的时候会向debug output显示错误信息。通常你必须在调试器下运行你的程序来查看这些信息(e.g. in Visual Studio's Debug output)。 -- QAxBase::internalInvoke: No such method A QAxBase::dynamicCall() failed - the function prototype did not match any function available in the object's API. -- Error calling IDispatch member: Non-optional parameter missing A QAxBase::dynamicCall() failed - the function prototype was correct, but too few parameters were provided. -- Error calling IDispatch member: Type mismatch in parameter n A QAxBase::dynamicCall() failed - the function prototype was correct, but the paramter at index n was of the wrong type and could not be coerced to the correct type. -- QAxScriptManager::call(): No script provides this function You try to call a function that is provided through an engine that doesn't provide introspection (ie. ActivePython or ActivePerl). You need to call the function directly on the respective QAxScript object.