为了定义复合图形对象,我引入了一种新型的图形元素 — 扩展标准图形对象。 参与创建复合图形对象的所有图形对象均应属于该类型。 至于目前,我尚未开发创建某些复合图形对象的类。 取而代之,我将实现允许创建预定义复合图形对象的功能,这自然不会排除通过编程和“动态”创建自定义复合图形对象的可能性 — 直接在图表上。
我将把自己的工作从功能方面划分成几个部分。 首先,我将创建必要的工具箱,用于管理和创建复合图形对象。 接下来,我将添加此类对象的预定义类(事实上,所有这些都取决于用户的个人需求,预定义复合图形对象类在这里仅用作示例)。 再接下来,我将开始实现该功能,令我们能够直观、手动、实时地在图表上直接创建复合图形对象。
实际上,在此,我还会把前一篇文章中实现的东西进行微调。 我将讲解如何为从属对象设置并接收定位点坐标。 此外,我还将测试移动带有从属对象的基准对象(在此阶段,我还需要以更复杂的形式移动复合对象坐标点的功能,而非简单地跟踪单一对象事件),以及创建移除复合图形对象的功能。
仅当松开鼠标按钮时,移动图形对象的坐标点才会触发 CHARTEVENT_OBJECT_DRAG 事件。 相应地,当我们仅跟踪此事件时,移动基准图形对象(且不释放鼠标按钮)会导致所有附加于它的对象保持不变。 释放按钮时事件出现,绑定的对象将移动到其基准对象的定位点。 这意味着我们应该跟踪按住鼠标按钮并移动鼠标。 此外,我们需要知道按钮是在基准图形对象上按下的,即在其坐标(或中心)定位点上。 我们还应该能够重新计算对象坐标点,及其从属对象定位点的位置 CHARTEVENT_OBJECT_DRAG 事件也应该在重新定位的最后进行处理,以便固定基准对象的最终坐标,并用它们重新计算绑定于其上的所有从属图形对象的坐标。
在本文中,我将实现处理 CHARTEVENT_OBJECT_DRAG 事件,并根据基准对象坐标的新位置重新计算其余绑定对象的坐标。 如果删除了基准对象,一个复合图形对象也会被删除。 如果发生此类事件,需删除绑定于其上的所有图形对象。 现在,我禁用鼠标选择所有图形对象(绑定到基准对象)的功能来简化操作。 因此,我们需要选择基准对象并将其删除,以便删除复合图形对象。 我们将无法再使用鼠标选择任何绑定对象。 这是防止复合图形对象被破坏的首选也是最简单的方式。 不过,可以打开对象列表(Ctrl+B),选择任何绑定对象的属性,并立即允许其可选择、或从图形对象列表窗口中删除。 稍后,我还将实现针对复合图形对象的有意破坏的处理。 当移除任何绑定到基准图形对象上的图形对象时,我们将移除参与构建复合图形对象的所有对象。 换言之,我将把整个复合对象构成时的任何对象都删除。 在后续的文章中,我还将讲解如何从基准对象里删除绑定的图形对象功能
改进库类
如往常一样,我们先实现新的函数库消息。 在 \MQL5\Include\DoEasy\Data.mqh 里,添加新消息的索引:
//--- CGraphElementsCollection MSG_GRAPH_OBJ_FAILED_GET_ADDED_OBJ_LIST, // Failed to get the list of newly added objects MSG_GRAPH_OBJ_FAILED_DETACH_OBJ_FROM_LIST, // Failed to remove a graphical object from the list MSG_GRAPH_OBJ_FAILED_DELETE_OBJ_FROM_LIST, // Failed to remove a graphical object from the list MSG_GRAPH_OBJ_FAILED_DELETE_OBJ_FROM_CHART, // Failed to remove a graphical object from the chart MSG_GRAPH_OBJ_FAILED_ADD_OBJ_TO_DEL_LIST, // Failed to set a graphical object to the list of removed objects MSG_GRAPH_OBJ_FAILED_ADD_OBJ_TO_RNM_LIST, // Failed to set a graphical object to the list of renamed objects
...
//--- CLinkedPivotPoint MSG_GRAPH_OBJ_EXT_NOT_ANY_PIVOTS_X, // Not a single pivot point is set for the object along the X axis MSG_GRAPH_OBJ_EXT_NOT_ANY_PIVOTS_Y, // Not a single pivot point is set for the object along the Y axis MSG_GRAPH_OBJ_EXT_NOT_ATACHED_TO_BASE, // The object is not attached to the basic graphical object MSG_GRAPH_OBJ_EXT_FAILED_CREATE_PP_DATA_OBJ, // Failed to create a data object for the X and Y pivot points MSG_GRAPH_OBJ_EXT_NUM_BASE_PP_TO_SET_X, // Number of base object pivot points for calculating the X coordinate: MSG_GRAPH_OBJ_EXT_NUM_BASE_PP_TO_SET_Y, // Number of base object pivot points for calculating the Y coordinate: }; //+------------------------------------------------------------------+
和与新添加的索引对应的文本消息:
//--- CGraphElementsCollection {"Не удалось получить список вновь добавленных объектов","Failed to get the list of newly added objects"}, {"Не удалось изъять графический объект из списка","Failed to detach graphic object from the list"}, {"Не удалось удалить графический объект из списка","Failed to delete graphic object from the list"}, {"Не удалось удалить графический объект с графика","Failed to delete graphic object from the chart"}, {"Не удалось поместить графический объект в список удалённых объектов","Failed to place graphic object in the list of deleted objects"}, {"Не удалось поместить графический объект в список переименованных объектов","Failed to place graphic object in the list of renamed objects"},
...
//--- CLinkedPivotPoint {"Для объекта не установлено ни одной опорной точки по оси X","The object does not have any pivot points set along the x-axis"}, {"Для объекта не установлено ни одной опорной точки по оси Y","The object does not have any pivot points set along the y-axis"}, {"Объект не привязан к базовому графическому объекту","The object is not attached to the base graphical object"}, {"Не удалось создать объект данных опорной точки X и Y.","Failed to create X and Y reference point data object"}, {"Количество опорных точек базового объекта для расчёта координаты X: ","Number of reference points of the base object to set the X coordinate: "}, {"Количество опорных точек базового объекта для расчёта координаты Y: ","Number of reference points of the base object to set the Y coordinate: "}, }; //+---------------------------------------------------------------------+