c# 开发 ActiveX 的过程参考我的另一篇文章 : https://www.cnblogs.com/baqifanye/p/10414004.html
本篇讲如何 在C# 开发的ActiveX 过程中添加事件,并在QT中调用
1.添加一个新的名为 ControlEvents 的接口文件,也可以不添加,,直接添加到主文件中也可,,等下会说明
ControlEvents.cs 文件:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace gMapActiveX
{
[Guid("AA5830BB-7B00-48C1-88F5-38D1206562AF")]//可自己在vs的guid工具中去生成,只要别和主文件guid相同就可
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ControlEvents
{
[DispId(0x00000001)]
void OnEventLatLng(double lat, double lng);//这就是dispid事件,,必须要有,,如果没有在QT中将无法调用
// [DispIdAttribute(0x002)]
// void OnRecordStopped();
// [DispIdAttribute(0x003)]
//void OnRecordVolumeChanged(int value);
}
}
主文件:
namespace gMapActiveX { [Guid("378786D4-D4C4-4F08-90CC-C94FCEDA423A")]//主要的guid,,会注册到注册表,,系统会靠它去识别activex控件 [ComVisible(true)]//这个好像可以不要,,在AssemblyInfo.cs 已有设置 [SecuritySafeCritical] [ComSourceInterfaces(typeof(ControlEvents))] //定义com 事件源的接口 ///ControlEvents 就是我们的事件类 public partial class UserControl1: UserControl, IObjectSafety { public delegate void EventLatLng(double lat, double lng); public event EventLatLng OnEventLatLng; public UserControl1() { InitializeComponent(); } private void GMapControl_MouseClick(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { PointLatLng point = this.gMapControl.FromLocalToLatLng(e.X, e.Y); OnEventLatLng(point.Lat, point.Lng);//触发事件 } } } }
下面说如何在QT中调用事件:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QAxWidget> #include <QTime> #include <QTimer> #include <QThread> #include <QDebug> #include <QColor> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void slotLatLng(double lat, double lng); void slot(const QString &name, int argc, void *argv); private: Ui::MainWindow *ui; QAxWidget * axWidget; }; #endif // MAINWINDOW_H
#include "MainWindow.h" #include "ui_MainWindow.h" #include <QFile> #if _MSC_VER >= 1600 #pragma execution_character_set("utf-8") #endif MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this);
axWidget = new QAxWidget(this); axWidget->setControl(QString::fromUtf8("{378786D4-D4C4-4F08-90CC-C94FCEDA423A}")); axWidget->resize(620,720); axWidget->show();; //QT官方提供了两种事件查看方式,都是用connect,但前者是任何事件信号都会触发,可根据信号名去对应所需要的事件 //后都是把事件当信号使用,非常简单 QObject::connect(axWidget, SIGNAL(signal(QString, int, void*)), this, SLOT(slot(QString, int, void*))); QObject::connect(axWidget,SIGNAL(OnEventLatLng(double,double)),this,SLOT(slotLatLng(double,double))); } void MainWindow::slotLatLng(double lat, double lng) { ui->textEdit->append(QString::number(lat,'f',10) + "<<" + QString::number(lng,'f',10)); qDebug() <<"Lat:" << QString::number(lat,'f',8) << "Lng" << lng; } void MainWindow::slot(const QString &name, int argc, void *argv) { qDebug() << name << ",,," << argc; //可以看到的值的输出,说明signal信号也被触发,具体可以查看手册 qDebug() << argv; //以下被注释的是qt官方的代码,,具体可以查看手册:QAxBase Class // VARIANTARG *params = (VARIANTARG*)argv; // if (name.startsWith("BeforeNavigate2(")) { // IDispatch *pDisp = params[argc-1].pdispVal; // VARIANTARG URL = *params[argc-2].pvarVal; // VARIANTARG Flags = *params[argc-3].pvarVal; // VARIANTARG TargetFrameName = *params[argc-4].pvarVal; // VARIANTARG PostData = *params[argc-5].pvarVal; // VARIANTARG Headers = *params[argc-6].pvarVal; // bool *Cancel = params[argc-7].pboolVal; // } }