You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ActiveX实现从Qt迁移到wxWidgets并获取接口文档

问题:从Qt QAxWidget迁移至wxWidgets wxActiveXContainer连接ActiveX并获取接口文档

原本使用Qt的QAxWidget访问ActiveX控件,现需迁移至wxWidgets的wxActiveXContainer,但在VS2019 C++环境中参考示例后仍无法成功连接。核心需求是:用wxWidgets连接任意ActiveX并获取其接口文档。

Qt实现代码

#include "sc_samlight_client_ctrl_type_lib.h"
QAxWidget actX(this);
actX.setVisible(false);
actX.setControl(QUuid(__uuidof(ScSamlightClientCtrl)).toString());

QString str = actX.generateDocumentation();

wxWidgets尝试代码

#include <wx/wx.h>
#include "wx/msw/ole/activex.h"
#include "wx/msw/ole/automtn.h" 
#include "sc_samlight_client_ctrl_type_lib.h"

wxWindow* parent; // from caller...

// 似乎能连接到对象...
wxAutomationObject ao;
ao.CreateInstance(wxS("SCAPS.ScSamlightClientCtrl"));

// 这里无法工作...不知道第三个参数传什么,甚至不确定第二个参数是否正确...
wxActiveXContainer* m_pAX;
m_pAX = new wxActiveXContainer(parent, __uuidof(ScSamlightClientCtrl), NULL);

注:sc_samlight_client_ctrl_type_lib.h为待控制设备/程序提供的接口文件。


解决方案

1. 无界面自动化场景(对应Qt隐藏控件的需求)

如果不需要显示ActiveX控件,仅需调用其接口,使用wxAutomationObject即可,无需wxActiveXContainer。wx没有直接对应QtgenerateDocumentation()的方法,需通过OLE原生接口提取文档信息:

#include <wx/wx.h>
#include "wx/msw/ole/automtn.h"
#include "sc_samlight_client_ctrl_type_lib.h"
#include <oleauto.h>

void GetActiveXDocumentation(wxWindow* parent)
{
    wxAutomationObject ao;
    // 两种创建方式:用ProgID字符串,或直接传CLSID
    bool created = ao.CreateInstance(wxS("SCAPS.ScSamlightClientCtrl"));
    // 或者用CLSID:created = ao.CreateInstance(__uuidof(ScSamlightClientCtrl));

    if (!created)
    {
        wxMessageBox(wxT("创建ActiveX实例失败"));
        return;
    }

    IDispatch* disp = ao.GetDispatch();
    if (!disp)
    {
        wxMessageBox(wxT("获取Dispatch接口失败"));
        return;
    }

    ITypeInfo* typeInfo = nullptr;
    HRESULT hr = disp->GetTypeInfo(0, LOCALE_USER_DEFAULT, &typeInfo);
    if (FAILED(hr) || !typeInfo)
    {
        wxMessageBox(wxT("获取类型信息失败"));
        disp->Release();
        return;
    }

    // 提取类型文档
    BSTR docBstr = nullptr;
    hr = typeInfo->GetDocumentation(MEMBERID_NIL, nullptr, &docBstr, nullptr, nullptr);
    if (SUCCEEDED(hr) && docBstr)
    {
        wxString docStr(docBstr, wxConvUTF16);
        // 这里可以处理文档内容,比如输出到日志或弹窗
        wxMessageBox(docStr, wxT("ActiveX接口文档"));
        SysFreeString(docBstr);
    }

    // 释放资源
    typeInfo->Release();
    disp->Release();
}

2. 可视化ActiveX容器场景

如果需要显示ActiveX控件,正确初始化wxActiveXContainer的方式如下:

#include <wx/wx.h>
#include "wx/msw/ole/activex.h"
#include "wx/msw/ole/automtn.h" 
#include "sc_samlight_client_ctrl_type_lib.h"

void CreateActiveXContainer(wxWindow* parent)
{
    // 构造函数参数:父窗口、控件ID、ProgID/CLSID、位置、大小、样式
    // 推荐用ProgID字符串,比直接传CLSID更直观
    wxActiveXContainer* axContainer = new wxActiveXContainer(
        parent, 
        wxID_ANY, 
        wxS("SCAPS.ScSamlightClientCtrl"), 
        wxDefaultPosition, 
        wxDefaultSize, 
        wxTAB_TRAVERSAL
    );

    // 检查控件是否创建成功
    if (!axContainer->CreateControl())
    {
        wxMessageBox(wxT("创建ActiveX容器失败"));
        delete axContainer;
        return;
    }

    // 若需调用自动化接口,从容器中获取Dispatch对象
    wxAutomationObject ao;
    ao.AttachDispatch(axContainer->GetDispatch());

    // 后续提取文档的代码和无界面场景一致
    IDispatch* disp = ao.GetDispatch();
    // ...(省略提取文档的重复代码)
}

关键说明

  • wxAutomationObject对应Qt QAxWidget的无界面自动化场景,无需创建可视化容器
  • wxActiveXContainer用于需要显示ActiveX控件的场景,构造时第三个参数可直接传入ProgID字符串(如wxS("SCAPS.ScSamlightClientCtrl")),无需手动处理CLSID的转换
  • wxWidgets没有封装类似QtgenerateDocumentation()的方法,需通过OLE的ITypeInfo接口手动遍历提取接口文档,这部分逻辑和Qt内部实现原理一致

内容的提问来源于stack exchange,提问作者MHelene Lavoie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:11:00