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");




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