Qt下使用ActiveX控件

  最近需要用到esri 的ActiveX控件MapObjects.刚开始以为Qt不支持MapObjects,因为在网上查了好多Qt+MapObjects关键字搜索不到相关的资料。后来在Qt里面加了个QAxWidget,然后设置控件,发现列表里有MapObjects控件,所以Qt应该是支持MapObjects的(我的开发环境是vs2010+Qt4.8.4)。下面关于QAxWidget和MapObjects 进行简单的介绍:(参考:点击打开链接


1.QAxWidget的使用

在vs2010中新建一个Qt工程,命名为MOtest,在MOtest类的构造函数中添加如下代码:

MOtest::MOtest(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);
	QAxWidget *mmap = new QAxWidget(this ,0);
	this->resize(500, 500);
	mmap->resize(500, 500);
	mmap->setControl(QString::fromUtf8("{d27cdb6e-ae6d-11cf-96b8-444553540000}"));//flash的CLSID

	mmap->dynamicCall("LoadMovie(long,string)",0,"F:/test.swf");
    mmap->show();
}

运行程序会在一个窗口中播放flash文件 F:/test.swf


2.MapObjects在QAxWidget中使用

修改上面的构造函数,首先尝试添加一些简单的函数看看MapObjects控件能不能正常使用:

MOtest::MOtest(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);
	QAxWidget *mmap = new QAxWidget(this ,0);
	this->resize(500, 500);
	mmap->resize(500, 500);
	mmap->setControl(QString::fromUtf8("{9BD6A64B-CE75-11D1-AF04-204C4F4F5020}"));//MapObjects组件的CoClassID
	QVariantList params;//参数链表

	QColor color(85, 135, 206);
//	QString text("map objects test!"); 
	params.push_back(color);
//	params.push_back(text);
	params.push_back(1);
	mmap->dynamicCall("SetBackColor(QColor)", params.at(0));//设置Map控件的背景颜色
	mmap->dynamicCall("SetBorderStyle(int)", params.at(1));//设置Map控件的边框是否可见
}

在Qt里QAxWidget的使用基本就通过建立一个空的COM组件对象,然后在把需要封装的组件放到对象中。代码就是上面的new和setControl两个操作。解决了导入的问题,接下来就是如何使用该组件的接口和方法。COM是个自描述的结果,任何第三方软件都可以把这种描述化信息自动导出来。Qt中导出方法:

	QString doc=mmap->generateDocumentation();
	QFile outFile("F:/MapObjects.html");
	outFile.open(QIODevice::WriteOnly|QIODevice::Append);QTextStream ts(&outFile);
	ts<<doc<<endl;
得到的html文档里面包含有MapObjects在Qt下的一些接口和方法、属性。参考里面的帮助就可以调用函数了。

QVariantList params0;

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

params0<<QVariant(1);

params0<<QVariant("License");

params0<<QVariant("");

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


从上面代码可以看出,可以通过dynamicCall方法来调用ActiveX控件的方法。有些注意的地方:(参考:点击打开链接
1)dynamicCall()最多传递八个QVariant类型的参数,并且返回类型也是QVariant。

2)如果我们需要传递IDispatch *或者是IUnknown *,我们可以将这些组件封装成QAxObject,然后通过调用asVariant()方法来将这个COM对象转换为QVariant。同样如果我们返回一个IDispatch*或者IUnknown*的对象,就需要通过querySubObject方法将这个对象转换为QAxObject。

	QAxObject *session = outlook.querySubObject("Session");
3)如果不想这样做还可以QAxWidget还为我们提供了QueryInterface方法
	IWebBrowser2 *webBrowser = 0;
	activeX->queryInterface(IID_IWebBrowser2, (void *)&webBrowser);
	if (webBrowser) {
		webBrowser->Navigate2(pvarURL);
		webBrowser->Release();
	}
4)dynamicCall方法还可以设置COM控件的属性:
		activeX->dynamicCall("Value", 5);
		QString text = activeX->dynamicCall("Text").toString();
5)通过dynamicCall调用COM对象的方法的时候需要提供完成的函数签名。
		activeX->dynamicCall("Navigate(const QString&)", "qt.nokia.com");




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章