一、环境介绍
操作系统: win10 64位
QT版本: 5.12.6
Visual Studio IDE 版本: 2017
二、ActiveX控件介绍
ActiveX控件是Microsoft的ActiveX技术的一部分。
ActiveX控件是可以在应用程序和网络中计算机上重复使用的程序对象。创建它的主要技术是Microsoft的ActiveX技术,其中主要是组件对象模型(COM)。
ActiveX控件可以以小程序下载装入网页,也可以用在一般的Windows和Macintosh应用程序环境中。一般说来,ActiveX 控件代替了原先的OCX,它与JAVAapplet的概念和功能差不多。ActiveX控件可以由不同的可以识别Microsoft的COM技术的语言开发,它是一个组件或自包含的软件包,它可以在同一个或分布式的计算环境中开发或使用。
ActiveX控件运行有两种形式:
(1) 可独立运行的exe形式
(2) 插件dll形式 参考这里: https://blog.csdn.net/xiaolong1126626497/article/details/112556866
本篇文章讲的就是可独立运行的exe形式。
QT的帮助文档里有对ActiveX使用的详细介绍:
三、搭建开发环境
QT程序生成ActiveX插件需要使用MSVC编译器。
VS2017与QT5.12.6环境搭建可以参考这里: https://blog.csdn.net/xiaolong1126626497/article/details/112402861
四、新建工程
打开QtCreate创建一个简单的测试工程。
在UI界面拖一个日历控件,方便测试。
五、配置工程生成ActiveX插件
接下来,打开xxx.pro工程文件,加入以下代码:
TEMPLATE = app
QT += axserver
VERSION = 1.1
如果是生成dll文件,就需要这样配置:
TEMPLATE = lib
QT += axserver
CONFIG += dll
DEF_FILE = PlayerPlugin.def #这个文件可以从VS里得到,VS建工程会自动生成
RC_FILE = playerplugin.rc
#VERSION = 2
然后声明ID: main.cpp可以不要,不需要main函数。
QAXFACTORY_DEFAULT(CPlayerPlugin,
"{A5071BCA-52E6-4685-9FBA-7554003FC42D}",
"{854705F4-D8DF-4768-8A02-407BD22DA47F}",
"{B80C8AF2-7BF7-4839-8AC8-3DAED7AE8A8D}",
"{1829EFE3-6E75-4B68-9287-A9D64F9115C7}",
"{5BC124D6-9FF9-438A-AD13-30426B91607E}")
接下来在,新建的类里加上Q_CLASSINFO()宏,为该类提供额外的一些信息。要想实现QT的COM或ActiveX,创建的每个想导出成COM的类必须都继承自QObject或QWidget或者它们的子类。继承自QObject及子类的为COM插件,继承自QWidget及子类的为ActiveX控件。
Q _CLASSINFO定义了COM组件的一些信息,这里面ClassID和InterfaceID是必须的,当需要使用COM中的事件时,EventsID就需要添加进来。
Q _CLASSINFO里面的128位的字符串只要保证唯一性即可,可以使用visual Studio的工具菜单中的GUID.exe工具生成。
#ifndef ACTIVE_TEST_H
#define ACTIVE_TEST_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Active_Test; }
QT_END_NAMESPACE
class Active_Test : public QWidget
{
Q_OBJECT
Q_CLASSINFO("ClassID", "{CB1DB4A6-D16D-4D20-AE0D-67F1DCF542C5}")
Q_CLASSINFO("InterfaceID", "{C03C4B03-B376-4B95-9349-3A2D547D5905}")
Q_CLASSINFO("EventsID", "{59A44941-3EF7-443E-AFA1-0B2F7129B7A4}")
public:
Active_Test(QWidget *parent = nullptr);
~Active_Test();
private:
Ui::Active_Test *ui;
};
#endif // ACTIVE_TEST_H
上面的步骤只是创建了可以导出的COM类,但要想让客户端能申请创建这个类对象,那这个类就必须让外部知道才能创建。而要想实现这个则必须要导出一个QAxFactory的实例出来,。该实例提供了向系统注册/销COM服务的方法,告知 COM系统,其导出了哪些类和类型可供它创建;最简单的实现方法就是在main.cpp中使用QAxFactory提供的宏构造。
因为当前生成的ActiveX插件是独立运行的exe文件,需要用到事件循环,还需要在main.cpp里加入以下代码。
#include "active_test.h"
#include <QApplication>
#include <QMessageBox>
#include <QApplication>
#include <QAxFactory>
QAXFACTORY_BEGIN(
"{41B3F63E-2E83-4BC5-A75B-9C08B5BF9BB7}", // type library ID
"{CEF1EDF1-1BEE-48B5-8C7F-43FE9FA42E0C}" // application ID
)QAXCLASS(Active_Test)
QAXFACTORY_END()
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if(QAxFactory::isServer())
{
Active_Test w;
w.show();
return a.exec();//离开了{}这个作用域w窗口就没了,可能看到的是一闪而过的画面
}
else
{
QMessageBox::information(nullptr,"提示","服务启动失败",QMessageBox::Ok,QMessageBox::Ok);
}
return a.exec();
}
ActiveX控件以exe形式发布可以不需要注册,在启动时加上-activex参数告诉它以提供COM服务的形式启动(默认是以可执行程序启动),那客户端就可以正常使用它提供的服务了。它也可以注册到系统中去,这样不用每次都加-activex启动。
为了方便测试,可以在QtCreate配置参数命令行里加上-activex
接下来,打开注册表就可以查看注册的ID:
六、发布应用程序并运行测试
程序编译成功之后,接下来进入到应用程序生成的目录下,为xxx.exe寻找依赖库。
D:\linux-share-dir\QT\build-activex_test-Desktop_Qt_5_12_6_MSVC2017_32bit-Release\release>cd /d D:\linux-share-dir\QT\build-activex_test-Desktop_Qt_5_12_6_MSVC2017_32bit-Release\release
D:\linux-share-dir\QT\build-activex_test-Desktop_Qt_5_12_6_MSVC2017_32bit-Release\release>windeployqt.exe activex_test.exe
打包完毕之后,在任意目录下新建一个xxx.html文件,写入测试代码,完成调用。
示例:
<html>
<head>
<title>Active_Test</title>
</head>
<body>
<object id="Active_Test" width="80%" height="80%"
classid="clsid:CB1DB4A6-D16D-4D20-AE0D-67F1DCF542C5">
</object>
</body>
</html>
其中的classid 要根据自己程序里的classid进行更改。
编写之后,鼠标选中文件,右键选择打开方式,选择IE浏览器打开。
到此,程序在浏览器里已经运行成功。