思考点线面的绘制过程:
1. 考虑ITool与控件AxMapControl的参数传递,这里HookHelper的Hook属性用AxMapControl.Object赋值。AxMapControl(.Net对象)对MapControl(COM对象)进行了封装。
2. 明显所有的绘制都涉及控件这几个事件Mouse_Down、Mouse_Move、Mouse_Up、DoubleClick;事件是控件的,IMapControlEvents2中几个事件的定义:
而Itool中只有如下三个重载的方法,注意参数不一样。
public virtual void OnMouseDown(int Button, int Shift, int X, int Y);
public virtual void OnMouseDown(int Button, int Shift, int X, int Y);
public virtual void OnMouseUp(int Button, int Shift, int X, int Y);
所以必然有一个机制实现了绘制事件的多态。
根据蒋波涛的插件框架,我似乎理解了这种机制。实际是在UI层控件的Mouse_Down、Mouse_Move、Mouse_Up事件方法中调用虚基类BaseTool(ITool)的方法,进一步,调用的是CurrentTool的重载方法。UI层控件-〉基类BaseTool-〉CurrentTool顺次调用。
这样就解释了直接给UI层控件添加Mouse_Down、Mouse_Move、Mouse_Up自定义事件响应函数时候会和现有的ITool中的方法产生冲突,因为是将Tool的重载方法和自定义的事件响应函数同时添加到了事件的链上,因而顺次执行了。
这种思路实现了UI界面和绘制图形交互动作的分离,是通过ICommand这个中间对象实现的,从UI界面中抽象出全新的一层,通过OnClick方法和UI界面控件的事件绑定。
IDisplayFeedBack对象实现了绘制逻辑和交互动作的分离。IDisplayFeedBack具有缓存绘制的几何对象的功能,很奇妙。
绘制图形有两种关联鼠标事件的方式:
一种如ArcGIS的彻底抽象,UI(鼠标键盘事件是界面的)和ITool(抽象鼠标键盘事件)分离,绘制流程用IDisplayFeedBack抽象。
另一种将绘制的将鼠标键盘事件与图形放在一起,即抽象出一个图形类如点、线、面,这种方式估计国内很多的绘图软件都是如此吧。比如抽象一个Draw基类,有鼠标事件。
在三维球中,由于屏幕绘制是按照帧率来显示的,或者说何时屏幕绘制不受控制。居然会这样:在绘制过程中使用临时渲染对象,最后鼠标双击结束时再删除临时渲染对象,再构造一个新的渲染对象。更试图用一个控制类囊括所有的绘制操作。这可能真的很保密啊!