
DoEasy 函数库中的图形(第八十三部分):抽象标准图形对象类
内容
概述
为了进一步完善我在上一篇实现的图形对象集合类,我需要终端中存在的所有标准图形的对象类。 一旦创建了所有这些对象之后,我就拥有了处理基于 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。
各种图形对象都被加到图表上,而日志会显示有关所添加新对象的消息,及其简述:
正如我们所见,一切都按预期运行。
下一步是什么?
在下一篇文章中,我将创建标准图形对象类,并继续细化图形对象集合。
请您在评论中留下问题和建议。
*该系列的前几篇文章:
DoEasy 函数库中的图形(第七十三部分):图形元素的交互窗对象
DoEasy 函数库中的图形(第七十四部分):由 CCanvas 类提供强力支持的基本图形元素
DoEasy 函数库中的图形(第七十五部分):处理基本图形元素图元和文本的方法
DoEasy 函数库中的图形(第七十六部分):会话窗对象和预定义的颜色主题
DoEasy 函数库中的图形(第七十七部分):阴影对象类
DoEasy 函数库中的图形(第七十八部分):函数库中的动画原理 图像切片
DoEasy 函数库中的图形(第七十九部分):“动画框”对象类及其衍生对象
DoEasy 函数库中的图形(第八十部分):“几何动画框”对象类
DoEasy 函数库中的图形(第八十一部分):将图形集成到函数库对象之中
DoEasy 函数库中的图形(第八十二部分):函数库对象重构和图形对象集合
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/9902
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.



下午好、
总之,我很乐意回答问题,接受批评和建议。
感谢您的关注。
无论如何,我很乐意回答问题,接受批评和建议。
感谢您的关注。
1.具体来说,我指的是代码开头的部分"在类代码 的基础上编写方法,以简化对象属性的设置和返回:"。
根据我的理解,这是对基类中函数的描述,也就是说,这些函数对所有对象都是详尽无遗的,并且访问级别为公共,如果创建一个继承者,它将看到所有这些函数,但并不是每个对象都有控制和文本输出的属性,例如,等等....。当然 ,获得 基类 的 所有功能、日志输出等可能是有意义的,但在创建继承者时,有必要将所有不能应用于继承者类的函数虚拟化并隐藏在访问级别 private 中。
也许这就是您实现的诀窍,如果是这样的话,那么超级!))))))
顺便说一句,也许对于某些函数来说,protected 级比public 级更合适,但在这里你更清楚,当然,这取决于你的理解。
2.是的,我再次查看了您的代码,您构建库的概念与我的不同,我同意,最主要的是,当您创建上层类时,要创建虚拟的公共函数,这样其他开发人员就可以使用您的解决方案,而无需直接编辑库。
3.我还注意到,你使用了字符串合并+,在某些版本的终端中,在大合并和长时间终端操作时,这种实现方式会出现不可预知的情况。)
我使用 StringFormat 和 StringAdd 函数后,工作的可靠性提高了,代码的可读性也更强了。
4.我还想提醒一下渲染时 创建对象长度的限制,请记住这一点,最好从名称生成哈希值,并在其基础上创建对象,该限制有一个标准函数,我记不清楚了,但可能是 ResourceCreate....
1.具体来说,我指的是代码开头的部分"在类代码 的基础上,我们将编写简化访问对象设置和返回属性的方法:"。
根据我的理解,这是对基类中函数的描述,即它们对所有对象都是详尽无遗的,并且访问级别为公共,如果创建了一个继承者,它将看到所有这些函数,但并不是每个对象都有控制和文本输出的属性,例如,等等....。当然 ,获得基类 的 所有功能、日志输出等也许是有意义的,但在创建继承者时,有必要将所有不能应用于继承者类的函数虚拟化并隐藏在访问级别 private 中。
也许这就是您实现的诀窍,如果是这样的话,那么超级!)))))))
顺便说一句,也许对于某些函数来说,protected 级比public 级更合适,当然,您更清楚其中的含义。
2.是的,我再次查看了您的代码,您的库构建概念与众不同,我同意,最主要的是,当您创建上层类时,应创建虚拟的公共函数,这样其他开发人员就可以使用您的解决方案,而无需直接编辑库。
3.我还注意到您使用了 "+"来组合字符串,在某些版本的终端中,当组合较多且终端操作较长时,会出现不可预知的情况,这种实现方式获得了))))。
我使用 StringFormat 和 StringAdd 函数后,工作的可靠性提高了,代码的可读性也更强了。
4.我还想提醒一下渲染时 创建对象的长度限制,请记住,最好生成名称缓存并在其基础上创建对象,该限制有一个标准函数,我记不清楚了,但可能是 ResourceCreate....
1.方法的公开性和冗余性是希望通过多种不同方式访问相同属性的代价。但有些方法确实是虚拟的,或者只在继承者中规定。但这同样只适用于库本身的对象。从它们继承时,所有公共方法都将被继承。
2.我会考虑的。但实际上,最高级别的访问将是进入库的另一个入口,它将是用户定义的函数,再次重复库中已实现的功能,但对普通用户来说更容易理解--只需使用函数得到结果,而不必发明逻辑和处理程序--所有这些都将在库中完成,输出将是用户函数,只需得到必要的信息即可。
3.我没有对任何东西进行优化(除了事先考虑好的逻辑),也没有对任何东西进行剖析。这是最后的工作。
4.用我的方法检查过。长对象名称是可能的。不过谢谢你,我会记住并留意的。
1.把方法变成公共的和多余的,是想用多种不同方法访问相同属性的代价。但有些方法确实是虚拟的,或者只在继承者中规定。但这同样只适用于库本身的对象。当从它们继承时,所有公共方法都将被继承。
2.我会考虑的。但实际上,最高级别的访问将是进入库的另一个入口,它将是用户定义的函数,同样是重复库中已经实现的功能,但对普通用户来说更容易理解--只需使用函数得到结果,而不必发明逻辑和处理程序--所有这些都将在库中完成,输出将是用户函数,只需得到必要的信息即可。
3.我没有对任何东西进行优化(除了事先考虑好的逻辑),也没有对任何东西进行剖析。这是最后的工作。
4.用我的方法检查过。长对象名称是可能的。不过谢谢你,我会记住并留意的。
4.这个错误可能已经消除了,但还不确定......函数似乎起作用了,但没有创建对象,这是长度较大时的行为。