现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

Qt 下的COM组件开发

2014-10-08 10:09 工业·编程 ⁄ 共 1762字 ⁄ 字号 暂无评论

     Qt下的COM组件开发着实让人害怕,因为不是简单的调用,而是需要人为的去包装一下COM,然后在包装的基础上去使用COM中的方法和类。我们习惯了VC编译器带来的便利,通过VC编译器,只需直接import一下组件编译器就能自动帮我们导出COM的tlh描述文件,接下来用户就能很方便的去调用接口,使用方法。

       最新的Qt直接可以下载SDK,这些SDK直接基于MinGW编译器,所以如果想按照VC的那套方式来使用COM组件,那行不通(会报编译器不支持的错误),必须让Qt的源码在VC下编译才能使用。如果用户需要在MinGW编译器下使用COM组件,需要了解一下Qt对COM组件的包装类。我用的Qt版本是4.7,里面会用到QAxObject和QAxWidget类。QAxObject是对COM组件的包装,QAxWidget是对ActiveX控件的包装,简单理解功能性的封装我们一般就是普通的COM组件,如果涉及UI一般会用ActiveX控件。有了这两个类几乎就可以开始简单调用组件了。

     QAxObject和QAxWidget可以通过默认的构造函数建立一个空的COM组件对象(可以理解为COM容器),然后再把需要封装的组件放到空对象中,代码如下

    QAxObject   object((QObject)0);     //建立封装容器

    object.setControl(QString::fromUtf8("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}")); //填充需要封装的COM组件到容器中

    或者我们把上面的两步合并成一步,如下代码

   QAxObjectobject("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}");

   当然QAxWidget的代码和上面类似。

       解决了导入COM组件和封装的问题,接下来最重要的就是如何使用接口和方法的问题。如果上面导入过程涉及的CLSID(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)对应就是一个CoClass问题就好办很多,直接可以调用这个CoClass的方法。当然如果你手中没有COM组件的Qt方法说明,这件事依然很难入手。其实COM是个自描述的结构,任何第三方软件是可以把这种描述化信息自动导出来的。Qt有方法可以自动导出来的,参考如下代码

         QStringdoc= object.generateDocumentation(); 

QFile outFile("c:/debuglog.html");

outFile.open(QIODevice::WriteOnly|QIODevice::Append);QTextStreamts(&outFile);

ts<<doc<<endl;

导出后你会发现是一个非常好的HTML格式的帮助问题,里面对每一个方法都有调用的详细描述。参考帮助后就能开始自己调用了,

QVariantListparams0;

params0<<QVariant((int)(w.winId()));

params0<<QVariant(1);

params0<<QVariant("License");

params0<<QVariant("");

object.dynamicCall("ShowStatusDialog(int,int,QVariant, QVariant)",params0);

      上面的方法就能完成大部分的工作,如果方法中涉及很多的接口,我建议采用VC,Qt中比较麻烦,如果非要用就考虑导出COM组件的代理类。Qt自带的工具是dumpcpp,可以在Qt安装后的目录下找到DOS环境的快捷方式,然后直接运行dumpcpp,参考dumpcpp的帮助即可。导出后的文件是.h,.cpp文件,加入到工程中,很不幸,这些导出的.h,.cpp文件不一定能直接用,因为很多自定义的接口变量在导出过程中被忽略了,例如有的变量是int64,但是Qt中没有这个变量,如果有的变量是基于int64定义的,极有可能会报错,应为你要手工把定义指定为qlonglong类型。其他的错误都类似,我们只需要把错误的地方修改成Qt的类型就可以。

给我留言

留言无头像?