QT下使用MapX控件的問題以及Activex技術

  近期使用MapX控件做了一個GIS項目,因爲是在QT中使用,所以用dumpcpp生成了QT下可用的代碼,做了一些修改之後,代碼在QT中正常運行。

  後來客戶提出新的需要,要求顯示地圖經緯度,但是因爲地圖上圖元移動使用的單位是公里,所以之前把地圖的NumericCoord的單位設置爲了miUnitKilometer,而Mapx並不支持兩種座標系統同時使用。

  初期的思路如下:

  1.監聽鼠標移動事件,獲取到屏幕座標XY

  2.將屏幕座標XY轉換爲地圖座標,單位爲公里

  3.將公里轉換爲經緯度

  問題主要出現在第二步,調用MapX的ConvertCoord時,提示Type MisMatch,函數原型爲

  void ConvertCoord(double& ScreenX, double& ScreenY, double& MapX, double& MapY, int Direction);

  參數給的也是正確的,使用DynamicCall之後仍然出現同樣的錯誤。無奈之下,參照QT的源碼,直接使用queryInterface獲取IDispatch接口,用IDispatch的Invoke接口調用,仍然提示Type Mismatch錯誤。

  後來查看了下VC的Mapx的cpp文件,發現裏面代碼如下:

  

void CMapX::ConvertCoord(float* ScreenX, float* ScreenY, double* MapX, double* MapY, short Direction)
{
	static BYTE parms[] =
		VTS_PR4 VTS_PR4 VTS_PR8 VTS_PR8 VTS_I2;
	InvokeHelper(0x22, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
		ScreenX, ScreenY, MapX, MapY, Direction);
}
   使用的是InvokeHelper函數,再查一下,發現COleDispatchDriver有InvokeHelper成員,引入了MFC庫後,COleDiapatcherDriver綁定IDispatch接口,調用InvokeHelper後,調用成功,終於解決了activex控件在QT中的最麻煩的問題,我看stackoverflow上也有很多類似的問題,大多是採用dynamicCall+QVariantList的調用方式,但是那種方式並沒有解決我的問題。

   QT實現的Activex兼容技術還是有缺陷的,適當的時候還是需要引入原生的COM來進行activex控件方法的調用,不能超出了QT平臺之外,就束手無策了。

   最後貼上代碼:

   

IDispatch* map_itf = NULL;
map_ctrl_->queryInterface(IID_IDispatch,(void**)&map_itf);

if(map_itf)
{
    COleDispatchDriver driver(map_itf,FALSE);

    static BYTE parms[] =
        VTS_PR4 VTS_PR4 VTS_PR8 VTS_PR8 VTS_I2;

    driver.InvokeHelper(0x22, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
        &screen_x, &screen_y, &map_x, &map_y, miScreenToMap);
}

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