我实现了依据控件窗体移动扩展图形对象轴点的功能。 不过,我还未完成将这种图形对象作为一个整体进行移动的功能。 任何标准图形对象在移动其中心点时都可以整体移动。 类似地,这里我将制作一个管控图形对象的单一中心点,从而能够通过移动该点来移动整个图形对象(而非其轴点)。 为了执行测试,我选择了一个复合图形对象,该对象由一条趋势线组成,其末端带有价格标签对象。 考虑到这一点,整个工作将针对图形对象完成,而该图形对象有两个轴点用于重新定位其端点,单个中心点用于整体移动图形对象(两个点用于修改对象端点,一个中心点用于移动对象)。 稍后,我将为拥有三个以上控制点的图形对象创建含有相同控制点的窗体。
并非所有在此实现的东西都会像预期的那样工作。 但本文的目标是讲述为了获得必要结果,所进行的开发和创建代码的过程。 我相信,从规划功能到实现,几乎所有的过程都比阅读一篇枯燥的关于“最终一切如何如何”的演讲要生动有趣得多。
由于获取屏幕坐标的 ChartTimePriceToXY() 函数仅返回图表可视部分的坐标,因此我们无法计算图表界限之外点线的屏幕坐标。 如果我们请求位于可视图表左侧以外的屏幕时间像素中的 X 坐标,该函数始终返回 0。 由此,当沿屏幕移动复合图形对象时,若其左侧超出屏幕的左边框时,对象的左枢轴点将保持在图表像素坐标 0 处。 这将导致图形对象失真。 这同样适用于图形对象右侧和图表屏幕右侧(以及顶部和底部)部分。 因此,我将为复合图形对象引入一个限制,限制把图形对象移到图表的可视区域之外。 这样做是为了防止图形对象的任何边缘在移动时“撞到”屏幕边框产生变形。
改进库类
由于用来显示管理扩展图形对象轴点的管控点的对象窗体是函数库对象中的一个重要对象,但这些窗体未包含在图形对象集合当中,故此我们需要为此类窗体定义一种新类型。 所有基准函数库对象都有自己的函数库对象类型名称,据其我们就能定义当前处于活动状态的对象。 我们来为管理函数库扩展图形对象中管控点的窗体对象定义类型。
//+------------------------------------------------------------------+ //| List of library object types | //+------------------------------------------------------------------+ enum ENUM_OBJECT_DE_TYPE { //--- Graphics OBJECT_DE_TYPE_GBASE = COLLECTION_ID_LIST_END+1, // "Base object of all library graphical objects" object type OBJECT_DE_TYPE_GELEMENT, // "Graphical element" object type OBJECT_DE_TYPE_GFORM, // Form object type OBJECT_DE_TYPE_GFORM_CONTROL, // "Form for managing pivot points of graphical object" object type OBJECT_DE_TYPE_GSHADOW, // Shadow object type //--- Animation OBJECT_DE_TYPE_GFRAME, // "Single animation frame" object type OBJECT_DE_TYPE_GFRAME_TEXT, // "Single text animation frame" object type OBJECT_DE_TYPE_GFRAME_QUAD, // "Single rectangular animation frame" object type OBJECT_DE_TYPE_GFRAME_GEOMETRY, // "Single geometric animation frame" object type OBJECT_DE_TYPE_GANIMATIONS, // "Animations" object type //--- Managing graphical objects ... ... ... }