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

你可能感兴趣的:(C++)