千家信息网

如何开发COM应用程序

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这期内容当中小编将会给大家带来有关如何开发COM应用程序,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Qt(发音为" cute",而不是" cu-tee")是一个跨
千家信息网最后更新 2026年11月02日如何开发COM应用程序

这期内容当中小编将会给大家带来有关如何开发COM应用程序,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

Qt(发音为" cute",而不是" cu-tee")是一个跨平台框架,通常用作图形工具包,它不仅创建CLI应用程序中也非常有用。而且它也可以在三种主要的台式机操作系统以及移动操作系统(如Symbian,Nokia Belle,Meego Harmattan,MeeGo或BB10)以及嵌入式设备,Android(Necessitas)和iOS的端口上运行。

COM应用程序示例显示了如何使用ActiveQt开发可通过COM自动化的Qt应用程序。不同的基于QObject的类作为与运行Qt应用程序的GUI通信的COM对象公开。这些COM对象的API的设计类似于标准COM应用程序的API。比如Microsoft Office。

class Application : public QObject{    Q_OBJECT    Q_CLASSINFO("ClassID", "{b50a71db-c4a7-4551-8d14-49983566afee}")    Q_CLASSINFO("InterfaceID", "{4a427759-16ef-4ed8-be79-59ffe5789042}")    Q_CLASSINFO("RegisterObject", "yes")    Q_PROPERTY(DocumentList* documents READ documents)    Q_PROPERTY(QString id READ id)    Q_PROPERTY(bool visible READ isVisible WRITE setVisible)public:    explicit Application(QObject *parent = nullptr);    DocumentList *documents() const;    QString id() const { return objectName(); }    void setVisible(bool on);    bool isVisible() const;    QTabWidget *window() const { return m_ui.data(); }public slots:    void quit();private:    QScopedPointer  m_docs;    QScopedPointer  m_ui;};

第一类Application代表应用程序对象。它公开了只读属性documents、id去访问文档列表和标识符。读/写属性visible控制应用程序基于QTabWidget的用户界面是否应可见,并且插槽quit()终止该应用程序。

RegisterObject属性设置以确保该类的实例在COM的运行对象表(ROT)注册-这使得COM客户端连接到已经实例化的COM对象。

class DocumentList : public QObject{    Q_OBJECT    Q_CLASSINFO("ClassID", "{496b761d-924b-4554-a18a-8f3704d2a9a6}")    Q_CLASSINFO("InterfaceID", "{6c9e30e8-3ff6-4e6a-9edc-d219d074a148}")    Q_PROPERTY(Application* application READ application)    Q_PROPERTY(int count READ count)public:    explicit DocumentList(Application *application);    int count() const;    Application *application() const;public slots:    Document *addDocument();    Document *item(int index) const;private:    QVector m_list;};

该DocumentList级存储的文件清单。它提供了一个API,可以读取文档数量,按索引访问每个文档并创建一个新文档。该application属性返回根对象。

class Document : public QObject{    Q_OBJECT    Q_CLASSINFO("ClassID", "{2b5775cd-72c2-43da-bc3b-b0e8d1e1c4f7}")    Q_CLASSINFO("InterfaceID", "{2ce1761e-07a3-415c-bd11-0eab2c7283de}")    Q_PROPERTY(Application *application READ application)    Q_PROPERTY(QString title READ title WRITE setTitle)public:    explicit Document(DocumentList *list);    virtual ~Document();    Application *application() const;    QString title() const;    void setTitle(const QString &title);private:    QScopedPointer  m_page;};

该Document类最后表示应用程序中的文件。每个文档均由应用程序选项卡小部件中的页面表示,并可通过文档API读取和写入的标题。该application属性再次返回根对象。

Document::Document(DocumentList *list): QObject(list){    QTabWidget *tabs = list->application()->window();    m_page.reset(new QWidget(tabs));    m_page->setWindowTitle(tr("Unnamed"));    tabs->addTab(m_page.data(), m_page->windowTitle());    m_page->show();}Document::~Document() = default;Application *Document::application() const{    return qobject_cast(parent())->application();}QString Document::title() const{    return m_page->windowTitle();}void Document::setTitle(const QString &t){    m_page->setWindowTitle(t);    QTabWidget *tabs = application()->window();    int index = tabs->indexOf(m_page.data());    tabs->setTabText(index, m_page->windowTitle());}

Document该类的实现为选项卡小部件创建一个新页面,并将该页面的标题用作title属性。删除文档后,页面即被删除。

DocumentList::DocumentList(Application *application): QObject(application){}Application *DocumentList::application() const{    return qobject_cast(parent());}int DocumentList::count() const{    return m_list.count();}Document *DocumentList::item(int index) const{    return m_list.value(index, nullptr);}Document *DocumentList::addDocument(){    Document *document = new Document(this);    m_list.append(document);    return document;}

DocumentList可直接实现。

Application::Application(QObject *parent): QObject(parent),  m_ui(new QTabWidget),  m_docs(new DocumentList(this)){    setObjectName(QStringLiteral("From QAxFactory"));}DocumentList *Application::documents() const{    return m_docs.data();}void Application::setVisible(bool on){    m_ui->setVisible(on);}bool Application::isVisible() const{    return m_ui->isVisible();}void Application::quit(){    m_docs.reset();    m_ui.reset();    QTimer::singleShot(0 /*ms*/, qApp, &QCoreApplication::quit);}#include "main.moc"

在Application类初始化构造函数中的用户界面,可通过setVisible()实现显示和隐藏它,其对象名称(可通过id属性访问)设置为" "From QAxFactory ",以指示此COM对象已由COM创建。请注意没有析构函数可删除QTabWidget而是在调用quit()前就完成通过单发计时器来确保对插槽的COM调用。

QAXFACTORY_BEGIN("{edd3e836-f537-4c6f-be7d-6014c155cc7a}", "{b7da3de8-83bb-4bbe-9ab7-99a05819e201}")   QAXCLASS(Application)   QAXTYPE(Document)   QAXTYPE(DocumentList)QAXFACTORY_END()

使用QAxFactory宏从服务器导出类。只能从Application外部实例化对象-其他API只能在访问整个ApplicationAPI中的相应对象后才能使用。

int main(int argc, char *argv[]){    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);    QApplication app(argc, argv);    app.setQuitOnLastWindowClosed(false);    // started by COM - don't do anything    if (QAxFactory::isServer())        return app.exec();    // started by user    Application appobject;    appobject.setObjectName(QStringLiteral("From Application"));    QAxFactory::startServer();    QAxFactory::registerActiveObject(&appobject);    appobject.window()->setMinimumSize(300, 100);    appobject.setVisible(true);    QObject::connect(&app, &QGuiApplication::lastWindowClosed, &appobject, &Application::quit);    return app.exec();}

使用main()入口点函数创建一个QApplication,如果应用程序已由COM启动,则仅进入事件循环。如果应用程序已由用户启动,则将Application创建对象并将对象名称设置为"From Application"。然后启动COM服务器,并向COM注册应用程序对象。现在,COM客户端可以通过特定于客户端的API访问它。

应用程序的退出受到显式控制-如果COM启动了应用程序,则客户端代码必须调用quit(); 如果用户启动了该应用程序,则该应用程序将在关闭最后一个窗口时终止。

最后,使用户界面可见,并启动事件循环。

一个简单的Visual Basic应用程序现在可以访问此Qt应用程序。在VB中,启动一个新的" Standard Exe"项目,并将项目引用添加到comappLib类型库。创建一个带有列表框" DocumentList",静态标签" DocumentsCount"和命令按钮" NewDocument"的表单。最后,实现如下形式的代码:

Private Application As comappLib.ApplicationPrivate MyApp As BooleanPrivate Sub UpdateList()    DocumentList.Clear    DocumentsCount.Caption = Application.documents.Count    For Index = 0 To Application.documents.Count - 1       DocumentList.AddItem (Application.documents.Item(Index).Title)    NextEnd SubPrivate Sub Form_Load()    On Error GoTo CreateNew    Set Application = GetObject(, "comapp.Application")    MyApp = False    GoTo InitializedCreateNew:    On Error GoTo InitializeFailed    Set Application = New Application    Application.Visible = True    MyApp = TrueInitialized:    Caption = Application.id    UpdateListInitializeFailed:End SubPrivate Sub Form_Unload(Cancel As Integer)    If MyApp Then        Application.quit    End IfEnd SubPrivate Sub NewDocument_Click()    Application.documents.addDocument    UpdateListEnd Sub

要构建示例,您必须首先构建QAxServer库。然后运行qmake,将您的制作工具放入examples\activeqt\comapp。

上述就是小编为大家分享的如何开发COM应用程序了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

应用程序 程序 应用 对象 属性 文档 用户 客户 页面 可通 运行 开发 函数 实例 客户端 用户界面 界面 并将 操作系统 事件 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百单网互联网科技有限公司怎么样 互联网科技公司经营范围 互联网金融监管科技数据 厦门中拓互联网络科技有限公司 互联网与科技发展 易互联网科技有限公司 高科技与互联网 伴你行互联网科技有限公司 亿人帮互联网科技 互联网科技创新企业排名 西藏七维空间互联网科技有限公司 广州优美互联网科技 中国互联网有什么科技含量 呼和浩特新华互联网科技学院 电子科技大学互联网创业大赛 爱医互联网络科技 云南省自由互联网科技有限公司 互联网科技手机排行榜 互联网科技品牌 保山浩联互联网科技有限公司 互联网 科技公司 奇酷互联网络科技 奔汉互联网科技 农村开互联网科技讲堂 互联网系的金融科技公司 荆州市昕露互联网络科技有限公司 赶超互联网科技 微信多开 知域互联网科技有限公司大骗子 版纳互联网科技选哪家 杭州科技互联网公司有哪些
0