English Русский Español Deutsch 日本語 Português
DoEasy 函数库中的图形(第八十三部分):抽象标准图形对象类

DoEasy 函数库中的图形(第八十三部分):抽象标准图形对象类

MetaTrader 5示例 | 1 十一月 2021, 08:45
1 178 0
Artyom Trishkin
Artyom Trishkin

内容


概述

为了进一步完善我在上一篇实现的图形对象集合类,我需要终端中存在的所有标准图形的对象类。 一旦创建了所有这些对象之后,我就拥有了处理基于 CCanvas 类的任何图形对象(标准和自定义对象)的工具。 它们都将位于图形对象的集合列表中。

由于该函数库能够管理手工创建的图形对象,我将需要能够处理手工创建标准图形的对象类。 这种对象将与手工创建的图形对象绑定,且拥有相应方法管理其属性。 为了管理这类图形对象,函数库用户应该手工指定实施这种管理的必要性。

举例来说,这可以通过在特定条件下调用关联菜单来完成。 这意味着我们需要一个图形面板,能够为图形对象选择可用的操作。 这样的面板可借助基于 CCanvas 的类和它们的对象来创建,我在之前的几篇文章里就开始创建它们。 我打算在图形对象集合类和相应的标准图形对象类创建完毕后立即返回它们。

所有其余的标准图形对象结构与所有函数库对象的结构相同。 有一个通用的抽象图形对象类,拥有所有图形对象固有的基本属性。 描述每个单独标准图形对象的类也是从它继承而来的。 这些类用于指定对象属性。

在此,我将创建抽象图形对象类,并添加处理所有图形对象固有属性的方法 — 这些都是可以调用 ObjectGetInteger()ObjectGetDouble()ObjectGetString() 函数来获取的图形对象属性。 当创建继承自抽象图形对象的衍生后代对象类时,仅需在衍生后代对象中继承描述某个图形对象的方法,但在基准对象中实现的方法应从基准对象移到衍生后代对象,如此这般,没有这些属性的对象就无法访问相应方法。
为了更清晰,我们来研究以下示例:

  • 终端提供了箭头图形图标对象。 该对象具有箭头代码属性,但没有向右射线;
  • 终端提供了趋势线图形对象。 该对象具有向右射线属性,但没有箭头代码。

我将在抽象图形对象类中指定这些属性和处理方法。 这些方法可供任意继承自基准对象的对象使用 — 抽象图形对象。
接下来,我将创建衍生后代对象。 在这种情况下,它们是箭头图标对象和趋势线图形对象。 它们中的每一个都会收到仅处理自身固有属性的方法:

  • 指定箭头代码的方法被移至箭头图标对象;
  • 指定向右射线 (向左射线) 属性的方法被移至趋势线图形对象。

当引用这些衍生后代对象中的任一个时,我们只能访问其固有属性,及仅在这些对象中设置的相应处理方法、还有继承自所有图形对象中处理公用属性的方法、和设置在抽象图形对象类中的方法。

图形对象拥有多种属性。 因此,在实际创建抽象图形对象类之前,我还需要做很多的准备工作。 这项工作包括在函数库枚举中设置属性、为每个图形对象属性编写定义、以及创建返回某些图形对象属性定义的函数。


改进库类

我在上一篇文章中创建的函数库对象类型列表含有标准图形对象类型。 不过,我们还需要另一种类型的抽象图形对象。 在 \MQL5\Include\DoEasy\Defines.mqh 中的函数库对象类型枚举中添加常量。 后续对象类型常量的计算是从新的常量值开始:

//+------------------------------------------------------------------+
//| 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_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
   OBJECT_DE_TYPE_GELEMENT_CONTROL,                               // "Managing graphical objects" object type
//--- Standard graphical objects
   OBJECT_DE_TYPE_GSTD_OBJ,                                       // "Standard graphical object" object type
   OBJECT_DE_TYPE_GSTD_VLINE              =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_VLINE,            // "Vertical line" object type
   OBJECT_DE_TYPE_GSTD_HLINE              =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_HLINE,            // "Horizontal line" object type
   OBJECT_DE_TYPE_GSTD_TREND              =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_TREND,            // "Trend line" object type
   OBJECT_DE_TYPE_GSTD_TRENDBYANGLE       =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_TRENDBYANGLE,     // "Trend line by angle" object type
   OBJECT_DE_TYPE_GSTD_CYCLES             =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_CYCLES,           // "Cyclic lines" object type
   OBJECT_DE_TYPE_GSTD_ARROWED_LINE       =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROWED_LINE,     // "Arrowed line" object type
   OBJECT_DE_TYPE_GSTD_CHANNEL            =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_CHANNEL,          // "Equidistant channel" object type
   OBJECT_DE_TYPE_GSTD_STDDEVCHANNEL      =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_STDDEVCHANNEL,    // "Standard deviation channel" object type
   OBJECT_DE_TYPE_GSTD_REGRESSION         =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_REGRESSION,       // "Linear regression channel" object type
   OBJECT_DE_TYPE_GSTD_PITCHFORK          =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_PITCHFORK,        // "Andrews' pitchfork" object type
   OBJECT_DE_TYPE_GSTD_GANNLINE           =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_GANNLINE,         // "Gann line" object type
   OBJECT_DE_TYPE_GSTD_GANNFAN            =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_GANNFAN,          // "Gann fan" object type
   OBJECT_DE_TYPE_GSTD_GANNGRID           =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_GANNGRID,         // "Gann grid" object type
   OBJECT_DE_TYPE_GSTD_FIBO               =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_FIBO,             // "Fibo levels" object type
   OBJECT_DE_TYPE_GSTD_FIBOTIMES          =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_FIBOTIMES,        // "Fibo time zones" object type
   OBJECT_DE_TYPE_GSTD_FIBOFAN            =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_FIBOFAN,          // "Fibo fan" object type
   OBJECT_DE_TYPE_GSTD_FIBOARC            =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_FIBOARC,          // "Fibo arcs" object type
   OBJECT_DE_TYPE_GSTD_FIBOCHANNEL        =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_FIBOCHANNEL,      // "Fibo channel" object type
   OBJECT_DE_TYPE_GSTD_EXPANSION          =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_EXPANSION,        // "Fibo expansion" object type
   OBJECT_DE_TYPE_GSTD_ELLIOTWAVE5        =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ELLIOTWAVE5,      // "Elliott 5 waves" object type
   OBJECT_DE_TYPE_GSTD_ELLIOTWAVE3        =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ELLIOTWAVE3,      // "Elliott 3 waves" object type
   OBJECT_DE_TYPE_GSTD_RECTANGLE          =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_RECTANGLE,        // "Rectangle" object type
   OBJECT_DE_TYPE_GSTD_TRIANGLE           =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_TRIANGLE,         // "Triangle" object type
   OBJECT_DE_TYPE_GSTD_ELLIPSE            =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ELLIPSE,          // "Ellipse" object type
   OBJECT_DE_TYPE_GSTD_ARROW_THUMB_UP     =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_THUMB_UP,   // "Thumb up" object type
   OBJECT_DE_TYPE_GSTD_ARROW_THUMB_DOWN   =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_THUMB_DOWN, // "Thumb down" object type
   OBJECT_DE_TYPE_GSTD_ARROW_UP           =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_UP,         // "Arrow up" object type
   OBJECT_DE_TYPE_GSTD_ARROW_DOWN         =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_DOWN,       // "Arrow down" object type
   OBJECT_DE_TYPE_GSTD_ARROW_STOP         =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_STOP,       // "Stop sign" object type
   OBJECT_DE_TYPE_GSTD_ARROW_CHECK        =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_CHECK,      // "Check mark" object type
   OBJECT_DE_TYPE_GSTD_ARROW_LEFT_PRICE   =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_LEFT_PRICE, // "Left price label" object type
   OBJECT_DE_TYPE_GSTD_ARROW_RIGHT_PRICE  =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_RIGHT_PRICE,// "Right price label" object type
   OBJECT_DE_TYPE_GSTD_ARROW_BUY          =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_BUY,        // "Buy sign" object type
   OBJECT_DE_TYPE_GSTD_ARROW_SELL         =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW_SELL,       // "Sell sign" object type
   OBJECT_DE_TYPE_GSTD_ARROW              =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_ARROW,            // "Arrow" object type
   OBJECT_DE_TYPE_GSTD_TEXT               =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_TEXT,             // "Text" object type
   OBJECT_DE_TYPE_GSTD_LABEL              =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_LABEL,            // "Text label" object type
   OBJECT_DE_TYPE_GSTD_BUTTON             =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_BUTTON,           // "Button" object type
   OBJECT_DE_TYPE_GSTD_CHART              =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_CHART,            // "Chart" object type
   OBJECT_DE_TYPE_GSTD_BITMAP             =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_BITMAP,           // "Bitmap" object type
   OBJECT_DE_TYPE_GSTD_BITMAP_LABEL       =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_BITMAP_LABEL,     // "Bitmap label" object type
   OBJECT_DE_TYPE_GSTD_EDIT               =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_EDIT,             // "Input field" object type
   OBJECT_DE_TYPE_GSTD_EVENT              =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_EVENT,            // "Event object which corresponds to an event in Economic Calendar" object type
   OBJECT_DE_TYPE_GSTD_RECTANGLE_LABEL    =  OBJECT_DE_TYPE_GSTD_OBJ+1+OBJ_RECTANGLE_LABEL,  // "Rectangle Label object used to create and design the custom graphical interface" object type
   
//--- Objects
   OBJECT_DE_TYPE_BASE  =  OBJECT_DE_TYPE_GSTD_RECTANGLE_LABEL+1, // Base object for all library objects
   OBJECT_DE_TYPE_BASE_EXT,                                       // Extended base object for all library objects
   
   // .......... The constants of other object types are skipped for brevity
   // ..........
   // ..........

  };

在枚举图形对象所属列表中,更改命名表示图形对象属于终端的 GRAPH_OBJ_BELONG_TERMINAL 常量。 我们让它更合适:GRAPH_OBJ_BELONG_NO_PROGRAM,因为对象也许不属于函数库控制的程序,但它也许属于另一个程序而不是终端:

//+------------------------------------------------------------------+
//| List of graphical objects affiliations                           |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_OBJ_BELONG
  {
   GRAPH_OBJ_BELONG_PROGRAM,                          // Graphical object belongs to a program
   GRAPH_OBJ_BELONG_NO_PROGRAM,                       // Graphical object does not belong to a program
  };
//+------------------------------------------------------------------+

在图形元素类型的枚举中添加一个新的常量

//+------------------------------------------------------------------+
//| The list of graphical element types                              |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_ELEMENT_TYPE
  {
   GRAPH_ELEMENT_TYPE_STANDART,                       // Standard graphical object
   GRAPH_ELEMENT_TYPE_ELEMENT,                        // Element
   GRAPH_ELEMENT_TYPE_SHADOW_OBJ,                     // Shadow object
   GRAPH_ELEMENT_TYPE_FORM,                           // Form
   GRAPH_ELEMENT_TYPE_WINDOW,                         // Window
  };
//+------------------------------------------------------------------+

鉴于在程序中创建的所有描述图形对象的对象都被存储在单列表中,因此指定图形元素类型允许我们从整个列表中快速选取所需的图形元素。 相应地,如果我们选择“标准图形对象”作为集合列表的过滤条件,我们得到的列表只包含描述所创建标准图形对象的对象。

对于抽象标准图形对象类的对象,我们需要为所有图形对象属性创建三个枚举 — 整数型实数型字符型,包含所有图形对象属性,以及处理此类对象所需的附加属性:

//+------------------------------------------------------------------+
//| Integer properties of a standard graphical object                |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_OBJ_PROP_INTEGER
  {
   //--- Additional properties
   GRAPH_OBJ_PROP_ID = 0,                             // Object ID
   GRAPH_OBJ_PROP_TYPE,                               // Graphical object type (ENUM_OBJECT)
   GRAPH_OBJ_PROP_ELEMENT_TYPE,                       // Graphical element type (ENUM_GRAPH_ELEMENT_TYPE)
   GRAPH_OBJ_PROP_BELONG,                             // Graphical object affiliation
   GRAPH_OBJ_PROP_CHART_ID,                           // Chart ID
   GRAPH_OBJ_PROP_WND_NUM,                            // Chart subwindow index
   GRAPH_OBJ_PROP_NUM,                                // Object index in the list
   //--- Common properties of all graphical objects
   GRAPH_OBJ_PROP_CREATETIME,                         // Object creation time
   GRAPH_OBJ_PROP_TIMEFRAMES,                         // Object visibility on timeframes
   GRAPH_OBJ_PROP_BACK,                               // Background object
   GRAPH_OBJ_PROP_ZORDER,                             // Priority of a graphical object for receiving the event of clicking on a chart
   GRAPH_OBJ_PROP_HIDDEN,                             // Disable displaying the name of a graphical object in the terminal object list
   GRAPH_OBJ_PROP_SELECTED,                           // Object selection
   GRAPH_OBJ_PROP_SELECTABLE,                         // Object availability
//--- Properties belonging to different graphical objects
   GRAPH_OBJ_PROP_TIME,                               // Time coordinate
   GRAPH_OBJ_PROP_COLOR,                              // Color
   GRAPH_OBJ_PROP_STYLE,                              // Style
   GRAPH_OBJ_PROP_WIDTH,                              // Line width
   GRAPH_OBJ_PROP_FILL,                               // Object color filling
   GRAPH_OBJ_PROP_READONLY,                           // Ability to edit text in the Edit object
   GRAPH_OBJ_PROP_LEVELS,                             // Number of levels
   GRAPH_OBJ_PROP_LEVELCOLOR,                         // Level line color
   GRAPH_OBJ_PROP_LEVELSTYLE,                         // Level line style
   GRAPH_OBJ_PROP_LEVELWIDTH,                         // Level line width
   GRAPH_OBJ_PROP_ALIGN,                              // Horizontal text alignment in the Edit object (OBJ_EDIT)
   GRAPH_OBJ_PROP_FONTSIZE,                           // Font size
   GRAPH_OBJ_PROP_RAY_LEFT,                           // Ray goes to the left
   GRAPH_OBJ_PROP_RAY_RIGHT,                          // Ray goes to the right
   GRAPH_OBJ_PROP_RAY,                                // Vertical line goes through all windows of a chart
   GRAPH_OBJ_PROP_ELLIPSE,                            // Display the full ellipse of the Fibonacci Arc object
   GRAPH_OBJ_PROP_ARROWCODE,                          // Arrow code for the "Arrow" object
   GRAPH_OBJ_PROP_ANCHOR,                             // Position of the binding point of the graphical object
   GRAPH_OBJ_PROP_XDISTANCE,                          // Distance from the base corner along the X axis in pixels
   GRAPH_OBJ_PROP_YDISTANCE,                          // Distance from the base corner along the Y axis in pixels
   GRAPH_OBJ_PROP_DIRECTION,                          // Gann object trend
   GRAPH_OBJ_PROP_DEGREE,                             // Elliott wave marking level
   GRAPH_OBJ_PROP_DRAWLINES,                          // Display lines for Elliott wave marking
   GRAPH_OBJ_PROP_STATE,                              // Button state (pressed/released)
   GRAPH_OBJ_PROP_OBJ_CHART_ID,                       // Chart object ID (OBJ_CHART).
   GRAPH_OBJ_PROP_CHART_OBJ_PERIOD,                   // Chart object period
   GRAPH_OBJ_PROP_CHART_OBJ_DATE_SCALE,               // Time scale display flag for the Chart object
   GRAPH_OBJ_PROP_CHART_OBJ_PRICE_SCALE,              // Price scale display flag for the Chart object
   GRAPH_OBJ_PROP_CHART_OBJ_CHART_SCALE,              // Chart object scale
   GRAPH_OBJ_PROP_XSIZE,                              // Object width along the X axis in pixels.
   GRAPH_OBJ_PROP_YSIZE,                              // Object height along the Y axis in pixels.
   GRAPH_OBJ_PROP_XOFFSET,                            // X coordinate of the upper-left corner of the visibility area.
   GRAPH_OBJ_PROP_YOFFSET,                            // Y coordinate of the upper-left corner of the visibility area.
   GRAPH_OBJ_PROP_BGCOLOR,                            // Background color for OBJ_EDIT, OBJ_BUTTON, OBJ_RECTANGLE_LABEL
   GRAPH_OBJ_PROP_CORNER,                             // Chart corner for binding a graphical object
   GRAPH_OBJ_PROP_BORDER_TYPE,                        // Border type for "Rectangle border"
   GRAPH_OBJ_PROP_BORDER_COLOR,                       // Border color for OBJ_EDIT and OBJ_BUTTON
  };
#define GRAPH_OBJ_PROP_INTEGER_TOTAL (51)             // Total number of integer properties
#define GRAPH_OBJ_PROP_INTEGER_SKIP  (0)              // Number of integer properties not used in sorting
//+------------------------------------------------------------------+
//| Real properties of a standard graphical object                   |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_OBJ_PROP_DOUBLE
  {
   GRAPH_OBJ_PROP_PRICE = GRAPH_OBJ_PROP_INTEGER_TOTAL,// Price coordinate
   GRAPH_OBJ_PROP_LEVELVALUE,                         // Level value
   GRAPH_OBJ_PROP_SCALE,                              // Scale
   GRAPH_OBJ_PROP_ANGLE,                              // Angle
   GRAPH_OBJ_PROP_DEVIATION,                          // Deviation of the standard deviation channel
  };
#define GRAPH_OBJ_PROP_DOUBLE_TOTAL  (5)              // Total number of real properties
#define GRAPH_OBJ_PROP_DOUBLE_SKIP   (0)              // Number of real properties not used in sorting
//+------------------------------------------------------------------+
//| String properties of a standard graphical object                 |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_OBJ_PROP_STRING
  {
   GRAPH_OBJ_PROP_NAME = (GRAPH_OBJ_PROP_INTEGER_TOTAL+GRAPH_OBJ_PROP_DOUBLE_TOTAL), // Object name
   GRAPH_OBJ_PROP_TEXT,                               // Object description (text contained in the object)
   GRAPH_OBJ_PROP_TOOLTIP,                            // Tooltip text
   GRAPH_OBJ_PROP_LEVELTEXT,                          // Level description
   GRAPH_OBJ_PROP_FONT,                               // Font
   GRAPH_OBJ_PROP_BMPFILE,                            // BMP file name for the "Bitmap Level" object
   GRAPH_OBJ_PROP_CHART_OBJ_SYMBOL,                   // Symbol for the Chart object 
  };
#define GRAPH_OBJ_PROP_STRING_TOTAL  (7)              // Total number of string properties
//+------------------------------------------------------------------+

我们已经知道此类枚举的意图,因为所有函数库对象都遵循相同的原则。

因此,我们还需要添加针对集合列表中图形对象进行排序的可能标准的枚举:

//+------------------------------------------------------------------+
//| Possible sorting criteria of graphical objects                   |
//+------------------------------------------------------------------+
#define FIRST_GRAPH_OBJ_DBL_PROP  (GRAPH_OBJ_PROP_INTEGER_TOTAL-GRAPH_OBJ_PROP_INTEGER_SKIP)
#define FIRST_GRAPH_OBJ_STR_PROP  (GRAPH_OBJ_PROP_INTEGER_TOTAL-GRAPH_OBJ_PROP_INTEGER_SKIP+GRAPH_OBJ_PROP_DOUBLE_TOTAL-GRAPH_OBJ_PROP_DOUBLE_SKIP)
enum ENUM_SORT_GRAPH_OBJ_MODE
  {
//--- Sort by integer properties
   SORT_BY_GRAPH_OBJ_ID = 0,                             // Sort by object ID
   SORT_BY_GRAPH_OBJ_TYPE,                               // Sort by object type
   SORT_BY_GRAPH_OBJ_ELEMENT_TYPE,                       // Sort by graphical element type
   SORT_BY_GRAPH_OBJ_BELONG,                             //  Sort by a graphical element affiliation
   SORT_BY_GRAPH_OBJ_CHART_ID,                           // Sort by chart ID
   SORT_BY_GRAPH_OBJ_WND_NUM,                            // Sort by chart subwindow index
   SORT_BY_GRAPH_OBJ_NUM,                                // Sort by object index in the list
   SORT_BY_GRAPH_OBJ_CREATETIME,                         // Sort by object creation time
   SORT_BY_GRAPH_OBJ_TIMEFRAMES,                         // Sort by object visibility on timeframes
   SORT_BY_GRAPH_OBJ_BACK,                               // Sort by the "Background object" property
   SORT_BY_GRAPH_OBJ_ZORDER,                             // Sort by the priority of a graphical object for receiving the event of clicking on a chart
   SORT_BY_GRAPH_OBJ_HIDDEN,                             // Sort by a disabling display of the name of a graphical object in the terminal object list
   SORT_BY_GRAPH_OBJ_SELECTED,                           // Sort by the "Object selection" property
   SORT_BY_GRAPH_OBJ_SELECTABLE,                         // Sort by the "Object availability" property
   SORT_BY_GRAPH_OBJ_TIME,                               // Sort by time coordinate
   SORT_BY_GRAPH_OBJ_COLOR,                              // Sort by color
   SORT_BY_GRAPH_OBJ_STYLE,                              // Sort by style
   SORT_BY_GRAPH_OBJ_WIDTH,                              // Sort by line width
   SORT_BY_GRAPH_OBJ_FILL,                               // Sort by the "Object color filling" property
   SORT_BY_GRAPH_OBJ_READONLY,                           // Sort by the ability to edit text in the Edit object
   SORT_BY_GRAPH_OBJ_LEVELS,                             // Sort by number of levels
   SORT_BY_GRAPH_OBJ_LEVELCOLOR,                         // Sort by line level color
   SORT_BY_GRAPH_OBJ_LEVELSTYLE,                         // Sort by line level style
   SORT_BY_GRAPH_OBJ_LEVELWIDTH,                         // Sort by line level width
   SORT_BY_GRAPH_OBJ_ALIGN,                              // Sort by the "Horizontal text alignment in the Entry field" property
   SORT_BY_GRAPH_OBJ_FONTSIZE,                           // Sort by font size
   SORT_BY_GRAPH_OBJ_RAY_LEFT,                           // Sort by "Ray goes to the left" property
   SORT_BY_GRAPH_OBJ_RAY_RIGHT,                          // Sort by "Ray goes to the right" property
   SORT_BY_GRAPH_OBJ_RAY,                                // Sort by the "Vertical line goes through all windows of a chart" property
   SORT_BY_GRAPH_OBJ_ELLIPSE,                            // Sort by the "Display the full ellipse of the Fibonacci Arc object" property
   SORT_BY_GRAPH_OBJ_ARROWCODE,                          // Sort by an arrow code for the Arrow object
   SORT_BY_GRAPH_OBJ_ANCHOR,                             // Sort by the position of a binding point of a graphical object
   SORT_BY_GRAPH_OBJ_XDISTANCE,                          // Sort by a distance from the base corner along the X axis in pixels
   SORT_BY_GRAPH_OBJ_YDISTANCE,                          // Sort by a distance from the base corner along the Y axis in pixels
   SORT_BY_GRAPH_OBJ_DIRECTION,                          // Sort by the "Gann object trend" property
   SORT_BY_GRAPH_OBJ_DEGREE,                             // Sort by the "Elliott wave marking level" property
   SORT_BY_GRAPH_OBJ_DRAWLINES,                          // Sort by the "Display lines for Elliott wave marking" property
   SORT_BY_GRAPH_OBJ_STATE,                              // Sort by button state (pressed/released)
   SORT_BY_GRAPH_OBJ_OBJ_CHART_ID,                       // Sort by Chart object ID.
   SORT_BY_GRAPH_OBJ_CHART_OBJ_PERIOD,                   // Sort by Chart object period
   SORT_BY_GRAPH_OBJ_CHART_OBJ_DATE_SCALE,               // Sort by time scale display flag for the Chart object
   SORT_BY_GRAPH_OBJ_CHART_OBJ_PRICE_SCALE,              // Sort by price scale display flag for the Chart object
   SORT_BY_GRAPH_OBJ_CHART_OBJ_CHART_SCALE,              // Sort by Chart object scale
   SORT_BY_GRAPH_OBJ_XSIZE,                              // Sort by Object width along the X axis in pixels
   SORT_BY_GRAPH_OBJ_YSIZE,                              // Sort by object height along the Y axis in pixels
   SORT_BY_GRAPH_OBJ_XOFFSET,                            // Sort by X coordinate of the upper-left corner of the visibility area
   SORT_BY_GRAPH_OBJ_YOFFSET,                            // Sort by Y coordinate of the upper-left corner of the visibility area
   SORT_BY_GRAPH_OBJ_BGCOLOR,                            // Sort by background color for OBJ_EDIT, OBJ_BUTTON and OBJ_RECTANGLE_LABEL
   SORT_BY_GRAPH_OBJ_CORNER,                             // Sort by chart corner for binding a graphical object
   SORT_BY_GRAPH_OBJ_BORDER_TYPE,                        // Sort by border type for the "Rectangle border" object
   SORT_BY_GRAPH_OBJ_BORDER_COLOR,                       // Sort by frame color for the OBJ_EDIT and OBJ_BUTTON objects
//--- Sort by real properties
   SORT_BY_GRAPH_OBJ_PRICE = FIRST_GRAPH_OBJ_DBL_PROP,   // Sort by price coordinate
   SORT_BY_GRAPH_OBJ_LEVELVALUE,                         // Sort by level value
   SORT_BY_GRAPH_OBJ_SCALE,                              // Sort by scale (property of Gann objects and Fibonacci Arcs objects)
   SORT_BY_GRAPH_OBJ_ANGLE,                              // Sort by angle
   SORT_BY_GRAPH_OBJ_DEVIATION,                          // Sort by a deviation of the standard deviation channel
//--- Sort by string properties
   SORT_BY_GRAPH_OBJ_NAME = FIRST_GRAPH_OBJ_STR_PROP,    // Sort by object name
   SORT_BY_GRAPH_OBJ_TEXT,                               // Sort by object description
   SORT_BY_GRAPH_OBJ_TOOLTIP,                            // Sort by tooltip text
   SORT_BY_GRAPH_OBJ_LEVELTEXT,                          // Sort by level description
   SORT_BY_GRAPH_OBJ_FONT,                               // Sort by font
   SORT_BY_GRAPH_OBJ_BMPFILE,                            // Sort by BMP file name for the "Bitmap Level" object
   SORT_BY_GRAPH_OBJ_CHART_OBJ_SYMBOL,                   // Sort by Chart object period symbol
  };
//+------------------------------------------------------------------+


现在我们添加新函数库消息的文本,和所有图形对象属性的描述。
为此,在 \MQL5\Include\DoEasy\Data.mqh 中添加新函数库消息索引:

   MSG_LIB_TEXT_JANUARY,                              // January
   MSG_LIB_TEXT_FEBRUARY,                             // February
   MSG_LIB_TEXT_MARCH,                                // March
   MSG_LIB_TEXT_APRIL,                                // April
   MSG_LIB_TEXT_MAY,                                  // May
   MSG_LIB_TEXT_JUNE,                                 // June
   MSG_LIB_TEXT_JULY,                                 // July
   MSG_LIB_TEXT_AUGUST,                               // August
   MSG_LIB_TEXT_SEPTEMBER,                            // September
   MSG_LIB_TEXT_OCTOBER,                              // October
   MSG_LIB_TEXT_NOVEMBER,                             // November
   MSG_LIB_TEXT_DECEMBER,                             // December
   
   MSG_LIB_TEXT_ALIGN_LEFT,                           // Left alignment 
   MSG_LIB_TEXT_ALIGN_CENTER,                         // Center alignment
   MSG_LIB_TEXT_ALIGN_RIGHT,                          // Right alignment
   
   MSG_LIB_TEXT_GANN_UP_TREND,                        // Line corresponds to an uptrend
   MSG_LIB_TEXT_GANN_DOWN_TREND,                      // Line corresponds to a downtrend
   
   MSG_LIB_TEXT_ELLIOTT_GRAND_SUPERCYCLE,             // Grand Supercycle
   MSG_LIB_TEXT_ELLIOTT_SUPERCYCLE,                   // Supercycle
   MSG_LIB_TEXT_ELLIOTT_CYCLE,                        // Cycle
   MSG_LIB_TEXT_ELLIOTT_PRIMARY,                      // Primary cycle
   MSG_LIB_TEXT_ELLIOTT_INTERMEDIATE,                 // Intermediate
   MSG_LIB_TEXT_ELLIOTT_MINOR,                        // Minor cycle
   MSG_LIB_TEXT_ELLIOTT_MINUTE,                       // Minute
   MSG_LIB_TEXT_ELLIOTT_MINUETTE,                     // Second (Minuette)
   MSG_LIB_TEXT_ELLIOTT_SUBMINUETTE,                  // Subsecond (Subminuette)
   
   MSG_LIB_TEXT_BUTTON_STATE_PRESSED,                 // Pressed
   MSG_LIB_TEXT_BUTTON_STATE_DEPRESSED,               // Released
   
   MSG_LIB_TEXT_CORNER_LEFT_UPPER,                    // Center of coordinates at the upper left corner of the chart
   MSG_LIB_TEXT_CORNER_LEFT_LOWER,                    // Center of coordinates at the lower left corner of the chart
   MSG_LIB_TEXT_CORNER_RIGHT_LOWER,                   // Center of coordinates at the lower right corner of the chart
   MSG_LIB_TEXT_CORNER_RIGHT_UPPER,                   // Center of coordinates at the upper right corner of the chart
   
   MSG_LIB_TEXT_BORDER_FLAT,                          // Flat
   MSG_LIB_TEXT_BORDER_RAISED,                        // Raised
   MSG_LIB_TEXT_BORDER_SUNKEN,                        // Sunken
   
   MSG_LIB_TEXT_SUNDAY,                               // Sunday
   MSG_LIB_TEXT_MONDAY,                               // Monday
   MSG_LIB_TEXT_TUESDAY,                              // Tuesday
   MSG_LIB_TEXT_WEDNESDAY,                            // Wednesday
   MSG_LIB_TEXT_THURSDAY,                             // Thursday
   MSG_LIB_TEXT_FRIDAY,                               // Friday
   MSG_LIB_TEXT_SATURDAY,                             // Saturday

...

//--- CGraphElementsCollection
   MSG_GRAPH_ELM_COLLECTION_ERR_OBJ_ALREADY_EXISTS,   // Error. A chart control object already exists with chart id 
   MSG_GRAPH_ELM_COLLECTION_ERR_FAILED_CREATE_CTRL_OBJ,// Failed to create chart control object with chart ID 
   
//--- GStdGraphObj
   MSG_GRAPH_STD_OBJ_ERR_NOT_FIND_SUBWINDOW,          // Failed to find the chart subwindow
   
   MSG_GRAPH_ELEMENT_TYPE_STANDART,                   // Standard graphical object
   MSG_GRAPH_ELEMENT_TYPE_ELEMENT,                    // Element
   MSG_GRAPH_ELEMENT_TYPE_SHADOW_OBJ,                 // Shadow object
   MSG_GRAPH_ELEMENT_TYPE_FORM,                       // Form
   MSG_GRAPH_ELEMENT_TYPE_WINDOW,                     // Window
   
   MSG_GRAPH_OBJ_BELONG_PROGRAM,                      // Graphical object belongs to a program
   MSG_GRAPH_OBJ_BELONG_NO_PROGRAM,                   // Graphical object does not belong to a program
//---
   MSG_GRAPH_STD_OBJ_VLINE,                           // Vertical line
   MSG_GRAPH_STD_OBJ_HLINE,                           // Horizontal line
   MSG_GRAPH_STD_OBJ_TREND,                           // Trend line
   MSG_GRAPH_STD_OBJ_TRENDBYANGLE,                    // Trend line by angle
   MSG_GRAPH_STD_OBJ_CYCLES,                          // Cyclic lines
   MSG_GRAPH_STD_OBJ_ARROWED_LINE,                    // Arrowed line object
   MSG_GRAPH_STD_OBJ_CHANNEL,                         // Equidistant channel
   MSG_GRAPH_STD_OBJ_STDDEVCHANNEL,                   // Standard deviation channel
   MSG_GRAPH_STD_OBJ_REGRESSION,                      // Linear regression channel
   MSG_GRAPH_STD_OBJ_PITCHFORK,                       // Andrews' pitchfork
   MSG_GRAPH_STD_OBJ_GANNLINE,                        // Gann line
   MSG_GRAPH_STD_OBJ_GANNFAN,                         // Gann fan
   MSG_GRAPH_STD_OBJ_GANNGRID,                        // Gann grid
   MSG_GRAPH_STD_OBJ_FIBO,                            // Fibo levels
   MSG_GRAPH_STD_OBJ_FIBOTIMES,                       // Fibo time zones
   MSG_GRAPH_STD_OBJ_FIBOFAN,                         // Fibo fan
   MSG_GRAPH_STD_OBJ_FIBOARC,                         // Fibo arcs
   MSG_GRAPH_STD_OBJ_FIBOCHANNEL,                     // Fibo channel
   MSG_GRAPH_STD_OBJ_EXPANSION,                       // Fibo expansion
   MSG_GRAPH_STD_OBJ_ELLIOTWAVE5,                     // Elliott 5 waves
   MSG_GRAPH_STD_OBJ_ELLIOTWAVE3,                     // Elliott 3 waves
   MSG_GRAPH_STD_OBJ_RECTANGLE,                       // Rectangle
   MSG_GRAPH_STD_OBJ_TRIANGLE,                        // Triangle
   MSG_GRAPH_STD_OBJ_ELLIPSE,                         // Ellipse
   MSG_GRAPH_STD_OBJ_ARROW_THUMB_UP,                  // Thumb up
   MSG_GRAPH_STD_OBJ_ARROW_THUMB_DOWN,                // Thumb down
   MSG_GRAPH_STD_OBJ_ARROW_UP,                        // Arrow up
   MSG_GRAPH_STD_OBJ_ARROW_DOWN,                      // Arrow down
   MSG_GRAPH_STD_OBJ_ARROW_STOP,                      // Stop
   MSG_GRAPH_STD_OBJ_ARROW_CHECK,                     // Check mark
   MSG_GRAPH_STD_OBJ_ARROW_LEFT_PRICE,                // Left price label
   MSG_GRAPH_STD_OBJ_ARROW_RIGHT_PRICE,               // Right price label
   MSG_GRAPH_STD_OBJ_ARROW_BUY,                       // Buy
   MSG_GRAPH_STD_OBJ_ARROW_SELL,                      // Sell
   MSG_GRAPH_STD_OBJ_ARROW,                           // Arrow
   MSG_GRAPH_STD_OBJ_TEXT,                            // Text
   MSG_GRAPH_STD_OBJ_LABEL,                           // Text label
   MSG_GRAPH_STD_OBJ_BUTTON,                          // Button
   MSG_GRAPH_STD_OBJ_CHART,                           // Chart
   MSG_GRAPH_STD_OBJ_BITMAP,                          // Bitmap
   MSG_GRAPH_STD_OBJ_BITMAP_LABEL,                    // Bitmap label
   MSG_GRAPH_STD_OBJ_EDIT,                            // Edit
   MSG_GRAPH_STD_OBJ_EVENT,                           // Event object which corresponds to an event in Economic Calendar
   MSG_GRAPH_STD_OBJ_RECTANGLE_LABEL,                 // Rectangle Label object used to create and design the custom graphical interface

   MSG_GRAPH_OBJ_PROP_ID,                             // Object ID
   MSG_GRAPH_OBJ_PROP_TYPE,                           // Graphical object type (ENUM_OBJECT)
   MSG_GRAPH_OBJ_PROP_ELEMENT_TYPE,                   // Graphical element type (ENUM_GRAPH_ELEMENT_TYPE)
   MSG_GRAPH_OBJ_PROP_BELONG,                         // Graphical object affiliation
   MSG_GRAPH_OBJ_PROP_CHART_ID,                       // Chart ID
   MSG_GRAPH_OBJ_PROP_WND_NUM,                        // Chart subwindow index
   MSG_GRAPH_OBJ_PROP_CREATETIME,                     // Creation time
   MSG_GRAPH_OBJ_PROP_TIMEFRAMES,                     // Object visibility on timeframes
   MSG_GRAPH_OBJ_PROP_BACK,                           // Background object
   MSG_GRAPH_OBJ_PROP_ZORDER,                         // Priority of a graphical object for receiving the event of clicking on a chart
   MSG_GRAPH_OBJ_PROP_HIDDEN,                         // Disable displaying the name of a graphical object in the terminal object list
   MSG_GRAPH_OBJ_PROP_SELECTED,                       // Object selection
   MSG_GRAPH_OBJ_PROP_SELECTABLE,                     // Object availability
   MSG_GRAPH_OBJ_PROP_NUM,                            // Object index in the list
   MSG_GRAPH_OBJ_PROP_TIME,                           // Time coordinate
   MSG_GRAPH_OBJ_PROP_COLOR,                          // Color
   MSG_GRAPH_OBJ_PROP_STYLE,                          // Style
   MSG_GRAPH_OBJ_PROP_WIDTH,                          // Line width
   MSG_GRAPH_OBJ_PROP_FILL,                           // Object color filling
   MSG_GRAPH_OBJ_PROP_READONLY,                       // Ability to edit text in the Edit object
   MSG_GRAPH_OBJ_PROP_LEVELS,                         // Number of levels
   MSG_GRAPH_OBJ_PROP_LEVELCOLOR,                     // Level line color
   MSG_GRAPH_OBJ_PROP_LEVELSTYLE,                     // Level line style
   MSG_GRAPH_OBJ_PROP_LEVELWIDTH,                     // Level line width
   MSG_GRAPH_OBJ_PROP_ALIGN,                          // Horizontal text alignment in the Edit object (OBJ_EDIT)
   MSG_GRAPH_OBJ_PROP_FONTSIZE,                       // Font size
   MSG_GRAPH_OBJ_PROP_RAY_LEFT,                       // Ray goes to the left
   MSG_GRAPH_OBJ_PROP_RAY_RIGHT,                      // Ray goes to the right
   MSG_GRAPH_OBJ_PROP_RAY,                            // Vertical line goes through all windows of a chart
   MSG_GRAPH_OBJ_PROP_ELLIPSE,                        // Display the full ellipse of the Fibonacci Arc object
   MSG_GRAPH_OBJ_PROP_ARROWCODE,                      // Arrow code for the "Arrow" object
   MSG_GRAPH_OBJ_PROP_ANCHOR,                         // Position of the binding point of the graphical object
   MSG_GRAPH_OBJ_PROP_XDISTANCE,                      // Distance from the base corner along the X axis in pixels
   MSG_GRAPH_OBJ_PROP_YDISTANCE,                      // Distance from the base corner along the Y axis in pixels
   MSG_GRAPH_OBJ_PROP_DIRECTION,                      // Gann object trend
   MSG_GRAPH_OBJ_PROP_DEGREE,                         // Elliott wave marking level
   MSG_GRAPH_OBJ_PROP_DRAWLINES,                      // Display lines for Elliott wave marking
   MSG_GRAPH_OBJ_PROP_STATE,                          // Button state (pressed/released)
   MSG_GRAPH_OBJ_PROP_CHART_OBJ_PERIOD,               // Chart object period
   MSG_GRAPH_OBJ_PROP_CHART_OBJ_DATE_SCALE,           // Time scale display flag for the Chart object
   MSG_GRAPH_OBJ_PROP_CHART_OBJ_PRICE_SCALE,          // Price scale display flag for the Chart object
   MSG_GRAPH_OBJ_PROP_CHART_OBJ_CHART_SCALE,          // Chart object scale
   MSG_GRAPH_OBJ_PROP_XSIZE,                          // Object width along the X axis in pixels.
   MSG_GRAPH_OBJ_PROP_YSIZE,                          // Object height along the Y axis in pixels.
   MSG_GRAPH_OBJ_PROP_XOFFSET,                        // X coordinate of the upper-left corner of the visibility area.
   MSG_GRAPH_OBJ_PROP_YOFFSET,                        // Y coordinate of the upper-left corner of the visibility area.
   MSG_GRAPH_OBJ_PROP_BGCOLOR,                        // Background color for OBJ_EDIT, OBJ_BUTTON, OBJ_RECTANGLE_LABEL
   MSG_GRAPH_OBJ_PROP_CORNER,                         // Chart corner for binding a graphical object
   MSG_GRAPH_OBJ_PROP_BORDER_TYPE,                    // Border type for "Rectangle border"
   MSG_GRAPH_OBJ_PROP_BORDER_COLOR,                   // Border color for OBJ_EDIT and OBJ_BUTTON
//---
   MSG_GRAPH_OBJ_PROP_PRICE,                          // Price coordinate
   MSG_GRAPH_OBJ_PROP_LEVELVALUE,                     // Level value
   MSG_GRAPH_OBJ_PROP_SCALE,                          // Scale (property of Gann objects and Fibonacci Arcs objects)
   MSG_GRAPH_OBJ_PROP_ANGLE,                          // Angle
   MSG_GRAPH_OBJ_PROP_DEVIATION,                      // Deviation of the standard deviation channel
//---
   MSG_GRAPH_OBJ_PROP_NAME,                           // Object name
   MSG_GRAPH_OBJ_PROP_TEXT,                           // Object description (text contained in the object)
   MSG_GRAPH_OBJ_PROP_TOOLTIP,                        // Tooltip text
   MSG_GRAPH_OBJ_PROP_LEVELTEXT,                      // Level description
   MSG_GRAPH_OBJ_PROP_FONT,                           // Font
   MSG_GRAPH_OBJ_PROP_BMPFILE,                        // BMP file name for the "Bitmap Level" object
   MSG_GRAPH_OBJ_PROP_SYMBOL,                         // Symbol for the Chart object 
   
  };
//+------------------------------------------------------------------+

与新增索引相对应的消息

   {"Январь","January"},
   {"Февраль","February"},
   {"Март","March"},
   {"Апрель","April"},
   {"Май","May"},
   {"Июнь","June"},
   {"Июль","July"},
   {"Август","August"},
   {"Сентябрь","September"},
   {"Октябрь","October"},
   {"Ноябрь","November"},
   {"Декабрь","December"},
   
   {"Выравнивание по левой границе","Left alignment"},
   {"Выравнивание по центру","Centered"},
   {"Выравнивание по правой границе","Right alignment",},
   
   {"Линия соответствует восходящему тренду","Line corresponding to the uptrend line"},
   {"Линия соответствует нисходящему тренду","Line corresponding to the downward trend"},
   
   {"Главный Суперцикл (Grand Supercycle)","Grand Supercycle"},
   {"Суперцикл (Supercycle)","Supercycle"},
   {"Цикл (Cycle)","Cycle"},
   {"Первичный цикл (Primary)","Primary"},
   {"Промежуточное звено (Intermediate)","Intermediate"},
   {"Второстепенный цикл (Minor)","Minor"},
   {"Минута (Minute)","Minute"},
   {"Секунда (Minuette)","Minuette"},
   {"Субсекунда (Subminuette)","Subminuette"},
   
   {"Нажата","Pressed"},
   {"Отжата","Depressed"},
   
   {"Центр координат в левом верхнем углу графика","Center of coordinates is in the upper left corner of the chart"},
   {"Центр координат в левом нижнем углу графика","Center of coordinates is in the lower left corner of the chart"},
   {"Центр координат в правом нижнем углу графика","Center of coordinates is in the lower right corner of the chart"},
   {"Центр координат в правом верхнем углу графика","Center of coordinates is in the upper right corner of the chart"},
   
   {"Плоский вид","Flat form"},
   {"Выпуклый вид","Prominent form"},
   {"Вогнутый вид","Concave form"},
   
   {"Воскресение","Sunday"},
   {"Понедельник","Monday"},
   {"Вторник","Tuesday"},
   {"Среда","Wednesday"},
   {"Четверг","Thursday"},
   {"Пятница","Friday"},
   {"Суббота","Saturday"},

...

//--- CGraphElementsCollection
   {"Ошибка. Уже существует объект управления чартами с идентификатором чарта ","Error. A chart control object already exists with chart id "},
   {"Не удалось создать объект управления чартами с идентификатором чарта ","Failed to create chart control object with chart id "},

//--- GStdGraphObj
   {"Не удалось найти подокно графика","Could not find chart subwindow"},
   
   {"Стандартный графический объект","Standard graphic object"},
   {"Элемент","Element"},
   {"Объект тени","Shadow object"},
   {"Форма","Form"},
   {"Окно","Window"},
   
   {"Графический объект принадлежит программе","The graphic object belongs to the program"},
   {"Графический объект не принадлежит программе","The graphic object does not belong to the program"},
   
   {"Вертикальная линия","Vertical Line"},
   {"Горизонтальная линия","Horizontal Line"},
   {"Трендовая линия","Trend Line"},
   {"Трендовая линия по углу","Trend Line By Angle"},
   {"Циклические линии","Cycle Lines"},
   {"Линия со стрелкой","Arrowed Line"},
   {"Равноудаленный канал","Equidistant Channel"},
   {"Канал стандартного отклонения","Standard Deviation Channel"},
   {"Канал на линейной регрессии","Linear Regression Channel"},
   {"Вилы Эндрюса","Andrews’ Pitchfork"},
   {"Линия Ганна","Gann Line"},
   {"Веер Ганна","Gann Fan"},
   {"Сетка Ганна","Gann Grid"},
   {"Уровни Фибоначчи","Fibonacci Retracement"},
   {"Временные зоны Фибоначчи","Fibonacci Time Zones"},
   {"Веер Фибоначчи","Fibonacci Fan"},
   {"Дуги Фибоначчи","Fibonacci Arcs"},
   {"Канал Фибоначчи","Fibonacci Channel"},
   {"Расширение Фибоначчи","Fibonacci Expansion"},
   {"5-волновка Эллиотта","Elliott Motive Wave"},
   {"3-волновка Эллиотта","Elliott Correction Wave"},
   {"Прямоугольник","Rectangle"},
   {"Треугольник","Triangle"},
   {"Эллипс","Ellipse"},
   {"Знак \"Хорошо\"","Thumbs Up"},
   {"Знак \"Плохо\"","Thumbs Down"},
   {"Знак \"Стрелка вверх\"","Arrow Up"},
   {"Знак \"Стрелка вниз\"","Arrow Down"},
   {"Знак \"Стоп\"","Stop Sign"},
   {"Знак \"Птичка\"","Check Sign"},
   {"Левая ценовая метка","Left Price Label"},
   {"Правая ценовая метка","Right Price Label"},
   {"Знак \"Buy\"","Buy Sign"},
   {"Знак \"Sell\"","Sell Sign"},
   {"Стрелка","Arrow"},
   {"Текст","Text"},
   {"Текстовая метка","Label"},
   {"Кнопка","Button"},
   {"График","Chart"},
   {"Рисунок","Bitmap"},
   {"Графическая метка","Bitmap Label"},
   {"Поле ввода","Edit"},
   {"Событие в экономическом календаре","The \"Event\" object corresponding to an event in the economic calendar"},
   {"Прямоугольная метка","The \"Rectangle label\" object for creating and designing the custom graphical interface"},
   
   {"Идентификатор объекта","Object ID"},
   {"Тип объекта","Object type"},
   {"Тип графического элемента","Graphic element type"},
   {"Принадлежность объекта","Object belongs to"},
   {"Идентификатор графика объекта","Object chart ID"},
   {"Номер подокна графика","Chart subwindow number"},
   {"Время создания","Time of creation"},
   {"Видимость объекта на таймфреймах","Visibility of an object at timeframes"},
   {"Объект на заднем плане","Object in the background"},
   {"Приоритет графического объекта на получение события нажатия мышки на графике","Priority of a graphical object for receiving events of clicking on a chart"},
   {"Запрет на показ имени графического объекта в списке объектов терминала","Prohibit showing of the name of a graphical object in the terminal objects list"},
   {"Выделенность объекта","Object is selected"},
   {"Доступность объекта","Object availability"},
   {"Номер объекта в списке","Object number in the list"},
   {"Координата времени","Time coordinate"},
   {"Цвет","Color"},
   {"Стиль","Style"},
   {"Толщина линии","Line thickness"},
   {"Заливка объекта цветом","Fill an object with color"},
   {"Возможность редактирования текста","Ability to edit text"},
   {"Количество уровней","Number of levels"},
   {"Цвет линии-уровня","Color of the line-level"},
   {"Стиль линии-уровня","Style of the line-level"},
   {"Толщина линии-уровня","Thickness of the line-level"},
   {"Горизонтальное выравнивание текста","Horizontal text alignment"},
   {"Размер шрифта","Font size"},
   {"Луч продолжается влево","Ray goes to the left"},
   {"Луч продолжается вправо","Ray goes to the right"},
   {"Вертикальная линия продолжается на все окна графика","A vertical line goes through all the windows of a chart"},
   {"Отображение полного эллипса","Showing the full ellipse"},
   {"Код стрелки","Arrow code"},
   {"Положение точки привязки","Location of the anchor point"},
   {"Дистанция в пикселях по оси X от угла привязки","The distance in pixels along the X axis from the binding corner"},
   {"Дистанция в пикселях по оси Y от угла привязки","The distance in pixels along the Y axis from the binding corner"},
   {"Тренд","Trend"},
   {"Уровень","Level"},
   {"Отображение линий","Displaying lines"},
   {"Состояние кнопки","Button state"},
   {"Период графика","Chart timeframe"},
   {"Отображение шкалы времени","Displaying the time scale"},
   {"Отображение ценовой шкалы","Displaying the price scale"},
   {"Масштаб графика","Chart scale"},
   {"Ширина по оси X в пикселях","Width along the X axis in pixels"},
   {"Высота по оси Y в пикселях","Height along the Y axis in pixels"},
   {"X-координата левого верхнего угла прямоугольной области видимости","The X coordinate of the upper left corner of the rectangular visible area"},
   {"Y-координата левого верхнего угла прямоугольной области видимости","The Y coordinate of the upper left corner of the rectangular visible area"},
   {"Цвет фона","Background color"},
   {"Угол графика для привязки","The corner of the chart to link a graphical object"},
   {"Тип рамки","Border type"},
   {"Цвет рамки","Border color"},
   {"Координата цены","Price coordinate"},
   {"Значение уровня","Level value"},
   {"Масштаб","Scale"},
   {"Угол","Angle"},
   {"Отклонение канала стандартного отклонения","Deviation for the Standard Deviation Channel"},
   {"Имя","Name"},
   {"Описание","Description"},
   {"Текст всплывающей подсказки","The text of a tooltip"},
   {"Описание уровня","Level description"},
   {"Шрифт","Font"},
   {"Имя BMP-файла","BMP-file name"},
   {"Символ графика","Chart Symbol"},

  };
//+---------------------------------------------------------------------+


一些图形对象属性具有枚举类型。 为了返回枚举的描述,我们需要在函数库服务函数文件 \MQL5\Include\DoEasy\Services\DELib.mqh 中创建函数:

返回线型描述的函数:

//+------------------------------------------------------------------+
//| Return description of the line style                             |
//+------------------------------------------------------------------+
string LineStyleDescription(const ENUM_LINE_STYLE style)
  {
   return
     (
      style==STYLE_SOLID      ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_SOLID)      :
      style==STYLE_DASH       ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DASH)       :
      style==STYLE_DOT        ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DOT)        :
      style==STYLE_DASHDOT    ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DASHDOT)    :
      style==STYLE_DASHDOTDOT ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DASHDOTDOT) :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

返回对齐类型描述的函数:

//+------------------------------------------------------------------+
//| Return the alignment type description                            |
//+------------------------------------------------------------------+
string AlignModeDescription(ENUM_ALIGN_MODE align)
  {
   return
     (
      align==ALIGN_LEFT    ? CMessage::Text(MSG_LIB_TEXT_ALIGN_LEFT)    :
      align==ALIGN_CENTER  ? CMessage::Text(MSG_LIB_TEXT_ALIGN_CENTER)  :
      align==ALIGN_RIGHT   ? CMessage::Text(MSG_LIB_TEXT_ALIGN_RIGHT)   :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

返回江恩网格趋势方向描述的函数:

//+------------------------------------------------------------------+
//| Return the description of the Gann grid trend direction          |
//+------------------------------------------------------------------+
string GannDirectDescription(const ENUM_GANN_DIRECTION direction)
  {
   return
     (
      direction==GANN_UP_TREND   ? CMessage::Text(MSG_LIB_TEXT_GANN_UP_TREND)    :
      direction==GANN_DOWN_TREND ? CMessage::Text(MSG_LIB_TEXT_GANN_DOWN_TREND)  :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

返回埃洛特波浪标记水平描述的函数:

//+------------------------------------------------------------------+
//| Return the description of the Elliott wave marking level         |
//+------------------------------------------------------------------+
string ElliotWaveDegreeDescription(const ENUM_ELLIOT_WAVE_DEGREE degree)
  {
   return
     (
      degree==ELLIOTT_GRAND_SUPERCYCLE ? CMessage::Text(MSG_LIB_TEXT_ELLIOTT_GRAND_SUPERCYCLE)  :
      degree==ELLIOTT_SUPERCYCLE       ? CMessage::Text(MSG_LIB_TEXT_ELLIOTT_SUPERCYCLE)        :
      degree==ELLIOTT_CYCLE            ? CMessage::Text(MSG_LIB_TEXT_ELLIOTT_CYCLE)             :
      degree==ELLIOTT_PRIMARY          ? CMessage::Text(MSG_LIB_TEXT_ELLIOTT_PRIMARY)           :
      degree==ELLIOTT_INTERMEDIATE     ? CMessage::Text(MSG_LIB_TEXT_ELLIOTT_INTERMEDIATE)      :
      degree==ELLIOTT_MINOR            ? CMessage::Text(MSG_LIB_TEXT_ELLIOTT_MINOR)             :
      degree==ELLIOTT_MINUTE           ? CMessage::Text(MSG_LIB_TEXT_ELLIOTT_MINUTE)            :
      degree==ELLIOTT_MINUETTE         ? CMessage::Text(MSG_LIB_TEXT_ELLIOTT_MINUETTE)          :
      degree==ELLIOTT_SUBMINUETTE      ? CMessage::Text(MSG_LIB_TEXT_ELLIOTT_SUBMINUETTE)       :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

该函数返回相对于指定坐标像素的图表边角描述,:

//+------------------------------------------------------------------+
//| Return the description of the chart corner, relative to          |
//| which the coordinates in pixels are specified                    |
//+------------------------------------------------------------------+
string BaseCornerDescription(const ENUM_BASE_CORNER corner)
  {
   return
     (
      corner==CORNER_LEFT_UPPER  ? CMessage::Text(MSG_LIB_TEXT_CORNER_LEFT_UPPER)   :
      corner==CORNER_LEFT_LOWER  ? CMessage::Text(MSG_LIB_TEXT_CORNER_LEFT_LOWER)   :
      corner==CORNER_RIGHT_LOWER ? CMessage::Text(MSG_LIB_TEXT_CORNER_RIGHT_LOWER)  :
      corner==CORNER_RIGHT_UPPER ? CMessage::Text(MSG_LIB_TEXT_CORNER_RIGHT_UPPER)  :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

返回图形对象边框外观描述的函数:

//+------------------------------------------------------------------+
//| Return the description of the graphical object frame look        |
//+------------------------------------------------------------------+
string BorderTypeDescription(const ENUM_BORDER_TYPE border_type)
  {
   return
     (
      border_type==BORDER_FLAT   ? CMessage::Text(MSG_LIB_TEXT_BORDER_FLAT)   :
      border_type==BORDER_RAISED ? CMessage::Text(MSG_LIB_TEXT_BORDER_RAISED) :
      border_type==BORDER_SUNKEN ? CMessage::Text(MSG_LIB_TEXT_BORDER_SUNKEN) :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

返回标准图形对象类型描述的函数:

//+------------------------------------------------------------------+
//| Return the description of the standard graphical object type     |
//+------------------------------------------------------------------+
string StdGraphObjectTypeDescription(const ENUM_OBJECT type)
  {
   return
     (
      type==OBJ_VLINE               ? CMessage::Text(MSG_GRAPH_STD_OBJ_VLINE)             :
      type==OBJ_HLINE               ? CMessage::Text(MSG_GRAPH_STD_OBJ_HLINE)             :
      type==OBJ_TREND               ? CMessage::Text(MSG_GRAPH_STD_OBJ_TREND)             :
      type==OBJ_TRENDBYANGLE        ? CMessage::Text(MSG_GRAPH_STD_OBJ_TRENDBYANGLE)      :
      type==OBJ_CYCLES              ? CMessage::Text(MSG_GRAPH_STD_OBJ_CYCLES)            :
      type==OBJ_ARROWED_LINE        ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROWED_LINE)      :
      type==OBJ_CHANNEL             ? CMessage::Text(MSG_GRAPH_STD_OBJ_CHANNEL)           :
      type==OBJ_STDDEVCHANNEL       ? CMessage::Text(MSG_GRAPH_STD_OBJ_STDDEVCHANNEL)     :
      type==OBJ_REGRESSION          ? CMessage::Text(MSG_GRAPH_STD_OBJ_REGRESSION)        :
      type==OBJ_PITCHFORK           ? CMessage::Text(MSG_GRAPH_STD_OBJ_PITCHFORK)         :
      type==OBJ_GANNLINE            ? CMessage::Text(MSG_GRAPH_STD_OBJ_GANNLINE)          :
      type==OBJ_GANNFAN             ? CMessage::Text(MSG_GRAPH_STD_OBJ_GANNFAN)           :
      type==OBJ_GANNGRID            ? CMessage::Text(MSG_GRAPH_STD_OBJ_GANNGRID)          :
      type==OBJ_FIBO                ? CMessage::Text(MSG_GRAPH_STD_OBJ_FIBO)              :
      type==OBJ_FIBOTIMES           ? CMessage::Text(MSG_GRAPH_STD_OBJ_FIBOTIMES)         :
      type==OBJ_FIBOFAN             ? CMessage::Text(MSG_GRAPH_STD_OBJ_FIBOFAN)           :
      type==OBJ_FIBOARC             ? CMessage::Text(MSG_GRAPH_STD_OBJ_FIBOARC)           :
      type==OBJ_FIBOCHANNEL         ? CMessage::Text(MSG_GRAPH_STD_OBJ_FIBOCHANNEL)       :
      type==OBJ_EXPANSION           ? CMessage::Text(MSG_GRAPH_STD_OBJ_EXPANSION)         :
      type==OBJ_ELLIOTWAVE5         ? CMessage::Text(MSG_GRAPH_STD_OBJ_ELLIOTWAVE5)       :
      type==OBJ_ELLIOTWAVE3         ? CMessage::Text(MSG_GRAPH_STD_OBJ_ELLIOTWAVE3)       :
      type==OBJ_RECTANGLE           ? CMessage::Text(MSG_GRAPH_STD_OBJ_RECTANGLE)         :
      type==OBJ_TRIANGLE            ? CMessage::Text(MSG_GRAPH_STD_OBJ_TRIANGLE)          :
      type==OBJ_ELLIPSE             ? CMessage::Text(MSG_GRAPH_STD_OBJ_ELLIPSE)           :
      type==OBJ_ARROW_THUMB_UP      ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_THUMB_UP)    :
      type==OBJ_ARROW_THUMB_DOWN    ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_THUMB_DOWN)  :
      type==OBJ_ARROW_UP            ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_UP)          :
      type==OBJ_ARROW_DOWN          ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_DOWN)        :
      type==OBJ_ARROW_STOP          ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_STOP)        :
      type==OBJ_ARROW_CHECK         ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_CHECK)       :
      type==OBJ_ARROW_LEFT_PRICE    ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_LEFT_PRICE)  :
      type==OBJ_ARROW_RIGHT_PRICE   ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_RIGHT_PRICE) :
      type==OBJ_ARROW_BUY           ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_BUY)         :
      type==OBJ_ARROW_SELL          ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW_SELL)        :
      type==OBJ_ARROW               ? CMessage::Text(MSG_GRAPH_STD_OBJ_ARROW)             :
      type==OBJ_TEXT                ? CMessage::Text(MSG_GRAPH_STD_OBJ_TEXT)              :
      type==OBJ_LABEL               ? CMessage::Text(MSG_GRAPH_STD_OBJ_LABEL)             :
      type==OBJ_BUTTON              ? CMessage::Text(MSG_GRAPH_STD_OBJ_BUTTON)            :
      type==OBJ_CHART               ? CMessage::Text(MSG_GRAPH_STD_OBJ_CHART)             :
      type==OBJ_BITMAP              ? CMessage::Text(MSG_GRAPH_STD_OBJ_BITMAP)            :
      type==OBJ_BITMAP_LABEL        ? CMessage::Text(MSG_GRAPH_STD_OBJ_BITMAP_LABEL)      :
      type==OBJ_EDIT                ? CMessage::Text(MSG_GRAPH_STD_OBJ_EDIT)              :
      type==OBJ_EVENT               ? CMessage::Text(MSG_GRAPH_STD_OBJ_EVENT)             :
      type==OBJ_RECTANGLE_LABEL     ? CMessage::Text(MSG_GRAPH_STD_OBJ_RECTANGLE_LABEL)   :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

正如我们所看到的,每个函数都接收一个变量,指示该函数验证的类型。 接下来,比较传递给函数的类型,并调用 CMessage 类 的 Text() 方法返回其描述。

在抽象指标缓冲区类的 \MQL5\Include\DoEasy\Objects\Indicators\Buffer.mqh 文件中,重写返回指标缓冲区线型描述的方法。 以前,该方法与新添加的 LineStyleDescription() 函数具有相同的逻辑,如下所示:

//+------------------------------------------------------------------+
//| Return description of the drawing line style                     |
//+------------------------------------------------------------------+
string CBuffer::GetLineStyleDescription(void) const
  {
   return
     (
      this.LineStyle()==STYLE_SOLID       ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_SOLID)      :
      this.LineStyle()==STYLE_DASH        ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DASH)       :
      this.LineStyle()==STYLE_DOT         ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DOT)        :
      this.LineStyle()==STYLE_DASHDOT     ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DASHDOT)    :
      this.LineStyle()==STYLE_DASHDOTDOT  ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DASHDOTDOT) :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

由于我们已经有了所有函数库类通用的服务函数,故我们只需在方法中返回调用该函数的结果即可:

//+------------------------------------------------------------------+
//| Return description of the drawing line style                     |
//+------------------------------------------------------------------+
string CBuffer::GetLineStyleDescription(void) const
  {
   return LineStyleDescription(this.LineStyle());
  }
//+------------------------------------------------------------------+


鉴于我已为所有图形对象添加了许多新属性,且其中一些属性是所有函数库图形对象所共有的,因此 \MQL5\Include\DoEasy\Objects\Graph\ 中的函数库基准图形对象类 GBaseObj.mqh 应该被修改。 这是所有函数库图表对象均要从其继承的类。 我们添加所有图形对象公用的变量,并创建设置和返回变量值的方法。

在类的受保护部分,声明所有必要的变量

//+------------------------------------------------------------------+
//|                                                     GBaseObj.mqh |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "..\..\Services\DELib.mqh"
#include <Graphics\Graphic.mqh>
//+------------------------------------------------------------------+
//| Class of the base object of the library graphical objects        |
//+------------------------------------------------------------------+
class CGBaseObj : public CObject
  {
private:

protected:
   ENUM_OBJECT       m_type_graph_obj;                   // Graphical object type
   ENUM_GRAPH_ELEMENT_TYPE m_type_element;               // Graphical element type
   ENUM_GRAPH_OBJ_BELONG m_belong;                       // Program affiliation
   string            m_name_prefix;                      // Object name prefix
   string            m_name;                             // Object name
   long              m_chart_id;                         // Object chart ID
   long              m_object_id;                        // Object ID
   long              m_zorder;                           // Priority of a graphical object for receiving the mouse click event
   int               m_subwindow;                        // Subwindow index
   int               m_shift_y;                          // Subwindow Y coordinate shift
   int               m_type;                             // Object type
   int               m_timeframes_visible;               // Visibility of an object on timeframes (a set of flags)
   int               m_digits;                           // Number of decimal places in a quote
   bool              m_visible;                          // Object visibility
   bool              m_back;                             // "Background object" flag
   bool              m_selected;                         // "Object selection" flag
   bool              m_selectable;                       // "Object availability" flag
   bool              m_hidden;                           // "Disable displaying the name of a graphical object in the terminal object list" flag
   datetime          m_create_time;                      // Object creation time
   
//--- Create (1) the object structure and (2) the object from the structure
   virtual bool      ObjectToStruct(void)                      { return true; }
   virtual void      StructToObject(void){;}

public:

在类的公开部分,设置为每个函数库图形对象中存在的属性指定数值的方法:

public:
//--- Set the values of the class variables
   void              SetObjectID(const long value)             { this.m_object_id=value;           }
   void              SetBelong(const ENUM_GRAPH_OBJ_BELONG belong){ this.m_belong=belong;          }
   void              SetTypeGraphObject(const ENUM_OBJECT obj) { this.m_type_graph_obj=obj;        }
   void              SetTypeElement(const ENUM_GRAPH_ELEMENT_TYPE type) { this.m_type_element=type;}
   void              SetName(const string name)                { this.m_name=name;                 }
   void              SetChartID(const long chart_id)           { this.m_chart_id=chart_id;         }
   void              SetDigits(const int value)                { this.m_digits=value;              }

这些方法为指定对象属性设置的值仅存储在这些变量中,因此将传递给方法的值添加到变量中就足够了。

存储在类变量中,并在图形对象本身中指定的属性应以不同的方式设置。 首先,我们需要更改图形对象的属性如果请求成功, 在类变量中也要设置相同的值

//--- Set the "Background object" flag
   bool              SetBack(const bool flag)
                       {
                        ::ResetLastError();
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_BACK,flag))
                          {
                           this.m_back=flag;
                           return true;
                          }
                        else
                           CMessage::ToLog(DFUN,::GetLastError(),true);
                        return false;
                       }

设置图形对象值的函数使用异步调用,这意味着命令被加到另一个图表队列,而该函数不会等待其执行。 取而代之的是,它会立即返回控制权。

据此,我们并不能确信已成功添加到事件队列的函数会确定无疑地更爱图形对象的属性。


根据帮助为了查看命令执行结果,我们可以利用请求指定对象属性的函数。 不过,您应该记住,此类函数会添加到该图表队列的末尾,并且它们会等待执行结果,故可能会很耗时。 在图表上处理大量对象时,应考虑到此特性。

现在,我保持它们不变,并假设更改对象属性的命令已成功运行。 如果在使用函数库时,我检测到在类变量属性已经指定的情况下没有设置图形对象属性,我将添加一个检查,从而确保图形对象属性已被真实更改。

我们来研究为图形对象设置属性的所有类似方法,以及添加到类的公开部分的变量:

//--- Set the "Background object" flag
   bool              SetBack(const bool flag)
                       {
                        ::ResetLastError();
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_BACK,flag))
                          {
                           this.m_back=flag;
                           return true;
                          }
                        else
                           CMessage::ToLog(DFUN,::GetLastError(),true);
                        return false;
                       }
//--- Set the "Object selection" flag
   bool              SetSelected(const bool flag)
                       {
                        ::ResetLastError();
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_SELECTED,flag))
                          {
                           this.m_selected=flag;
                           return true;
                          }
                        else
                           CMessage::ToLog(DFUN,::GetLastError(),true);
                        return false;
                       }
//--- Set the "Object selection" flag
   bool              SetSelectable(const bool flag)
                       {
                        ::ResetLastError();
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_SELECTABLE,flag))
                          {
                           this.m_selectable=flag;
                           return true;
                          }
                        else
                           CMessage::ToLog(DFUN,::GetLastError(),true);
                        return false;
                       }
//--- Set the "Disable displaying the name of a graphical object in the terminal object list" flag
   bool              SetHidden(const bool flag)
                       {
                        ::ResetLastError();
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_SELECTABLE,flag))
                          {
                           this.m_hidden=flag;
                           return true;
                          }
                        else
                           CMessage::ToLog(DFUN,::GetLastError(),true);
                        return false;
                       }
//--- Set the priority of a graphical object for receiving the event of clicking on a chart 
   bool              SetZorder(const long value)
                       {
                        ::ResetLastError();
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_ZORDER,value))
                          {
                           this.m_zorder=value;
                           return true;
                          }
                        else
                           CMessage::ToLog(DFUN,::GetLastError(),true);
                        return false;
                       }
//--- Set object visibility on all timeframes
   bool              SetVisible(const bool flag)   
                       {
                        long value=(flag ? OBJ_ALL_PERIODS : OBJ_NO_PERIODS);
                        ::ResetLastError();
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_TIMEFRAMES,value))
                          {
                           this.m_visible=flag;
                           return true;
                          }
                        else
                           CMessage::ToLog(DFUN,::GetLastError(),true);
                        return false;
                       }
//--- Set visibility flags on timeframes specified as flags
   bool              SetVisibleOnTimeframe(const int flags)
                       {
                        ::ResetLastError();
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_TIMEFRAMES,flags))
                          {
                           this.m_timeframes_visible=flags;
                           return true;
                          }
                        else
                           CMessage::ToLog(DFUN,::GetLastError(),true);
                        return false;
                       }
//--- Add the visibility flag on a specified timeframe
   bool              SetVisibleOnTimeframe(const ENUM_TIMEFRAMES timeframe)
                       {
                        int flags=this.m_timeframes_visible;
                        switch(timeframe)
                          {
                           case PERIOD_M1    : flags |= OBJ_PERIOD_M1;  break;
                           case PERIOD_M2    : flags |= OBJ_PERIOD_M2;  break;
                           case PERIOD_M3    : flags |= OBJ_PERIOD_M3;  break;
                           case PERIOD_M4    : flags |= OBJ_PERIOD_M4;  break;
                           case PERIOD_M5    : flags |= OBJ_PERIOD_M5;  break;
                           case PERIOD_M6    : flags |= OBJ_PERIOD_M6;  break;
                           case PERIOD_M10   : flags |= OBJ_PERIOD_M10; break;
                           case PERIOD_M12   : flags |= OBJ_PERIOD_M12; break;
                           case PERIOD_M15   : flags |= OBJ_PERIOD_M15; break;
                           case PERIOD_M20   : flags |= OBJ_PERIOD_M20; break;
                           case PERIOD_M30   : flags |= OBJ_PERIOD_M30; break;
                           case PERIOD_H1    : flags |= OBJ_PERIOD_H1;  break;
                           case PERIOD_H2    : flags |= OBJ_PERIOD_H2;  break;
                           case PERIOD_H3    : flags |= OBJ_PERIOD_H3;  break;
                           case PERIOD_H4    : flags |= OBJ_PERIOD_H4;  break;
                           case PERIOD_H6    : flags |= OBJ_PERIOD_H6;  break;
                           case PERIOD_H8    : flags |= OBJ_PERIOD_H8;  break;
                           case PERIOD_H12   : flags |= OBJ_PERIOD_H12; break;
                           case PERIOD_D1    : flags |= OBJ_PERIOD_D1;  break;
                           case PERIOD_W1    : flags |= OBJ_PERIOD_W1;  break;
                           case PERIOD_MN1   : flags |= OBJ_PERIOD_MN1; break;
                           default           : return true;
                          }
                        ::ResetLastError();
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_TIMEFRAMES,flags))
                          {
                           this.m_timeframes_visible=flags;
                           return true;
                          }
                        else
                           CMessage::ToLog(DFUN,::GetLastError(),true);
                        return false;
                       }
//--- Set a subwindow index
   bool              SetSubwindow(const long chart_id,const string name)
                       {
                        ::ResetLastError();
                        this.m_subwindow=::ObjectFind(chart_id,name);
                        if(this.m_subwindow<0)
                           CMessage::ToLog(DFUN,MSG_GRAPH_STD_OBJ_ERR_NOT_FIND_SUBWINDOW);
                        return(this.m_subwindow>WRONG_VALUE);
                       }
   bool              SetSubwindow(void)
                       {
                        return this.SetSubwindow(this.m_chart_id,this.m_name);
                       }

//--- Return the values of class variables

接下来,添加返回类变量值的方法:

//--- Return the values of class variables
   ENUM_GRAPH_ELEMENT_TYPE TypeGraphElement(void)        const { return this.m_type_element;       }
   ENUM_GRAPH_OBJ_BELONG   Belong(void)                  const { return this.m_belong;             }
   ENUM_OBJECT       TypeGraphObject(void)               const { return this.m_type_graph_obj;     }
   datetime          TimeCreate(void)                    const { return this.m_create_time;        }
   string            Name(void)                          const { return this.m_name;               }
   long              ChartID(void)                       const { return this.m_chart_id;           }
   long              ObjectID(void)                      const { return this.m_object_id;          }
   long              Zorder(void)                        const { return this.m_zorder;             }
   int               SubWindow(void)                     const { return this.m_subwindow;          }
   int               ShiftY(void)                        const { return this.m_shift_y;            }
   int               VisibleOnTimeframes(void)           const { return this.m_timeframes_visible; }
   int               Digits(void)                        const { return this.m_digits;             }
   bool              IsBack(void)                        const { return this.m_back;               }
   bool              IsSelected(void)                    const { return this.m_selected;           }
   bool              IsSelectable(void)                  const { return this.m_selectable;         }
   bool              IsHidden(void)                      const { return this.m_hidden;             }
   bool              IsVisible(void)                     const { return this.m_visible;            }
//--- Return the object visibility flag on a specified timeframe
   bool              IsVisibleOnTimeframe(const ENUM_TIMEFRAMES timeframe) const
                       { return((this.m_timeframes_visible & timeframe)==timeframe);               }
//--- Return the graphical object type (ENUM_OBJECT) calculated from the object type (ENUM_OBJECT_DE_TYPE) passed to the method
   ENUM_OBJECT       GraphObjectType(const ENUM_OBJECT_DE_TYPE obj_type) const
                       { 
                        return ENUM_OBJECT(obj_type-OBJECT_DE_TYPE_GSTD_OBJ-1);
                       }
   
//--- Return the description of the graphical object type

所有方法都返回相应类变量中设置的值。

GraphObjectType() 方法根据对象类型值计算图形对象类型,从而可由函数库 ENUM_OBJECT_DE_TYPE 枚举类型来代表对象类型。

接下来,声明返回对象类型描述及其从属关系的方法

//--- Return the description of the type of the graphical (1) object, (2) element and (3) graphical object affiliation
string               TypeGraphObjectDescription(void);
string               TypeElementDescription(void);
string               BelongDescription(void);

//--- The virtual method returning the object type
   virtual int       Type(void)                          const { return this.m_type;               }

//--- Constructor/destructor
                     CGBaseObj();
                    ~CGBaseObj(){;}
  };
//+------------------------------------------------------------------+

在类构造函数中,为所有类变量设置默认值:

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CGBaseObj::CGBaseObj() : m_shift_y(0),m_visible(false), m_name_prefix(::MQLInfoString(MQL_PROGRAM_NAME)+"_"),m_belong(GRAPH_OBJ_BELONG_PROGRAM)
  {
   this.m_type=OBJECT_DE_TYPE_GBASE;            // Object type
   this.m_type_graph_obj=WRONG_VALUE;           // Graphical object type
   this.m_type_element=WRONG_VALUE;             // Graphical object type
   this.m_belong=WRONG_VALUE;                   // Program/terminal affiliation
   this.m_name_prefix="";                       // Object name prefix
   this.m_name="";                              // Object name
   this.m_chart_id=0;                           // Object chart ID
   this.m_object_id=0;                          // Object ID
   this.m_zorder=0;                             // Priority of a graphical object for receiving the mouse click event
   this.m_subwindow=0;                          // Subwindow index
   this.m_shift_y=0;                            // Subwindow Y coordinate shift
   this.m_timeframes_visible=OBJ_ALL_PERIODS;   // Visibility of an object on timeframes (a set of flags)
   this.m_visible=true;                         // Object visibility
   this.m_back=false;                           // "Background object" flag
   this.m_selected=false;                       // "Object selection" flag
   this.m_selectable=false;                     // "Object availability" flag
   this.m_hidden=true;                          // "Disable displaying the name of a graphical object in the terminal object list" flag
   this.m_create_time=0;                        // Object creation time
   
  }
//+------------------------------------------------------------------+

稍后,类的衍生后代将允许我们根据衍生后代类所描述的图形对象属性值来设置这些变量的准确值。

实现返回图形对象类型描述的方法:

//+------------------------------------------------------------------+
//| Return the description of the graphical object type              |
//+------------------------------------------------------------------+
string CGBaseObj::TypeGraphObjectDescription(void)
  {
   if(this.TypeGraphElement()==GRAPH_ELEMENT_TYPE_STANDART)
      return StdGraphObjectTypeDescription(this.m_type_graph_obj);
   else
      return this.TypeElementDescription();
  }
//+------------------------------------------------------------------+

此处我们首先定义图形对象所属的图形元素类型。 如果这是一个标准图形对象调用我在上面讲述过的 StdGraphObjectTypeDescription() 服务函数返回它的描述
否则,调用下面研究的 TypeElementDescription() 方法,返回图形元素类型的描述

//+------------------------------------------------------------------+
//| Return the description of the graphical element type             |
//+------------------------------------------------------------------+
string CGBaseObj::TypeElementDescription(void)
  {
   return
     (
      this.TypeGraphElement()==GRAPH_ELEMENT_TYPE_STANDART     ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_STANDART)     :
      this.TypeGraphElement()==GRAPH_ELEMENT_TYPE_ELEMENT      ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_ELEMENT)      :
      this.TypeGraphElement()==GRAPH_ELEMENT_TYPE_SHADOW_OBJ   ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_SHADOW_OBJ)   :
      this.TypeGraphElement()==GRAPH_ELEMENT_TYPE_FORM         ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_FORM)         :
      this.TypeGraphElement()==GRAPH_ELEMENT_TYPE_WINDOW       ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WINDOW)       :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

返回图形对象隶属关系描述的方法:

//+------------------------------------------------------------------+
//| Return the description of the graphical object affiliation       |
//+------------------------------------------------------------------+
string CGBaseObj::BelongDescription(void)
  {
   return
     (
      this.Belong()==GRAPH_OBJ_BELONG_PROGRAM      ? CMessage::Text(MSG_GRAPH_OBJ_BELONG_PROGRAM)     :
      this.Belong()==GRAPH_OBJ_BELONG_NO_PROGRAM   ? CMessage::Text(MSG_GRAPH_OBJ_BELONG_NO_PROGRAM)  :
      "Unknown"
     );
  }
//+------------------------------------------------------------------+

后两种方法的逻辑类似于上面讲述过的服务函数的逻辑。


抽象图形对象类

我们已经贯穿了所有准备阶段。 现在我们创建抽象图形对象类。

在 \MQL5\Include\DoEasy\Objects\Graph\ 中,创建 Standart\ 文件夹,并含 CGStdGraphObj 类的新文件 GStdGraphObj.mqh

该类应该派生自所有 CGBaseObj 函数库图形对象的基准图形对象类。 图形对象文件也应该包含在所创建的类的新文件之中

//+------------------------------------------------------------------+
//|                                                 GStdGraphObj.mqh |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "..\GBaseObj.mqh"
//+------------------------------------------------------------------+
//| The class of the abstract standard graphical object              |
//+------------------------------------------------------------------+
class CGStdGraphObj : public CGBaseObj
  {
  }

在类的私密部分,放置存储对象属性的数组,和返回相应数组中实数型属性索引的方法:

//+------------------------------------------------------------------+
//| The class of the abstract standard graphical object              |
//+------------------------------------------------------------------+
class CGStdGraphObj : public CGBaseObj
  {
private:

   long              m_long_prop[GRAPH_OBJ_PROP_INTEGER_TOTAL];      // Integer properties
   double            m_double_prop[GRAPH_OBJ_PROP_DOUBLE_TOTAL];     // Real properties
   string            m_string_prop[GRAPH_OBJ_PROP_STRING_TOTAL];     // String properties

//--- Return the index of the array the (1) double and (2) string properties are actually located at
   int               IndexProp(ENUM_GRAPH_OBJ_PROP_DOUBLE property)  const { return(int)property-GRAPH_OBJ_PROP_INTEGER_TOTAL;                              }
   int               IndexProp(ENUM_GRAPH_OBJ_PROP_STRING property)  const { return(int)property-GRAPH_OBJ_PROP_INTEGER_TOTAL-GRAPH_OBJ_PROP_DOUBLE_TOTAL;  }

public:

在类的公开部分,为所有函数库对象设置标准方法,以及两个构造函数 — 默认的和参数型各一个:

public:
//--- Set object's (1) integer, (2) real and (3) string properties
   void              SetProperty(ENUM_GRAPH_OBJ_PROP_INTEGER property,long value)   { this.m_long_prop[property]=value;                      }
   void              SetProperty(ENUM_GRAPH_OBJ_PROP_DOUBLE property,double value)  { this.m_double_prop[this.IndexProp(property)]=value;    }
   void              SetProperty(ENUM_GRAPH_OBJ_PROP_STRING property,string value)  { this.m_string_prop[this.IndexProp(property)]=value;    }
//--- Return object’s (1) integer, (2) real and (3) string property from the properties array
   long              GetProperty(ENUM_GRAPH_OBJ_PROP_INTEGER property)        const { return this.m_long_prop[property];                     }
   double            GetProperty(ENUM_GRAPH_OBJ_PROP_DOUBLE property)         const { return this.m_double_prop[this.IndexProp(property)];   }
   string            GetProperty(ENUM_GRAPH_OBJ_PROP_STRING property)         const { return this.m_string_prop[this.IndexProp(property)];   }
//--- Return itself
   CGStdGraphObj    *GetObject(void)                                                { return &this;}

//--- Return the flag of the object supporting this property
   virtual bool      SupportProperty(ENUM_GRAPH_OBJ_PROP_INTEGER property)          { return true; }
   virtual bool      SupportProperty(ENUM_GRAPH_OBJ_PROP_DOUBLE property)           { return true; }
   virtual bool      SupportProperty(ENUM_GRAPH_OBJ_PROP_STRING property)           { return true; }

//--- Get description of (1) integer, (2) real and (3) string properties
   string            GetPropertyDescription(ENUM_GRAPH_OBJ_PROP_INTEGER property);
   string            GetPropertyDescription(ENUM_GRAPH_OBJ_PROP_DOUBLE property);
   string            GetPropertyDescription(ENUM_GRAPH_OBJ_PROP_STRING property);

//--- Return the description of the graphical object anchor point position
   virtual string    AnchorDescription(void)                                  const { return (string)this.GetProperty(GRAPH_OBJ_PROP_ANCHOR);}

//--- Display the description of the object properties in the journal (full_prop=true - all properties, false - supported ones only - implemented in descendant classes)
   virtual void      Print(const bool full_prop=false,const bool dash=false);
//--- Display a short description of the object in the journal
   virtual void      PrintShort(const bool dash=false,const bool symbol=false);
//--- Return the object short name
   virtual string    Header(const bool symbol=false);
  
//--- Compare CGStdGraphObj objects by a specified property (to sort the list by an object property)
   virtual int       Compare(const CObject *node,const int mode=0) const;
//--- Compare CGStdGraphObj objects with each other by all properties (to search for equal objects)
   bool              IsEqual(CGStdGraphObj* compared_req) const;
   
//--- Default constructor
                     CGStdGraphObj(){ this.m_type=OBJECT_DE_TYPE_GSTD_OBJ;  }
protected:
//--- Protected parametric constructor
                     CGStdGraphObj(const ENUM_OBJECT_DE_TYPE obj_type,const ENUM_GRAPH_OBJ_BELONG belong,const long chart_id,const string name);
                     
public:
//+--------------------------------------------------------------------+ 
//|Methods of simplified access and setting graphical object properties|
//+--------------------------------------------------------------------+

在此情况下,返回图形对象锚点位置描述的方法会返回一个数字,而非描述本身。 用不同枚举指定的锚点代表不同的对象。 因此,该方法定义为虚拟化,并需在含有此类属性的衍生后代对象中重新定义。

接下来,在类代码里添加设置和返回对象属性的简化访问方法:

public:
//+--------------------------------------------------------------------+ 
//|Methods of simplified access and setting graphical object properties|
//+--------------------------------------------------------------------+
//--- Object index in the list
   int               Number(void)                  const { return (int)this.GetProperty(GRAPH_OBJ_PROP_NUM);                              }
   void              SetNumber(const int number)         { this.SetProperty(GRAPH_OBJ_PROP_NUM,number);                                   }
//--- Object ID
   long              ObjectID(void)                const { return this.GetProperty(GRAPH_OBJ_PROP_ID);                                    }
   void              SetObjectID(const long obj_id)
                       {
                        CGBaseObj::SetObjectID(obj_id);
                        this.SetProperty(GRAPH_OBJ_PROP_ID,obj_id);
                       }
//--- Graphical object type
   ENUM_OBJECT       GraphObjectType(void)         const { return (ENUM_OBJECT)this.GetProperty(GRAPH_OBJ_PROP_TYPE);                     }
   void              SetGraphObjectType(const ENUM_OBJECT obj_type)
                       {
                        CGBaseObj::SetTypeGraphObject(obj_type);
                        this.SetProperty(GRAPH_OBJ_PROP_TYPE,obj_type);
                       }
//--- Graphical element type
   ENUM_GRAPH_ELEMENT_TYPE GraphElementType(void)  const { return (ENUM_GRAPH_ELEMENT_TYPE)this.GetProperty(GRAPH_OBJ_PROP_ELEMENT_TYPE); }
   void              SetGraphElementType(const ENUM_GRAPH_ELEMENT_TYPE elm_type)
                       {
                        CGBaseObj::SetTypeElement(elm_type);
                        this.SetProperty(GRAPH_OBJ_PROP_ELEMENT_TYPE,elm_type);
                       }
//--- Graphical object affiliation
   ENUM_GRAPH_OBJ_BELONG Belong(void)              const { return (ENUM_GRAPH_OBJ_BELONG)this.GetProperty(GRAPH_OBJ_PROP_BELONG);         }
   void              SetBelong(const ENUM_GRAPH_OBJ_BELONG belong)
                       {
                        CGBaseObj::SetBelong(belong);
                        this.SetProperty(GRAPH_OBJ_PROP_BELONG,belong);
                       }
//--- Chart ID
   long              ChartID(void)                 const { return this.GetProperty(GRAPH_OBJ_PROP_CHART_ID);                              }
   void              SetChartID(const long chart_id)
                       {
                        CGBaseObj::SetChartID(chart_id);
                        this.SetProperty(GRAPH_OBJ_PROP_CHART_ID,chart_id);
                       }
//--- Chart subwindow index
   int               SubWindow(void)               const { return (int)this.GetProperty(GRAPH_OBJ_PROP_WND_NUM);                          }
   void              SetSubWindow(void)
                       {
                        if(CGBaseObj::SetSubwindow(CGBaseObj::ChartID(),CGBaseObj::Name()))
                           this.SetProperty(GRAPH_OBJ_PROP_WND_NUM,CGBaseObj::SubWindow());
                       }
//--- Object creation time
   datetime          TimeCteate(void)              const { return (datetime)this.GetProperty(GRAPH_OBJ_PROP_CREATETIME);                  }
//--- Object visibility on timeframes
   bool              Visible(void)                 const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES);                      }
   void              SetFlagVisible(const bool flag)
                       {
                        if(CGBaseObj::SetVisible(flag))
                           this.SetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,flag);
                       }
//--- Background object
   bool              Back(void)                    const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_BACK);                            }
   void              SetFlagBack(const bool flag)
                       {
                        if(CGBaseObj::SetBack(flag))
                           this.SetProperty(GRAPH_OBJ_PROP_BACK,flag);
                       }
//--- Priority of a graphical object for receiving the event of clicking on a chart
   long              Zorder(void)                  const { return this.GetProperty(GRAPH_OBJ_PROP_ZORDER);                                }
   void              SetZorder(const long value)
                       {
                        if(CGBaseObj::SetZorder(value))
                           this.SetProperty(GRAPH_OBJ_PROP_ZORDER,value);
                       }
//--- Disable displaying the name of a graphical object in the terminal object list
   bool              Hidden(void)                  const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_HIDDEN);                          }
   void              SetFlagHidden(const bool flag)
                       {
                        if(CGBaseObj::SetHidden(flag))
                           this.SetProperty(GRAPH_OBJ_PROP_HIDDEN,flag);
                       }
//--- Object selection
   bool              Selected(void)                const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_SELECTED);                        }
   void              SetFlagSelected(const bool flag)
                       {
                        if(CGBaseObj::SetSelected(flag))
                           this.SetProperty(GRAPH_OBJ_PROP_SELECTED,flag);
                       }
//--- Object availability
   bool              Selectable(void)              const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_SELECTABLE);                      }
   void              SetFlagSelectable(const bool flag)
                       {
                        if(CGBaseObj::SetSelectable(flag))
                           this.SetProperty(GRAPH_OBJ_PROP_SELECTABLE,flag);
                       }
//--- Time coordinate
   datetime          Time(void)                    const { return (datetime)this.GetProperty(GRAPH_OBJ_PROP_TIME);                        }
   void              SetTime(const datetime time)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_TIME,time))
                           this.SetProperty(GRAPH_OBJ_PROP_TIME,time);
                       }
//--- Color
   color             Color(void)                   const { return (color)this.GetProperty(GRAPH_OBJ_PROP_COLOR);                          }
   void              SetColor(const color colour)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_COLOR,colour))
                           this.SetProperty(GRAPH_OBJ_PROP_COLOR,colour);
                       }
//--- Style
   ENUM_LINE_STYLE   Style(void)                   const { return (ENUM_LINE_STYLE)this.GetProperty(GRAPH_OBJ_PROP_STYLE);                }
   void              SetStyle(const ENUM_LINE_STYLE style)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_STYLE,style))
                           this.SetProperty(GRAPH_OBJ_PROP_STYLE,style);
                       }
//--- Line width
   int               Width(void)                   const { return (int)this.GetProperty(GRAPH_OBJ_PROP_WIDTH);                            }
   void              SetWidth(const int width)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_WIDTH,width))
                           this.SetProperty(GRAPH_OBJ_PROP_WIDTH,width);
                       }
//--- Object color filling
   bool              Fill(void)                    const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_FILL);                            }
   void              SetFlagFill(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_FILL,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_FILL,flag);
                       }
//--- Ability to edit text in the Edit object
   bool              ReadOnly(void)                const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_READONLY);                        }
   void              SetFlagReadOnly(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_READONLY,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_READONLY,flag);
                       }
//--- Number of levels
   int               Levels(void)                  const { return (int)this.GetProperty(GRAPH_OBJ_PROP_LEVELS);                           }
   void              SetLevels(const int levels)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_LEVELS,levels))
                           this.SetProperty(GRAPH_OBJ_PROP_LEVELS,levels);
                       }
//--- Line level color
   color             LevelColor(void)              const { return (color)this.GetProperty(GRAPH_OBJ_PROP_LEVELCOLOR);                     }
   void              SetLevelColor(const color colour)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_LEVELCOLOR,colour))
                           this.SetProperty(GRAPH_OBJ_PROP_LEVELCOLOR,colour);
                       }
//--- Level line style
   ENUM_LINE_STYLE   LevelStyle(void)              const { return (ENUM_LINE_STYLE)this.GetProperty(GRAPH_OBJ_PROP_LEVELSTYLE);           }
   void              SetLevelStyle(const ENUM_LINE_STYLE style)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_LEVELSTYLE,style))
                           this.SetProperty(GRAPH_OBJ_PROP_LEVELSTYLE,style);
                       }
///--- Level line width
   int               LevelWidth(void)              const { return (int)this.GetProperty(GRAPH_OBJ_PROP_LEVELWIDTH);                       }
   void              SetLevelWidth(const int width)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_LEVELWIDTH,width))
                           this.SetProperty(GRAPH_OBJ_PROP_LEVELWIDTH,width);
                       }
//--- Horizontal text alignment in the Edit object (OBJ_EDIT)
   ENUM_ALIGN_MODE   Align(void)                   const { return (ENUM_ALIGN_MODE)this.GetProperty(GRAPH_OBJ_PROP_ALIGN);                }
   void              SetAlign(const ENUM_ALIGN_MODE align)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_ALIGN,align))
                           this.SetProperty(GRAPH_OBJ_PROP_ALIGN,align);
                       }
//--- Font size
   int               FontSize(void)                const { return (int)this.GetProperty(GRAPH_OBJ_PROP_FONTSIZE);                         }
   void              SetFontSize(const int size)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_FONTSIZE,size))
                           this.SetProperty(GRAPH_OBJ_PROP_FONTSIZE,size);
                       }
//--- Ray goes to the left
   bool              RayLeft(void)                 const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_RAY_LEFT);                        }
   void              SetFlagRayLeft(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_RAY_LEFT,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_RAY_LEFT,flag);
                       }
//--- Ray goes to the right
   bool              RayRight(void)                const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_RAY_RIGHT);                       }
   void              SetFlagRayRight(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_RAY_RIGHT,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_RAY_RIGHT,flag);
                       }
//--- Vertical line goes through all windows of a chart
   bool              Ray(void)                     const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_RAY);                             }
   void              SetFlagRay(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_RAY,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_RAY,flag);
                       }
//--- Display the full ellipse of the Fibonacci Arc object
   bool              Ellipse(void)                 const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_ELLIPSE);                         }
   void              SetFlagEllipse(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_ELLIPSE,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_ELLIPSE,flag);
                       }
//--- Arrow code for the "Arrow" object
   uchar             ArrowCode(void)               const { return (uchar)this.GetProperty(GRAPH_OBJ_PROP_ARROWCODE);                      }
   void              SetArrowCode(const uchar code)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_ARROWCODE,code))
                           this.SetProperty(GRAPH_OBJ_PROP_ARROWCODE,code);
                       }
//--- Position of the graphical object anchor point
   int               Anchor(void)                  const { return (int)this.GetProperty(GRAPH_OBJ_PROP_ANCHOR);                           }
   void              SetAnchor(const int anchor)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_ANCHOR,anchor))
                           this.SetProperty(GRAPH_OBJ_PROP_ANCHOR,anchor);
                       }
//--- Distance from the base corner along the X axis in pixels
   int               XDistance(void)               const { return (int)this.GetProperty(GRAPH_OBJ_PROP_XDISTANCE);                        }
   void              SetXDistance(const int distance)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_XDISTANCE,distance))
                           this.SetProperty(GRAPH_OBJ_PROP_XDISTANCE,distance);
                       }
//--- Distance from the base corner along the Y axis in pixels
   int               YDistance(void)               const { return (int)this.GetProperty(GRAPH_OBJ_PROP_YDISTANCE);                        }
   void              SetYDistance(const int distance)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_YDISTANCE,distance))
                           this.SetProperty(GRAPH_OBJ_PROP_YDISTANCE,distance);
                       }
//--- Gann object trend
   ENUM_GANN_DIRECTION Direction(void)             const { return (ENUM_GANN_DIRECTION)this.GetProperty(GRAPH_OBJ_PROP_DIRECTION);        }
   void              SetDirection(const ENUM_GANN_DIRECTION direction)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_DIRECTION,direction))
                           this.SetProperty(GRAPH_OBJ_PROP_DIRECTION,direction);
                       }
//--- Elliott wave marking level
   ENUM_ELLIOT_WAVE_DEGREE Degree(void)            const { return (ENUM_ELLIOT_WAVE_DEGREE)this.GetProperty(GRAPH_OBJ_PROP_DEGREE);       }
   void              SetDegree(const ENUM_ELLIOT_WAVE_DEGREE degree)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_DEGREE,degree))
                           this.SetProperty(GRAPH_OBJ_PROP_DEGREE,degree);
                       }
//--- Display lines for Elliott wave marking
   bool              DrawLines(void)               const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_DRAWLINES);                       }
   void              SetFlagDrawLines(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_DRAWLINES,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_DRAWLINES,flag);
                       }
//--- Button state (pressed/released)
   bool              State(void)                   const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_STATE);                           }
   void              SetFlagState(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_STATE,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_STATE,flag);
                       }
//--- Chart object ID (OBJ_CHART)
   long              ChartObjChartID(void)         const { return this.GetProperty(GRAPH_OBJ_PROP_OBJ_CHART_ID);                          }
   void              SetChartObjChartID(const long chart_id)
                       {
                        this.SetProperty(GRAPH_OBJ_PROP_OBJ_CHART_ID,chart_id);
                       }
//--- Chart object period
   ENUM_TIMEFRAMES   ChartObjPeriod(void)          const { return (ENUM_TIMEFRAMES)this.GetProperty(GRAPH_OBJ_PROP_CHART_OBJ_PERIOD);     }
   void              SetChartObjPeriod(const ENUM_TIMEFRAMES timeframe)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_PERIOD,timeframe))
                           this.SetProperty(GRAPH_OBJ_PROP_CHART_OBJ_PERIOD,timeframe);
                       }
//--- Time scale display flag for the Chart object
   bool              ChartObjDateScale(void)       const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_CHART_OBJ_DATE_SCALE);            }
   void              SetFlagChartObjDateScale(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_DATE_SCALE,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_CHART_OBJ_DATE_SCALE,flag);
                       }
//--- Price scale display flag for the Chart object
   bool              ChartObjPriceScale(void)      const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_CHART_OBJ_PRICE_SCALE);           }
   void              SetFlagPriceScale(const bool flag)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_PRICE_SCALE,flag))
                           this.SetProperty(GRAPH_OBJ_PROP_CHART_OBJ_PRICE_SCALE,flag);
                       }
//--- Chart object scale
   int               ChartObjChartScale(void)      const { return (int)this.GetProperty(GRAPH_OBJ_PROP_CHART_OBJ_CHART_SCALE);            }
   void              SetChartObjChartScale(const int scale)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_CHART_SCALE,scale))
                           this.SetProperty(GRAPH_OBJ_PROP_CHART_OBJ_CHART_SCALE,scale);
                       }
//--- Object width along the X axis in pixels
   int               XSize(void)                   const { return (int)this.GetProperty(GRAPH_OBJ_PROP_XSIZE);                            }
   void              SetXSize(const int size)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_XSIZE,size))
                           this.SetProperty(GRAPH_OBJ_PROP_XSIZE,size);
                       }
//--- Object height along the Y axis in pixels
   int               YSize(void)                   const { return (int)this.GetProperty(GRAPH_OBJ_PROP_YSIZE);                            }
   void              SetYSize(const int size)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_YSIZE,size))
                           this.SetProperty(GRAPH_OBJ_PROP_YSIZE,size);
                       }
//--- X coordinate of the upper-left corner of the visibility area
   int               XOffset(void)                 const { return (int)this.GetProperty(GRAPH_OBJ_PROP_XOFFSET);                          }
   void              SetXOffset(const int offset)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_XOFFSET,offset))
                           this.SetProperty(GRAPH_OBJ_PROP_XOFFSET,offset);
                       }
//--- Y coordinate of the upper-left corner of the visibility area
   int               YOffset(void)                 const { return (int)this.GetProperty(GRAPH_OBJ_PROP_YOFFSET);                          }
   void              SetYOffset(const int offset)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_YOFFSET,offset))
                           this.SetProperty(GRAPH_OBJ_PROP_YOFFSET,offset);
                       }
//--- Background color for OBJ_EDIT, OBJ_BUTTON, OBJ_RECTANGLE_LABEL
   color             BGColor(void)                 const { return (color)this.GetProperty(GRAPH_OBJ_PROP_BGCOLOR);                        }
   void              SetBGColor(const color colour)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_BGCOLOR,colour))
                           this.SetProperty(GRAPH_OBJ_PROP_BGCOLOR,colour);
                       }
//--- Chart corner for attaching a graphical object
   ENUM_BASE_CORNER  Corner(void)                  const { return (ENUM_BASE_CORNER)this.GetProperty(GRAPH_OBJ_PROP_CORNER);              }
   void              SetCorner(const ENUM_BASE_CORNER corner)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_CORNER,corner))
                           this.SetProperty(GRAPH_OBJ_PROP_CORNER,corner);
                       }
//--- Border type for the Rectangle label object
   ENUM_BORDER_TYPE  BorderType(void)              const { return (ENUM_BORDER_TYPE)this.GetProperty(GRAPH_OBJ_PROP_BORDER_TYPE);         }
   void              SetBorderType(const ENUM_BORDER_TYPE type)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_BORDER_TYPE,type))
                           this.SetProperty(GRAPH_OBJ_PROP_BORDER_TYPE,type);
                       }
//--- Border color for OBJ_EDIT and OBJ_BUTTON
   color             BorderColor(void)             const { return (color)this.GetProperty(GRAPH_OBJ_PROP_BORDER_COLOR);                   }
   void              SetBorderColor(const color colour)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_BORDER_COLOR,colour))
                           this.SetProperty(GRAPH_OBJ_PROP_BORDER_COLOR,colour);
                       }

//--- Price coordinate
   double            Price(void)                   const { return this.GetProperty(GRAPH_OBJ_PROP_PRICE);                                 }
   void              SetPrice(const double price)
                       {
                        if(::ObjectSetDouble(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_PRICE,price))
                           this.SetProperty(GRAPH_OBJ_PROP_PRICE,price);
                       }
//--- Level value
   double            LevelValue(void)              const { return this.GetProperty(GRAPH_OBJ_PROP_LEVELVALUE);                            }
   void              SetLevelValue(const double value)
                       {
                        if(::ObjectSetDouble(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_LEVELVALUE,value))
                           this.SetProperty(GRAPH_OBJ_PROP_LEVELVALUE,value);
                       }
//--- Scale
   double            Scale(void)                   const { return this.GetProperty(GRAPH_OBJ_PROP_SCALE);                                 }
   void              SetScale(const double scale)
                       {
                        if(::ObjectSetDouble(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_SCALE,scale))
                           this.SetProperty(GRAPH_OBJ_PROP_SCALE,scale);
                       }
//--- Angle
   double            Angle(void)                   const { return this.GetProperty(GRAPH_OBJ_PROP_ANGLE);                                 }
   void              SetAngle(const double angle)
                       {
                        if(::ObjectSetDouble(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_ANGLE,angle))
                           this.SetProperty(GRAPH_OBJ_PROP_ANGLE,angle);
                       }
//--- Deviation of the standard deviation channel
   double            Deviation(void)               const { return this.GetProperty(GRAPH_OBJ_PROP_DEVIATION);                             }
   void              SetDeviation(const double deviation)
                       {
                        if(::ObjectSetDouble(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_DEVIATION,deviation))
                           this.SetProperty(GRAPH_OBJ_PROP_DEVIATION,deviation);
                       }

//--- Object name
   string            Name(void)                    const { return this.GetProperty(GRAPH_OBJ_PROP_NAME);                                  }
   void              SetName(const string name)
                       {
                        if(CGBaseObj::Name()==name)
                           return;
                        if(CGBaseObj::Name()=="")
                          {
                           CGBaseObj::SetName(name);
                           this.SetProperty(GRAPH_OBJ_PROP_NAME,name);
                           return;
                          }
                        else
                          {
                           if(::ObjectSetString(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_NAME,name))
                             {
                              CGBaseObj::SetName(name);
                              this.SetProperty(GRAPH_OBJ_PROP_NAME,name);
                             }
                          }
                       }
//--- Object description (text contained in the object)
   string            Text(void)                    const { return this.GetProperty(GRAPH_OBJ_PROP_TEXT);                                  }
   void              SetText(const string text)
                       {
                        if(::ObjectSetString(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_TEXT,text))
                           this.SetProperty(GRAPH_OBJ_PROP_TEXT,text);
                       }
//--- Tooltip text
   string            Tooltip(void)                 const { return this.GetProperty(GRAPH_OBJ_PROP_TOOLTIP);                               }
   void              SetTooltip(const string tooltip)
                       {
                        if(::ObjectSetString(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_TOOLTIP,tooltip))
                           this.SetProperty(GRAPH_OBJ_PROP_TOOLTIP,tooltip);
                       }
//--- Level description
   string            LevelText(void)               const { return this.GetProperty(GRAPH_OBJ_PROP_LEVELTEXT);                             }
   void              SetLevelText(const string text)
                       {
                        if(::ObjectSetString(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_LEVELTEXT,text))
                           this.SetProperty(GRAPH_OBJ_PROP_LEVELTEXT,text);
                       }
//--- Font
   string            Font(void)                    const { return this.GetProperty(GRAPH_OBJ_PROP_FONT);                                  }
   void              SetFont(const string font)
                       {
                        if(::ObjectSetString(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_FONT,font))
                           this.SetProperty(GRAPH_OBJ_PROP_FONT,font);
                       }
//--- BMP file name for the "Bitmap Level" object
   string            BMPFile(void)                 const { return this.GetProperty(GRAPH_OBJ_PROP_BMPFILE);                               }
   void              SetBMPFile(const string bmp_file)
                       {
                        if(::ObjectSetString(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_BMPFILE,bmp_file))
                           this.SetProperty(GRAPH_OBJ_PROP_BMPFILE,bmp_file);
                       }
//--- Symbol for the Chart object 
   string            Symbol(void)                  const { return this.GetProperty(GRAPH_OBJ_PROP_CHART_OBJ_SYMBOL);                      }
   void              SetChartObjSymbol(const string symbol)
                       {
                        if(::ObjectSetString(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_SYMBOL,symbol))
                           this.SetProperty(GRAPH_OBJ_PROP_CHART_OBJ_SYMBOL,symbol);
                       }
   
  };
//+------------------------------------------------------------------+

此处已预先设置了很多方法。 稍后,它们将被移到拥有相应属性的衍生后代对象类之中。 因此,不同的对象应拥有处理各自属性的单独方法集合。

我们以若干种方法为例来研究逻辑。

对象固有的属性直接从对象属性返回和设置:

//--- Object index in the list
   int               Number(void)                  const { return (int)this.GetProperty(GRAPH_OBJ_PROP_NUM);                              }
   void              SetNumber(const int number)         { this.SetProperty(GRAPH_OBJ_PROP_NUM,number);                                   }


所有图形对象固有的属性,其存储变量位于所有函数库图形对象的基准图形对象类当中,可从对象属性返回首先要设置基准对象之后是对象属性

//--- Object ID
   long              ObjectID(void)                const { return this.GetProperty(GRAPH_OBJ_PROP_ID);                                    }
   void              SetObjectID(const long obj_id)
                       {
                        CGBaseObj::SetObjectID(obj_id);
                        this.SetProperty(GRAPH_OBJ_PROP_ID,obj_id);
                       }


图形对象中固有,但基准对象中不存在的属性,直接从对象属性返回,并在图形对象属性中初始设置如果属性变更事件成功排队也会在对象属性中设置

//--- Time coordinate
   datetime          Time(void)                    const { return (datetime)this.GetProperty(GRAPH_OBJ_PROP_TIME);                        }
   void              SetTime(const datetime time)
                       {
                        if(::ObjectSetInteger(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_TIME,time))
                           this.SetProperty(GRAPH_OBJ_PROP_TIME,time);
                       }


名称设置方法与其它类似方法不同。 在终端中依据列表索引和对象名称选择图形对象(ObjectName() 函数依据对象列表中的索引获取对象名称,而 ObjectGetXXX() 函数随后依据图形对象名称接收其余属性)。 在创建对象后立即为其分配名称。

相应地,我们在此只需要将名称赋值给对象变量。 仅在变量中尚未设置名称时我们才需这样做。 如果已经给变量设置了名称,并且设置的名称与现有的不匹配如果匹配,则退出方法),这意味着为对象重命名。 此处尚未处理这种情况。 现在,我们只需发送一个图形对象重命名的请求,并在基类变量和当前变量的属性中重新命名。
//--- Object name
   string            Name(void)                    const { return this.GetProperty(GRAPH_OBJ_PROP_NAME);                                  }
   void              SetName(const string name)
                       {
                        if(CGBaseObj::Name()==name)
                           return;
                        if(CGBaseObj::Name()=="")
                          {
                           CGBaseObj::SetName(name);
                           this.SetProperty(GRAPH_OBJ_PROP_NAME,name);
                           return;
                          }
                        else
                          {
                           if(::ObjectSetString(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_NAME,name))
                             {
                              CGBaseObj::SetName(name);
                              this.SetProperty(GRAPH_OBJ_PROP_NAME,name);
                             }
                          }
                       }


在受保护的参数型构造函数中,设置了所有数值,并传递给构造函数,为基类和对象属性赋值:

//+------------------------------------------------------------------+
//| Protected parametric constructor                                 |
//+------------------------------------------------------------------+
CGStdGraphObj::CGStdGraphObj(const ENUM_OBJECT_DE_TYPE obj_type,const ENUM_GRAPH_OBJ_BELONG belong,const long chart_id,const string name)
  {
//--- Set the object (1) type, type of graphical (2) object, (3) element, (4) subwindow affiliation and (5) index, as well as (6) chart symbol Digits
   this.m_type=obj_type;
   CGBaseObj::SetChartID(chart_id);
   CGBaseObj::SetTypeGraphObject(CGBaseObj::GraphObjectType(obj_type));
   CGBaseObj::SetTypeElement(GRAPH_ELEMENT_TYPE_STANDART);
   CGBaseObj::SetBelong(belong);
   CGBaseObj::SetSubwindow(chart_id,name);
   CGBaseObj::SetDigits((int)::SymbolInfoInteger(::ChartSymbol(chart_id),SYMBOL_DIGITS));
   
//--- Save integer properties
   //--- properties inherent in all graphical objects but not present in a graphical object
   this.m_long_prop[GRAPH_OBJ_PROP_CHART_ID]    = CGBaseObj::ChartID();          // Chart ID

   this.m_long_prop[GRAPH_OBJ_PROP_WND_NUM]     = CGBaseObj::SubWindow();        // Chart subwindow index
   this.m_long_prop[GRAPH_OBJ_PROP_TYPE]        = CGBaseObj::TypeGraphObject();  // Graphical object type (ENUM_OBJECT)
   this.m_long_prop[GRAPH_OBJ_PROP_ELEMENT_TYPE]= CGBaseObj::TypeGraphElement(); // Graphical element type (ENUM_GRAPH_ELEMENT_TYPE)
   this.m_long_prop[GRAPH_OBJ_PROP_BELONG]      = CGBaseObj::Belong();           // Graphical object affiliation
   this.m_long_prop[GRAPH_OBJ_PROP_ID]          = 0;                             // Object ID
   this.m_long_prop[GRAPH_OBJ_PROP_NUM]         = 0;                             // Object index in the list
   //--- Properties inherent in all graphical objects and present in a graphical object
   this.m_long_prop[GRAPH_OBJ_PROP_CREATETIME]  = ::ObjectGetInteger(chart_id,name,OBJPROP_CREATETIME);  // Object creation time
   this.m_long_prop[GRAPH_OBJ_PROP_TIMEFRAMES]  = ::ObjectGetInteger(chart_id,name,OBJPROP_TIMEFRAMES);  // Object visibility on timeframes
   this.m_long_prop[GRAPH_OBJ_PROP_BACK]        = ::ObjectGetInteger(chart_id,name,OBJPROP_BACK);        // Background object
   this.m_long_prop[GRAPH_OBJ_PROP_ZORDER]      = ::ObjectGetInteger(chart_id,name,OBJPROP_ZORDER);      // Priority of a graphical object for receiving the event of clicking on a chart
   this.m_long_prop[GRAPH_OBJ_PROP_HIDDEN]      = ::ObjectGetInteger(chart_id,name,OBJPROP_HIDDEN);      // Disable displaying the name of a graphical object in the terminal object list
   this.m_long_prop[GRAPH_OBJ_PROP_SELECTED]    = ::ObjectGetInteger(chart_id,name,OBJPROP_SELECTED);    // Object selection
   this.m_long_prop[GRAPH_OBJ_PROP_SELECTABLE]  = ::ObjectGetInteger(chart_id,name,OBJPROP_SELECTABLE);  // Object availability
   this.m_long_prop[GRAPH_OBJ_PROP_TIME]        = ::ObjectGetInteger(chart_id,name,OBJPROP_TIME);        // First point time coordinate
   this.m_long_prop[GRAPH_OBJ_PROP_COLOR]       = ::ObjectGetInteger(chart_id,name,OBJPROP_COLOR);       // Color
   this.m_long_prop[GRAPH_OBJ_PROP_STYLE]       = ::ObjectGetInteger(chart_id,name,OBJPROP_STYLE);       // Style
   this.m_long_prop[GRAPH_OBJ_PROP_WIDTH]       = ::ObjectGetInteger(chart_id,name,OBJPROP_WIDTH);       // Line width
   //--- Properties belonging to different graphical objects
   this.m_long_prop[GRAPH_OBJ_PROP_FILL]                          = 0;  // Object color filling
   this.m_long_prop[GRAPH_OBJ_PROP_READONLY]                      = 0;  // Ability to edit text in the Edit object
   this.m_long_prop[GRAPH_OBJ_PROP_LEVELS]                        = 0;  // Number of levels
   this.m_long_prop[GRAPH_OBJ_PROP_LEVELCOLOR]                    = 0;  // Level line color
   this.m_long_prop[GRAPH_OBJ_PROP_LEVELSTYLE]                    = 0;  // Level line style
   this.m_long_prop[GRAPH_OBJ_PROP_LEVELWIDTH]                    = 0;  // Level line width
   this.m_long_prop[GRAPH_OBJ_PROP_ALIGN]                         = 0;  // Horizontal text alignment in the Edit object (OBJ_EDIT)
   this.m_long_prop[GRAPH_OBJ_PROP_FONTSIZE]                      = 0;  // Font size
   this.m_long_prop[GRAPH_OBJ_PROP_RAY_LEFT]                      = 0;  // Ray goes to the left
   this.m_long_prop[GRAPH_OBJ_PROP_RAY_RIGHT]                     = 0;  // Ray goes to the right
   this.m_long_prop[GRAPH_OBJ_PROP_RAY]                           = 0;  // Vertical line goes through all windows of a chart
   this.m_long_prop[GRAPH_OBJ_PROP_ELLIPSE]                       = 0;  // Display the full ellipse of the Fibonacci Arc object
   this.m_long_prop[GRAPH_OBJ_PROP_ARROWCODE]                     = 0;  // Arrow code for the "Arrow" object
   this.m_long_prop[GRAPH_OBJ_PROP_ANCHOR]                        = 0;  // Position of the binding point of the graphical object
   this.m_long_prop[GRAPH_OBJ_PROP_XDISTANCE]                     = 0;  // Distance from the base corner along the X axis in pixels
   this.m_long_prop[GRAPH_OBJ_PROP_YDISTANCE]                     = 0;  // Distance from the base corner along the Y axis in pixels
   this.m_long_prop[GRAPH_OBJ_PROP_DIRECTION]                     = 0;  // Gann object trend
   this.m_long_prop[GRAPH_OBJ_PROP_DEGREE]                        = 0;  // Elliott wave marking level
   this.m_long_prop[GRAPH_OBJ_PROP_DRAWLINES]                     = 0;  // Display lines for Elliott wave marking
   this.m_long_prop[GRAPH_OBJ_PROP_STATE]                         = 0;  // Button state (pressed/released)
   this.m_long_prop[GRAPH_OBJ_PROP_OBJ_CHART_ID]                  = 0;  // Chart object ID (OBJ_CHART).
   this.m_long_prop[GRAPH_OBJ_PROP_CHART_OBJ_PERIOD]              = 0;  // Chart object period<
   this.m_long_prop[GRAPH_OBJ_PROP_CHART_OBJ_DATE_SCALE]          = 0;  // Time scale display flag for the Chart object
   this.m_long_prop[GRAPH_OBJ_PROP_CHART_OBJ_PRICE_SCALE]         = 0;  // Price scale display flag for the Chart object
   this.m_long_prop[GRAPH_OBJ_PROP_CHART_OBJ_CHART_SCALE]         = 0;  // Chart object scale
   this.m_long_prop[GRAPH_OBJ_PROP_XSIZE]                         = 0;  // Object width along the X axis in pixels.
   this.m_long_prop[GRAPH_OBJ_PROP_YSIZE]                         = 0;  // Object height along the Y axis in pixels.
   this.m_long_prop[GRAPH_OBJ_PROP_XOFFSET]                       = 0;  // X coordinate of the upper-left corner of the visibility area.
   this.m_long_prop[GRAPH_OBJ_PROP_YOFFSET]                       = 0;  // Y coordinate of the upper-left corner of the visibility area.
   this.m_long_prop[GRAPH_OBJ_PROP_BGCOLOR]                       = 0;  // Background color for OBJ_EDIT, OBJ_BUTTON, OBJ_RECTANGLE_LABEL
   this.m_long_prop[GRAPH_OBJ_PROP_CORNER]                        = 0;  // Chart corner for binding a graphical object
   this.m_long_prop[GRAPH_OBJ_PROP_BORDER_TYPE]                   = 0;  // Border type for "Rectangle border"
   this.m_long_prop[GRAPH_OBJ_PROP_BORDER_COLOR]                  = 0;  // Border color for OBJ_EDIT and OBJ_BUTTON
   
//--- Save real properties
   this.m_double_prop[this.IndexProp(GRAPH_OBJ_PROP_PRICE)]       = ::ObjectGetDouble(chart_id,name,OBJPROP_PRICE);  // Price coordinate
   this.m_double_prop[this.IndexProp(GRAPH_OBJ_PROP_LEVELVALUE)]  = 0;                                               // Level value
   this.m_double_prop[this.IndexProp(GRAPH_OBJ_PROP_SCALE)]       = 0;                                               // Scale (property of Gann objects and Fibonacci Arcs objects)
   this.m_double_prop[this.IndexProp(GRAPH_OBJ_PROP_ANGLE)]       = 0;                                               // Angle
   this.m_double_prop[this.IndexProp(GRAPH_OBJ_PROP_DEVIATION)]   = 0;                                               // Deviation of the standard deviation channel
   
//--- Save string properties
   this.m_string_prop[this.IndexProp(GRAPH_OBJ_PROP_NAME)]        = name;                                            // Object name
   this.m_string_prop[this.IndexProp(GRAPH_OBJ_PROP_TEXT)]        = ::ObjectGetString(chart_id,name,OBJPROP_TEXT);   // Object description (the text contained in the object)
   this.m_string_prop[this.IndexProp(GRAPH_OBJ_PROP_TOOLTIP)]     = ::ObjectGetString(chart_id,name,OBJPROP_TOOLTIP);// Tooltip text
   this.m_string_prop[this.IndexProp(GRAPH_OBJ_PROP_LEVELTEXT)]   = "";                                              // Level description
   this.m_string_prop[this.IndexProp(GRAPH_OBJ_PROP_FONT)]        = "";                                              // Font
   this.m_string_prop[this.IndexProp(GRAPH_OBJ_PROP_BMPFILE)]     = "";                                              // BMP file name for the "Bitmap Level" object
   this.m_string_prop[this.IndexProp(GRAPH_OBJ_PROP_CHART_OBJ_SYMBOL)]= "";                                          // Chart object symbol 
   
//--- Save basic properties in the parent object
   this.m_create_time=(datetime)this.GetProperty(GRAPH_OBJ_PROP_CREATETIME);
   this.m_back=(bool)this.GetProperty(GRAPH_OBJ_PROP_BACK);
   this.m_selected=(bool)this.GetProperty(GRAPH_OBJ_PROP_SELECTED);
   this.m_selectable=(bool)this.GetProperty(GRAPH_OBJ_PROP_SELECTABLE);
   this.m_hidden=(bool)this.GetProperty(GRAPH_OBJ_PROP_HIDDEN);
   this.m_name=this.GetProperty(GRAPH_OBJ_PROP_NAME);
   
  }
//+-------------------------------------------------------------------+

代码注释中描述了为对象变量设置数值的顺序。 我们不必为每个对象属性设置,而只需为传递给构造函数的属性设置,而且我们可以从图形对象中获取的属性,前提是它们属于所有图形对象公有的。 所有剩余的属性都将在衍生后代类的构造函数中设置,因为每个图形对象都具有不同的属性集合,这些属性集合仅在创建某个特定图形对象时才清楚。

比较两个对象的标准方法:

//+-----------------------------------------------------------------------+
//|Compare CGStdGraphObj objects with each other by the specified property|
//+-----------------------------------------------------------------------+
int CGStdGraphObj::Compare(const CObject *node,const int mode=0) const
  {
   const CGStdGraphObj *obj_compared=node;
//--- compare integer properties of two orders
   if(mode<GRAPH_OBJ_PROP_INTEGER_TOTAL)
     {
      long value_compared=obj_compared.GetProperty((ENUM_GRAPH_OBJ_PROP_INTEGER)mode);
      long value_current=this.GetProperty((ENUM_GRAPH_OBJ_PROP_INTEGER)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- compare real properties of two orders
   else if(mode<GRAPH_OBJ_PROP_DOUBLE_TOTAL+GRAPH_OBJ_PROP_INTEGER_TOTAL)
     {
      double value_compared=obj_compared.GetProperty((ENUM_GRAPH_OBJ_PROP_DOUBLE)mode);
      double value_current=this.GetProperty((ENUM_GRAPH_OBJ_PROP_DOUBLE)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- compare string properties of two orders
   else if(mode<GRAPH_OBJ_PROP_DOUBLE_TOTAL+GRAPH_OBJ_PROP_INTEGER_TOTAL+GRAPH_OBJ_PROP_STRING_TOTAL)
     {
      string value_compared=obj_compared.GetProperty((ENUM_GRAPH_OBJ_PROP_STRING)mode);
      string value_current=this.GetProperty((ENUM_GRAPH_OBJ_PROP_STRING)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
   return 0;
  }
//+------------------------------------------------------------------+
//| Compare CGStdGraphObj objects by all properties                  |
//+------------------------------------------------------------------+
bool CGStdGraphObj::IsEqual(CGStdGraphObj *compared_obj) const
  {
   int beg=0, end=GRAPH_OBJ_PROP_INTEGER_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_GRAPH_OBJ_PROP_INTEGER prop=(ENUM_GRAPH_OBJ_PROP_INTEGER)i;
      if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; 
     }
   beg=end; end+=GRAPH_OBJ_PROP_DOUBLE_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_GRAPH_OBJ_PROP_DOUBLE prop=(ENUM_GRAPH_OBJ_PROP_DOUBLE)i;
      if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; 
     }
   beg=end; end+=GRAPH_OBJ_PROP_STRING_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_GRAPH_OBJ_PROP_STRING prop=(ENUM_GRAPH_OBJ_PROP_STRING)i;
      if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; 
     }
   return true;
  }
//+------------------------------------------------------------------+

在日志中显示对象属性的方法:

//+------------------------------------------------------------------+
//| Display object properties in the journal                         |
//+------------------------------------------------------------------+
void CGStdGraphObj::Print(const bool full_prop=false,const bool dash=false)
  {
   ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_BEG)," (",this.Header(),") =============");
   int beg=0, end=GRAPH_OBJ_PROP_INTEGER_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_GRAPH_OBJ_PROP_INTEGER prop=(ENUM_GRAPH_OBJ_PROP_INTEGER)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("------");
   beg=end; end+=GRAPH_OBJ_PROP_DOUBLE_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_GRAPH_OBJ_PROP_DOUBLE prop=(ENUM_GRAPH_OBJ_PROP_DOUBLE)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("------");
   beg=end; end+=GRAPH_OBJ_PROP_STRING_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_GRAPH_OBJ_PROP_STRING prop=(ENUM_GRAPH_OBJ_PROP_STRING)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_END)," (",this.Header(),") =============\n");
  }
//+------------------------------------------------------------------+

该方法返回一个对象名称的简述:

//+------------------------------------------------------------------+
//| Return the object short name                                     |
//+------------------------------------------------------------------+
string CGStdGraphObj::Header(const bool symbol=false)
  {
   return CGBaseObj::TypeGraphObjectDescription();
  }
//+------------------------------------------------------------------+

该方法在日志中显示对象简述:

//+------------------------------------------------------------------+
//| Display a short description of the object in the journal         |
//+------------------------------------------------------------------+
void CGStdGraphObj::PrintShort(const bool dash=false,const bool symbol=false)
  {
   ::Print
     (
      this.Header(symbol)," \"",CGBaseObj::Name(),"\": ID ",(string)this.GetProperty(GRAPH_OBJ_PROP_ID),
      " ",::TimeToString(CGBaseObj::TimeCreate(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)
     );
  }
//+------------------------------------------------------------------+

返回整数型实数型字符串型对象属性描述的方法:

//+------------------------------------------------------------------+
//| Return description of object's integer property                  |
//+------------------------------------------------------------------+
string CGStdGraphObj::GetPropertyDescription(ENUM_GRAPH_OBJ_PROP_INTEGER property)
  {
   return
     (
      property==GRAPH_OBJ_PROP_ID         ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_ID)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_TYPE       ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_TYPE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+StdGraphObjectTypeDescription((ENUM_OBJECT)this.GetProperty(property))
         )  :
      property==GRAPH_OBJ_PROP_ELEMENT_TYPE  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_ELEMENT_TYPE)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+CGBaseObj::TypeElementDescription()
         )  :
      property==GRAPH_OBJ_PROP_BELONG     ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_BELONG)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+CGBaseObj::BelongDescription()
         )  :
      property==GRAPH_OBJ_PROP_CHART_ID   ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_CHART_ID)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_WND_NUM    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_WND_NUM)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_CREATETIME   ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_CREATETIME)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::TimeToString(this.GetProperty(property),TIME_DATE|TIME_MINUTES|TIME_SECONDS)
         )  :
      property==GRAPH_OBJ_PROP_TIMEFRAMES ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_TIMEFRAMES)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_BACK       ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_BACK)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.IsBack() ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_ZORDER     ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_ZORDER)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_HIDDEN     ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_HIDDEN)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.IsHidden() ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_SELECTED   ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_SELECTED)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.IsSelected() ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_SELECTABLE ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_SELECTABLE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.IsSelectable() ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_NUM        ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_NUM)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_TIME       ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_TIME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::TimeToString(this.GetProperty(property),TIME_DATE|TIME_MINUTES)
         )  :
      property==GRAPH_OBJ_PROP_COLOR      ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_COLOR)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::ColorToString((color)this.GetProperty(property),true)
         )  :
      property==GRAPH_OBJ_PROP_STYLE      ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_STYLE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+LineStyleDescription((ENUM_LINE_STYLE)this.GetProperty(property))
         )  :
      property==GRAPH_OBJ_PROP_WIDTH     ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_WIDTH)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_FILL       ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_FILL)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_READONLY   ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_READONLY)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_LEVELS     ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELS)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_LEVELCOLOR ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELCOLOR)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::ColorToString((color)this.GetProperty(property),true)
         )  :
      property==GRAPH_OBJ_PROP_LEVELSTYLE ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELSTYLE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+LineStyleDescription((ENUM_LINE_STYLE)this.GetProperty(property))
         )  :
      property==GRAPH_OBJ_PROP_LEVELWIDTH ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELWIDTH)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_ALIGN      ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_ALIGN)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+AlignModeDescription((ENUM_ALIGN_MODE)this.GetProperty(property))
         )  :
      property==GRAPH_OBJ_PROP_FONTSIZE   ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_FONTSIZE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_RAY_LEFT   ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_RAY_LEFT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_RAY_RIGHT  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_RAY_RIGHT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_RAY        ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_RAY)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_ELLIPSE    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_ELLIPSE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_ARROWCODE  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_ARROWCODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_ANCHOR     ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_ANCHOR)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.AnchorDescription()
         )  :
      property==GRAPH_OBJ_PROP_XDISTANCE  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_XDISTANCE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_YDISTANCE  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_YDISTANCE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_DIRECTION  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_DIRECTION)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+GannDirectDescription((ENUM_GANN_DIRECTION)this.GetProperty(property))
         )  :
      property==GRAPH_OBJ_PROP_DEGREE     ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_DEGREE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+ElliotWaveDegreeDescription((ENUM_ELLIOT_WAVE_DEGREE)this.GetProperty(property))
         )  :
      property==GRAPH_OBJ_PROP_DRAWLINES  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_DRAWLINES)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_STATE      ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_STATE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_BUTTON_STATE_PRESSED) : CMessage::Text(MSG_LIB_TEXT_BUTTON_STATE_DEPRESSED))
         )  :
      property==GRAPH_OBJ_PROP_OBJ_CHART_ID  ?  CMessage::Text(MSG_CHART_OBJ_ID)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_CHART_OBJ_PERIOD ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_CHART_OBJ_PERIOD)+
         (!this.SupportProperty(property)       ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+TimeframeDescription((ENUM_TIMEFRAMES)this.GetProperty(property))
         )  :
      property==GRAPH_OBJ_PROP_CHART_OBJ_DATE_SCALE   ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_CHART_OBJ_DATE_SCALE)+
         (!this.SupportProperty(property)             ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_CHART_OBJ_PRICE_SCALE  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_CHART_OBJ_PRICE_SCALE)+
         (!this.SupportProperty(property)             ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      property==GRAPH_OBJ_PROP_CHART_OBJ_CHART_SCALE  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_CHART_OBJ_CHART_SCALE)+
         (!this.SupportProperty(property)             ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_XSIZE      ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_XSIZE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_YSIZE      ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_YSIZE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_XOFFSET    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_XOFFSET)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_YOFFSET    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_YOFFSET)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_BGCOLOR    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_BGCOLOR)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::ColorToString((color)this.GetProperty(property),true)
         )  :
      property==GRAPH_OBJ_PROP_CORNER     ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_CORNER)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+BaseCornerDescription((ENUM_BASE_CORNER)this.GetProperty(property))
         )  :
      property==GRAPH_OBJ_PROP_BORDER_TYPE   ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_BORDER_TYPE)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+BorderTypeDescription((ENUM_BORDER_TYPE)this.GetProperty(property))
         )  :
      property==GRAPH_OBJ_PROP_BORDER_COLOR  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_BORDER_COLOR)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::ColorToString((color)this.GetProperty(property),true)
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return description of object's real property                     |
//+------------------------------------------------------------------+
string CGStdGraphObj::GetPropertyDescription(ENUM_GRAPH_OBJ_PROP_DOUBLE property)
  {
   int dg=(this.m_digits>0 ? this.m_digits : 1);
   return
     (
      property==GRAPH_OBJ_PROP_PRICE      ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_PRICE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==GRAPH_OBJ_PROP_LEVELVALUE ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELVALUE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==GRAPH_OBJ_PROP_SCALE      ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_SCALE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),2)
         )  :
      property==GRAPH_OBJ_PROP_ANGLE      ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_ANGLE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),2)
         )  :
      property==GRAPH_OBJ_PROP_DEVIATION  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_DEVIATION)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),2)
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return description of object's string property                   |
//+------------------------------------------------------------------+
string CGStdGraphObj::GetPropertyDescription(ENUM_GRAPH_OBJ_PROP_STRING property)
  {
   return
     (
      property==GRAPH_OBJ_PROP_NAME       ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_NAME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_TEXT       ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_TEXT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_TOOLTIP    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_TOOLTIP)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_LEVELTEXT  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELTEXT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_FONT       ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_FONT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_BMPFILE    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_BMPFILE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetProperty(property)
         )  :
      property==GRAPH_OBJ_PROP_CHART_OBJ_SYMBOL ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_SYMBOL)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetProperty(property)
         )  :
      ""
     );
  }

//+------------------------------------------------------------------+

在讲述函数库的最开始就曾研究过与上述方法类似的操作方法。 此外,在添加不同对象的过程中,对它们的操作逻辑也进行了一番厘清。 因此,此时您应该对它们很熟悉了。 如果您有任何疑问,请随时在下面的评论中提问。

我已完成了抽象图形对象类的创建。 现在我们需要定义图形对象出现在图表上的事实,并在图形对象集合类中创建相应的抽象图形对象。

我不会将这些对象添加到这里的集合列表之中。 我们需要抽象对象的衍生后代来描述某些添加到图表中的图形对象类型。 我将在下一篇文章中实现它们。 在此我只检查新创建的类是否能正常工作。

我需要针对 \MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqh 中的图表对象管理类进行一些修改。 不可能像我在其它集合中所做的那样创建一个节省资源的算法来搜索添加到图表的最后一个图形对象,其中循环从集合类处理的最后一个对象的索引开始。 我们之所以·不能这样做,因为图形对象并非按它们添加到图表的顺序,而是按名称添加到终端列表之中的。 奇怪的是,图形对象在终端列表中却是按名称排序。 添加到图表的最后一个箭头图标成为对象列表中的第一个,而矩形对象由于名称的原因成为第二个。

因此,我们需要在在循环遍历所有图表图形对象,并依据其被添加到图表的时间搜索该对象。 额外变量会安排一次资源节省搜索,并初步添加到类中,以及在其帮助下进行的计算应删除

//+------------------------------------------------------------------+
//|                                      GraphElementsCollection.mqh |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "ListObj.mqh"
#include "..\Services\Select.mqh"
#include "..\Objects\Graph\Form.mqh"

//+------------------------------------------------------------------+
//| Chart object management class                                    |
//+------------------------------------------------------------------+
class CChartObjectsControl : public CObject
  {
private:
   ENUM_TIMEFRAMES   m_chart_timeframe;         // Chart timeframe
   long              m_chart_id;                // Chart ID
   string            m_chart_symbol;            // Chart symbol
   bool              m_is_graph_obj_event;      // Event flag in the list of graphical objects
   int               m_total_objects;           // Number of graphical objects
   int               m_last_objects;            // Number of graphical objects during the previous check
   int               m_index_object;            // Index of the last graphical object added to the collection from the terminal object list
   int               m_delta_graph_obj;         // Difference in the number of graphical objects compared to the previous check
public:
//--- Return the variable values
   ENUM_TIMEFRAMES   Timeframe(void)                           const { return this.m_chart_timeframe;    }
   long              ChartID(void)                             const { return this.m_chart_id;           }
   string            Symbol(void)                              const { return this.m_chart_symbol;       }
   bool              IsEvent(void)                             const { return this.m_is_graph_obj_event; }
   int               TotalObjects(void)                        const { return this.m_total_objects;      }
   int               Delta(void)                               const { return this.m_delta_graph_obj;    }
//--- Check the chart objects
   void              Refresh(void);
//--- Constructors
                     CChartObjectsControl(void)
                       { 
                        this.m_chart_id=::ChartID();
                        this.m_chart_timeframe=(ENUM_TIMEFRAMES)::ChartPeriod(this.m_chart_id);
                        this.m_chart_symbol=::ChartSymbol(this.m_chart_id);
                        this.m_is_graph_obj_event=false;
                        this.m_total_objects=0;
                        this.m_last_objects=0;
                        this.m_index_object=0;
                        this.m_delta_graph_obj=0;
                       }
                     CChartObjectsControl(const long chart_id)
                       {
                        this.m_chart_id=chart_id;
                        this.m_chart_timeframe=(ENUM_TIMEFRAMES)::ChartPeriod(this.m_chart_id);
                        this.m_chart_symbol=::ChartSymbol(this.m_chart_id);
                        this.m_is_graph_obj_event=false;
                        this.m_total_objects=0;
                        this.m_last_objects=0;
                        this.m_index_object=0;
                        this.m_delta_graph_obj=0;
                       }
                     
//--- Compare CChartObjectsControl objects by a chart ID (for sorting the list by an object property)
   virtual int       Compare(const CObject *node,const int mode=0) const
                       {
                        const CChartObjectsControl *obj_compared=node;
                        return(this.ChartID()>obj_compared.ChartID() ? 1 : this.ChartID()<obj_compared.ChartID() ? -1 : 0);
                       }
  };
//+------------------------------------------------------------------+
//| CChartObjectsControl Check objects on a chart                    |
//+------------------------------------------------------------------+
void CChartObjectsControl::Refresh(void)
  {
//--- Graphical objects on the chart
   this.m_total_objects=::ObjectsTotal(this.ChartID());
   int i=this.m_index_object;
   int delta=this.m_total_objects-this.m_last_objects;
   
//--- If the number of objects has changed
   if(delta!=0)
     {

检查图表对象的方法接收图表上图形对象数量递增的处理程序

//+------------------------------------------------------------------+
//| CChartObjectsControl Check objects on a chart                    |
//+------------------------------------------------------------------+
void CChartObjectsControl::Refresh(void)
  {
//--- Graphical objects on the chart
   this.m_total_objects=::ObjectsTotal(this.ChartID());
   this.m_delta_graph_obj=this.m_total_objects-this.m_last_objects;
   
//--- If the number of objects has changed
   if(this.m_delta_graph_obj!=0)
     {
      //--- Create the string and display it in the journal with the chart ID, its symbol and timeframe
      string txt=", "+(m_delta_graph_obj>0 ? "Added: " : "Deleted: ")+(string)fabs(m_delta_graph_obj)+" obj";
      Print(DFUN,"ChartID=",this.ChartID(),", ",this.Symbol(),", ",TimeframeDescription(this.Timeframe()),txt);
     }
   //--- If an object is added to the chart
   if(this.m_delta_graph_obj>0)
     {
      int index=0;
      datetime time=0;
      string name="";
      //--- find the last added graphical object and write its index
      for(int j=0;j<this.m_total_objects;j++)
        {
         name=::ObjectName(this.ChartID(),j);
         datetime tm=(datetime)::ObjectGetInteger(this.ChartID(),name,OBJPROP_CREATETIME);
         if(tm>time)
           {
            time=tm;
            index=j;
           }
        }
      
      //--- Select the last graphical object by its index
      name=::ObjectName(this.ChartID(),index);
      if(name!="")
        {
         //--- Create the object of the abstract graphical object class
         ENUM_OBJECT type=(ENUM_OBJECT)::ObjectGetInteger(this.ChartID(),name,OBJPROP_TYPE);
         ENUM_OBJECT_DE_TYPE obj_type=ENUM_OBJECT_DE_TYPE(type+OBJECT_DE_TYPE_GSTD_OBJ+1);
         CGStdGraphObj *obj=new CGStdGraphObj(obj_type,GRAPH_OBJ_BELONG_NO_PROGRAM,this.ChartID(),name);
         if(obj!=NULL)
           {
            //--- Set the object index, display its short description and remove the created object
            obj.SetObjectID(this.m_total_objects);
            obj.PrintShort();
            delete obj;
           }
        }
     }
//--- save the index of the last added graphical object and the difference with the last check
   this.m_last_objects=this.m_total_objects;
   this.m_is_graph_obj_event=(bool)this.m_delta_graph_obj;
  }
//+------------------------------------------------------------------+

主要逻辑均在代码注释中描述。

总之,为了纠正长期以来的遗漏,在 \MQL5\Include\DoEasy\Engine.mqh 中的 CEngine 函数库主要对象类里,加入了清除图表上所示全部注释的能力

//+------------------------------------------------------------------+
//| CEngine destructor                                               |
//+------------------------------------------------------------------+
CEngine::~CEngine()
  {
   ::EventKillTimer();
   ::Comment("");
  }
//+------------------------------------------------------------------+

现在到了测试新创建功能的时候了。


测试

为了执行测试,我们借用上一篇文章中的 EA,并将其保存到 \MQL5\Experts\TestDoEasy\Part83\,命名为 TestDoEasyPart83.mq5

这可能看起来很奇怪,但我们不需要对 EA 逻辑进行任何更改。 我仅略微修改 OnDeinit() 处理程序中的行为:

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();
   Comment("");
  }
//+------------------------------------------------------------------+

添加调用同名库方法来替代销毁毫秒计时器,并清除所有图表注释

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Deinitialize library
   engine.OnDeinit();
  }
//+------------------------------------------------------------------+

尝试编译 EA 时,我们收到以下错误:

'CGStdGraphObj::CGStdGraphObj' - cannot access protected member function
   see declaration of 'CGStdGraphObj::CGStdGraphObj'
1 errors, 0 warnings

这在意料之中,因为抽象图形对象类的参数型构造函数是在类的私密部分中声明的。 若要修复该错误,暂时为构造函数设置 “public” 访问说明符

//--- Default constructor
                     CGStdGraphObj(){ this.m_type=OBJECT_DE_TYPE_GSTD_OBJ;  }
protected:
public:
//--- Protected parametric constructor
                     CGStdGraphObj(const ENUM_OBJECT_DE_TYPE obj_type,const ENUM_GRAPH_OBJ_BELONG belong,const long chart_id,const string name);
                     

重新编译并启动 EA。

各种图形对象都被加到图表上,而日志会显示有关所添加新对象的消息,及其简述:


正如我们所见,一切都按预期运行。


下一步是什么?

在下一篇文章中,我将创建标准图形对象类,并继续细化图形对象集合。

以下是该函数库当前版本的所有文件,以及 MQL5 的测试 EA 文件,供您测试和下载。

请您在评论中留下问题和建议。

返回内容目录

*该系列的前几篇文章:

DoEasy 函数库中的图形(第七十三部分):图形元素的交互窗对象
DoEasy 函数库中的图形(第七十四部分):由 CCanvas 类提供强力支持的基本图形元素
DoEasy 函数库中的图形(第七十五部分):处理基本图形元素图元和文本的方法
DoEasy 函数库中的图形(第七十六部分):会话窗对象和预定义的颜色主题
DoEasy 函数库中的图形(第七十七部分):阴影对象类
DoEasy 函数库中的图形(第七十八部分):函数库中的动画原理 图像切片
DoEasy 函数库中的图形(第七十九部分):“动画框”对象类及其衍生对象
DoEasy 函数库中的图形(第八十部分):“几何动画框”对象类
DoEasy 函数库中的图形(第八十一部分):将图形集成到函数库对象之中
DoEasy 函数库中的图形(第八十二部分):函数库对象重构和图形对象集合

本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/9902

附加的文件 |
MQL5.zip (4068.71 KB)
DoEasy 函数库中的图形(第八十四部分):抽象标准图形对象的衍生后代类 DoEasy 函数库中的图形(第八十四部分):抽象标准图形对象的衍生后代类
在本文中,我将研究为终端的抽象标准图形对象创建衍生后代对象。 该类对象定义了所有图形对象通用的属性。 因此,它只是某个种类的图形对象。 为了阐明它与真实图形对象的从属关系,我们需要在衍生后代对象类中设置该图形对象特定的固有属性。
探索创建多彩烛条的选项 探索创建多彩烛条的选项
在本文中,我将探讨创建烛条自定义指标的可能性,并指出它们的优缺点。
DoEasy 函数库中的图形(第八十五部分):图形对象集合 - 添加新创建的对象 DoEasy 函数库中的图形(第八十五部分):图形对象集合 - 添加新创建的对象
在本文中,我将完成抽象图形对象类的衍生后代类的开发,并开始实现将这些对象存储在集合类中的能力。 特别是,我将开发把新创建的标准图形对象添加到集合类的功能。
MetaTrader 5 中的出价/要价(Bid/Ask)点差分析 MetaTrader 5 中的出价/要价(Bid/Ask)点差分析
一款能为您报告经纪商平台出价/要价(Bid/Ask)水平的指标。 现在我们可以利用 MT5 的即时报价数据来分析近期的历史真实平均买卖点差是多少。 您不需要查看当前点差,因为若您同时显示出价和要价指示线时,该值已出示。