DoEasyライブラリのグラフィックス(第93部): 複合グラフィカルオブジェクトを作成するための機能の準備

Artyom Trishkin | 21 3月, 2022

目次


概念

MetaTrader 5クライアントターミナルは、チャートのさまざまなグラフィカル構造で使用されるグラフィカルな分析ツールの幅広いセットを備えていますが、それでも、一部のユーザには特定のツールが不足しているとよく耳にします。ターミナルには44の分析ツールがあります。これらのグラフィカルオブジェクトをバンドルされたセットに組み合わせて、新しいテクニカル分析ツールを作成できたらどうなるか想像してみてください。MQL5言語はそれを可能にします。

ライブラリが複合グラフィカルオブジェクトの作成をサポートし、それらのオブジェクトが任意の接続階層を持つことができるようになります。このような各オブジェクトは、他のグラフィカルオブジェクトのリストが添付された基本グラフィカルオブジェクトを持つようになります。基本オブジェクトは、従属グラフィカルオブジェクトのプロパティを管理する機能を持ち、依存オブジェクトは、接続される一連のXおよびY基本オブジェクト座標を持つようになります。基本オブジェクトプロパティのリスト全体を座標として使用できます。たとえば、依存オブジェクトのX座標を計算するために、基本オブジェクトポイントのX座標ではなく、複数のX座標(たとえば、2つの座標(トレンドラインのポイント0と1))を使用できます。この場合、基本オブジェクトの2つのX座標の平均値を、依存オブジェクトのX座標として使用できます。

基本オブジェクトリスト内の各依存オブジェクトは、そのリストにある他のグラフィカルオブジェクトの基本オブジェクトにすることもできます。これにより、さまざまな複合グラフィカルオブジェクトからさまざまなセットを作成できます。
さらに、このようなオブジェクトの作成をプログラムで実装することを試みます。このようなオブジェクトでは、各依存オブジェクトがプログラムコードの基本オブジェクトのリストに追加されるだけでなく、リアルタイムでの作成も行われます。あるグラフィカルオブジェクトを別のグラフィカルオブジェクトにドラッグすると、アンカーポイントが視覚的に選択されて接続され、後で再定義できるようになります。

今回の記事では、拡張された標準グラフィカルオブジェクトを作成する機能を作成します。オブジェクトが拡張されていることを示す標準グラフィカルオブジェクトの新しいプロパティと、依存するものの座標を計算および指定するための基本オブジェクト座標の関連プロパティを格納するクラスです。


ライブラリクラスの改善

\MQL5\Include\DoEasy\Defines.mqhのグラフィカル要素タイプの列挙で、さらに別のタイプを追加します。拡張された標準グラフィカルオブジェクトです。

//+------------------------------------------------------------------+
//| The list of graphical element types                              |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_ELEMENT_TYPE
  {
   GRAPH_ELEMENT_TYPE_STANDARD,                       // Standard graphical object
   GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED,              // Extended 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
  };
//+------------------------------------------------------------------+

グラフィカルオブジェクトの整数プロパティの列挙にプロパティを追加(基本のグラフィカルオブジェクトID)し、整数プロパティの数を54から55に増やします

//+------------------------------------------------------------------+
//| 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_BASE_ID,                            // Base 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_SPECIES,                            // Graphical object species (ENUM_GRAPH_OBJ_SPECIES)
   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
   GRAPH_OBJ_PROP_CHANGE_HISTORY,                     // Flag of storing the change history
   GRAPH_OBJ_PROP_GROUP,                              // Group of objects the graphical object belongs to
   //--- 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_CHART_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 (55)             // Total number of integer properties
#define GRAPH_OBJ_PROP_INTEGER_SKIP  (0)              // Number of integer properties not used in sorting
//+------------------------------------------------------------------+

各依存オブジェクトでは基本オブジェクトIDが設定され、1から始まります。プロパティのゼロ値は、オブジェクトが他のオブジェクトに接続されておらず、依存オブジェクトではないことを示します。

グラフィカルオブジェクトの文字列プロパティの列挙に基本グラフィカルオブジェクト名プロパティを追加し、文字列プロパティの数を7から8に増やします

//+------------------------------------------------------------------+
//| 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_BASE_NAME,                          // Base 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  (8)              // 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_BASE_ID,                            // 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_SPECIES,                            // Sort by a graphical object species
   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_CHANGE_HISTORY,                     // Sort by the flag of storing the change history
   SORT_BY_GRAPH_OBJ_GROUP,                              // Sort by the group of objects the graphical object belongs to
   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_BASE_NAME,                          // Sort by base 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_SYS_REQUEST_OUTSIDE_LONG_ARRAY,            // Request outside long array
   MSG_LIB_SYS_REQUEST_OUTSIDE_DOUBLE_ARRAY,          // Request outside double array
   MSG_LIB_SYS_REQUEST_OUTSIDE_STRING_ARRAY,          // Request outside string array
   MSG_LIB_SYS_REQUEST_OUTSIDE_ARRAY,                 // Request outside the array

...

   MSG_GRAPH_ELEMENT_TYPE_STANDARD,                   // Standard graphical object
   MSG_GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED,          // Extended 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_PROP_ID,                             // Object ID
   MSG_GRAPH_OBJ_PROP_BASE_ID,                        // Base 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_NAME,                           // Object name
   MSG_GRAPH_OBJ_PROP_BASE_NAME,                      // Base 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,                         // Chart object symbol

...

   MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_CREATE,                // New graphical object created
   MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_CHANGE,                // Changed the graphical object property
   MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_RENAME,                // Graphical object renamed
   MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_DELETE,                // Graphical object removed
   MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_DEL_CHART,             // Graphical object removed together with the chart
   
//--- CGStdGraphObj (Extended)
   MSG_GRAPH_OBJ_FAILED_CREATE_NEW_EXT_OBJ,           //  Failed to create the class object of an extended graphical object
   MSG_GRAPH_OBJ_FAILED_CREATE_NEW_BASE_EXT_OBJ,      // Failed to create the base object for an extended graphical object
   MSG_GRAPH_OBJ_FAILED_ADD_EXT_OBJ_TO_LIST,          // Failed to add the extended standard graphical object to the list
   MSG_GRAPH_OBJ_FAILED_ADD_BASE_EXT_OBJ_TO_LIST,     // Failed to add the base object to the list
   MSG_GRAPH_OBJ_FAILED_CREATE_NEW_DEP_EXT_OBJ,       // Failed to create the subordinate object of an extended graphical object
   MSG_GRAPH_OBJ_FAILED_ADD_DEP_EXT_OBJ_TO_LIST,      // Failed to add the subordinate object to the list
   MSG_GRAPH_OBJ_FAILED_GET_EXT_OBJ_FROM_LIST,        // Failed to receive the extended graphical object from the list
   MSG_GRAPH_OBJ_PROP_NUM_EXT_BASE_OBJ,               // Base object of the extended graphical object
   MSG_GRAPH_OBJ_NOT_EXT_OBJ,                         // The object is not an extended standard graphical object
   
//--- CLinkedPivotPoint
   MSG_GRAPH_OBJ_EXT_NOT_ANY_PIVOTS_X,                // Not a single pivot point is set for the object along the X axis
   MSG_GRAPH_OBJ_EXT_NOT_ANY_PIVOTS_Y,                // Not a single pivot point is set for the object along the Y axis
   MSG_GRAPH_OBJ_EXT_NOT_ATACHED_TO_BASE,             // The object is not attached to the basic graphical object
   MSG_GRAPH_OBJ_EXT_FAILED_CREATE_PP_DATA_OBJ,       // Failed to create a data object for the X and Y pivot points
  };
//+------------------------------------------------------------------+

また、新しく追加されたインデックスに対応するテキストも追加します。

   {"Запрос за пределами long-массива","Data requested outside the long-array"},
   {"Запрос за пределами double-массива","Data requested outside the double-array"},
   {"Запрос за пределами string-массива","Data requested outside the string-array"},
   {"Запрос за пределами массива","Data requested outside the array"},

...

   {"Стандартный графический объект","Standard graphic object"},
   {"Расширенный стандартный графический объект","Extended standard graphic object"},
   {"Элемент","Element"},
   {"Объект тени","Shadow object"},
   {"Форма","Form"},
   {"Окно","Window"},

...

   {"Идентификатор объекта","Object ID"},
   {"Идентификатор базового объекта","Base object ID"},
   {"Тип объекта","Object type"},
   {"Тип графического элемента","Graphic element type"},

...

   {"Имя","Name"},
   {"Имя базового объекта","Base object name"},
   {"Описание","Description"},
   {"Текст всплывающей подсказки","The text of a tooltip"},
   {"Описание уровня","Level description"},
   {"Шрифт","Font"},
   {"Имя BMP-файла","BMP-file name"},
   {"Символ графика","Chart Symbol"},

...

   {"Создан новый графический объект","New graphic object created"},
   {"Изменено свойство графического объекта","Changed graphic object property"},
   {"Графический объект переименован","Graphic object renamed"},
   {"Удалён графический объект","Graphic object deleted"},
   {"Графический объект удалён вместе с графиком","The graphic object has been removed along with the chart"},
   
//--- CGStdGraphObj (Extended)
   {"Не удалось создать объект класса расширенного графического объекта","Failed to create the class object of extended standart graphics object"},
   {"Не удалось создать базовый объект расширенного графического объекта","Failed to create the base object of a extended graphics object"},
   {"Не удалось добавить расширенный стандартный графический объект в список","Failed to add extended standard graphic object to the list"},
   {"Не удалось добавить базовый объект в список","Failed to add base object to list"},
   {"Не удалось создать подчинённый объект расширенного графического объекта","Failed to create the dependent object of a extended graphics object"},
   {"Не удалось добавить подчинённый объект в список","Failed to add dependent object to list"},
   {"Не удалось получить расширенный графический объект из списка","Failed to get extended graphic object from list"},
   {"Базовый объект расширенного графического объекта","The base object of the extended graphical object"},
   {"Объект не является расширенным стандартным графическим объектом","The object is not an extended standard graphical object"},
   
//--- CLinkedPivotPoint
   {"Для объекта не установлено ни одной опорной точки по оси X","The object does not have any pivot points set along the x-axis"},
   {"Для объекта не установлено ни одной опорной точки по оси Y","The object does not have any pivot points set along the y-axis"},
   {"Объект не привязан к базовому графическому объекту","The object is not attached to the base graphical object"},
   {"Не удалось создать объект данных опорной точки X и Y.","Failed to create X and Y reference point data object"},
   
  };
//+---------------------------------------------------------------------+


拡張された標準グラフィカルオブジェクトは、標準オブジェクトに基づいています。オブジェクトを拡張するには、拡張グラフィカルオブジェクトプロパティをそれに設定します。リストに依存オブジェクトを追加して管理することにより、拡張された標準グラフィカルオブジェクトを処理するために作成された機能を使用します。

抽象標準グラフィカルオブジェクトクラスの子孫であるすべての標準グラフィカルオブジェクトのクラスがすでにあります。ここで行う必要があるのは、通常のオブジェクトではなく、拡張グラフィカルオブジェクトが作成されていることを示すフラグを指定することだけです。

このようなオブジェクトはプログラムで作成されるため、オブジェクト所属プロパティは「オブジェクトはプログラムに属している」として設定する必要があります(手動で作成されたオブジェクトのプロパティはデフォルトで設定されます)。標準の拡張グラフィカルオブジェクトタイプも同じように設定されます。これはすべて、作成中にグラフィカルオブジェクトコンストラクタに渡されたフラグ値に従って行われます。

これらの改善に加えて、新しいグラフィカルオブジェクトプロパティを、オブジェクトプロパティのサポートを示すフラグを返すメソッドに設定する必要があります。
これらの変更はすべて、\MQL5\Include\DoEasy\Objects\Graph\Standard\にある標準グラフィカルオブジェクトのすべてのクラスで同じタイプであるため、例としてGStdArrowBuyObj.mqhを使用して実装された変更を検討します。

クラスコンストラクタは、拡張された標準グラフィカルオブジェクトのフラグを受け取ります。フラグ値に応じて、これが標準なのか標準拡張グラフィカルオブジェクトなのか、およびオブジェクトが手動で作成されるプログラムで作成されるかを指定する必要があります。

public:
   //--- Constructor
                     CGStdArrowBuyObj(const long chart_id,const string name,const bool extended) : 
                        CGStdGraphObj(OBJECT_DE_TYPE_GSTD_ARROW_BUY,(!extended ? GRAPH_ELEMENT_TYPE_STANDARD : GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED),(!extended ? GRAPH_OBJ_BELONG_NO_PROGRAM : GRAPH_OBJ_BELONG_PROGRAM),GRAPH_OBJ_SPECIES_ARROWS,chart_id,1,name)
                          {
                           //--- Specify the object property
                           CGStdGraphObj::SetProperty(GRAPH_OBJ_PROP_ANCHOR,0,ANCHOR_TOP);
                          }

オブジェクトによるintegerおよびstringプロパティのサポートを示すフラグを返すメソッドで、上記で実装された新しいプロパティを追加します。

//+------------------------------------------------------------------+
//| Return 'true' if an object supports a passed                     |
//| integer property, otherwise return 'false'                       |
//+------------------------------------------------------------------+
bool CGStdArrowBuyObj::SupportProperty(ENUM_GRAPH_OBJ_PROP_INTEGER property)
  {
   switch((int)property)
     {
      //--- Supported properties
      case GRAPH_OBJ_PROP_ID           :
      case GRAPH_OBJ_PROP_BASE_ID      :
      case GRAPH_OBJ_PROP_TYPE         :
      case GRAPH_OBJ_PROP_ELEMENT_TYPE : 
      case GRAPH_OBJ_PROP_GROUP        : 
      case GRAPH_OBJ_PROP_BELONG       :
      case GRAPH_OBJ_PROP_CHART_ID     :
      case GRAPH_OBJ_PROP_WND_NUM      :
      case GRAPH_OBJ_PROP_NUM          :
      case GRAPH_OBJ_PROP_CREATETIME   :
      case GRAPH_OBJ_PROP_CHANGE_HISTORY:
      case GRAPH_OBJ_PROP_TIMEFRAMES   :
      case GRAPH_OBJ_PROP_BACK         :
      case GRAPH_OBJ_PROP_ZORDER       :
      case GRAPH_OBJ_PROP_HIDDEN       :
      case GRAPH_OBJ_PROP_SELECTED     :
      case GRAPH_OBJ_PROP_SELECTABLE   :
      case GRAPH_OBJ_PROP_TIME         :
      case GRAPH_OBJ_PROP_COLOR        :
      case GRAPH_OBJ_PROP_STYLE        :
      case GRAPH_OBJ_PROP_WIDTH        :
      case GRAPH_OBJ_PROP_ANCHOR       : return true;
      //--- Other properties are not supported
      //--- Default is 'false'
      default: break;
     }
   return false;
  }
//+------------------------------------------------------------------+
//| Return 'true' if an object supports a passed                     |
//| real property, otherwise return 'false'                          |
//+------------------------------------------------------------------+
bool CGStdArrowBuyObj::SupportProperty(ENUM_GRAPH_OBJ_PROP_DOUBLE property)
  {
   switch((int)property)
     {
      //--- Supported properties
      case GRAPH_OBJ_PROP_PRICE        : return true;
      //--- Other properties are not supported
      //--- Default is 'false'
      default: break;
     }
   return false;
  }
//+------------------------------------------------------------------+
//| Return 'true' if an object supports a passed                     |
//| string property, otherwise return 'false'                        |
//+------------------------------------------------------------------+
bool CGStdArrowBuyObj::SupportProperty(ENUM_GRAPH_OBJ_PROP_STRING property)
  {
   switch((int)property)
     {
      //--- Supported properties
      case GRAPH_OBJ_PROP_NAME            :
      case GRAPH_OBJ_PROP_BASE_NAME       :
      case GRAPH_OBJ_PROP_TEXT            :
      case GRAPH_OBJ_PROP_TOOLTIP         :  return true;
      //--- Other properties are not supported
      //--- Default is 'false'
      default: break;
     }
   return false;
  }
//+------------------------------------------------------------------+

このような変更を、\MQL5\Include\DoEasy\Objects\Graph\Standard\にあるすべてのファイルに実装する必要があります。これはすでに行われています。以下に添付されているファイルですべての改善を確認できます。

改善を実装した後、新しいプロパティは標準グラフィカルオブジェクトクラスのすべてのオブジェクトによって処理されます。これにより、これらの各オブジェクトはこれらの新しいプロパティのサポートを示すフラグを備えているため、これらのプロパティを最大限の効率で処理できます。

\MQL5\Include\DoEasy\Objects\Graph\GBaseObj.mqhで、基本グラフィカルオブジェクトクラスファイルのグラフィカル要素タイプの説明を返すメソッドで、グラフィカルオブジェクトの説明を正しく表示できるように「拡張された標準グラフィックオブジェクト」グラフィカル要素タイプの検証を追加します

//+------------------------------------------------------------------+
//| Return the description of the graphical element type             |
//+------------------------------------------------------------------+
string CGBaseObj::TypeElementDescription(void)
  {
   return
     (
      this.TypeGraphElement()==GRAPH_ELEMENT_TYPE_STANDARD           ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_STANDARD)           :
      this.TypeGraphElement()==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED  ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)  :
      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"
     );
  }
//+------------------------------------------------------------------+


依存オブジェクトの座標を指定するためのクラス

基本グラフィカルオブジェクトリスト内の依存オブジェクトには、それを構築するために使用される独自の座標があります。同時に、基本グラフィカルオブジェクトは、依存オブジェクトの座標を管理する方法を知っている必要があります。基本オブジェクトに依存するグラフィカルオブジェクトがバインドされている座標を知らせるために、後者は、基本オブジェクトが計算できる特定のプロパティを備えて、自身の座標が変更されたときに依存オブジェクトの座標を変更するコマンドを送信する必要があります。

基本オブジェクトプロパティと依存オブジェクトプロパティの間にこのような接続を確立するには、クラスを作成し、それを接続されたピボットポイントオブジェクトのクラスと呼びます。

3つのクラスがあります。

  1. 依存オブジェクトを基本オブジェクトの座標軸に接続するために使用されるプロパティを格納するピボットポイントデータクラス。
  2. 2つのファーストクラスオブジェクトを格納する2つのピボットポイントデータのクラス。最初のクラスは、依存オブジェクトをX座標でベースに接続するために使用されるプロパティのデータを格納し、2番目のクラスは、オブジェクトをY座標で接続できるようにするデータを格納します。
  3. 接続されたピボットポイントのクラス。このクラスは、2番目のタイプのオブジェクトのリストを格納するためのものです。2つのアンカーポイントデータのクラスの1つのオブジェクトは、そのピボットポイントごとに責任があります。つまり、各オブジェクトには、依存オブジェクトの単一のアンカーポイントを構築するために使用される基本オブジェクトのプロパティが格納されます。そのX座標とY座標は、関連するリストが各座標軸ごとの最初のタイプのオブジェクトに格納されている複数の基本オブジェクト座標を使用して計算できます。

最初のタイプのオブジェクトは、通常の2次元配列に基づいて作成されます。
配列の2番目の次元の次元は2で、ゼロセルにはプロパティ自体(TimeやPriceなど)が含まれ、最初の次元にはプロパティ修飾子が含まれます。トレンドラインが2つのアンカーポイントを備えていると仮定します。この場合、座標の設定に使用されるポイントは、配列の2次元目のセル1に設定されます。値は、トレンドラインの左側のポイントが0、右側のポイントが1です。
ほとんどの場合、最初の次元の配列のサイズは1になります。これは、依存オブジェクトを接続するために座標が使用される1つの基本オブジェクトプロパティのみが指定されることを意味します。ただし、たとえば2つのトレンドラインポイント間など、計算された座標にオブジェクトを接続する必要がある場合は、配列の次元を2つまで増やす必要があります。最初のものは基本オブジェクトの最初のアンカーポイントのプロパティを設定し、2番目のものは2番目のもののプロパティを含みます。この場合、依存オブジェクトは、ライブラリユーザーがコードで設定した特定の方程式に従って基本オブジェクトに接続されます。この機能は後で実装されます。今回の記事では、必要な準備をすべて行います。

クラスを\MQL5\Include\DoEasy\Objects\Graph\Standard\GStdGraphObj.mqh抽象標準グラフィカルオブジェクトに直接実装しましょう。これは、作成されたオブジェクトが拡張された標準グラフィカルオブジェクトである場合に、クラスが宣言されるファイルです。

ファイルリストの最初に、依存オブジェクトのピボットポイントデータのクラスを追加します。

//+------------------------------------------------------------------+
//|                                                 GStdGraphObj.mqh |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                             https://mql5.com/ja/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://mql5.com/ja/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "..\GBaseObj.mqh"
#include "..\..\..\Services\Properties.mqh"
//+------------------------------------------------------------------+
//| Class of the dependent object pivot point data                   |
//+------------------------------------------------------------------+
class CPivotPointData
  {
private:
   bool              m_axis_x;
   int               m_property_x[][2];
public:
//--- (1) Set and (2) return the flag indicating that the pivot point belongs to the X coordinate
   void              SetAxisX(const bool axis_x)         { this.m_axis_x=axis_x; }
   bool              IsAxisX(void)                 const { return this.m_axis_x; }
//--- Return the number of base object pivot points for calculating the coordinate of the dependent one
   int               GetBasePivotsNum(void)  const { return ::ArrayRange(this.m_property_x,0);  }
//--- Add the new pivot point of the base object for calculating the coordinate of a dependent one
   bool              AddNewBasePivotPoint(const string source,const int pivot_prop,const int pivot_num)
                       {
                        //--- Get the array size 
                        int pivot_index=this.GetBasePivotsNum();
                        //--- if failed to increase the array size, inform of that and return 'false'
                        if(::ArrayResize(this.m_property_x,pivot_index+1)!=pivot_index+1)
                          {
                           CMessage::ToLog(source,MSG_LIB_SYS_FAILED_ARRAY_RESIZE);
                           return false;
                          }
                        //--- Return the result of changing the values of a newly added new array dimension
                        return this.ChangeBasePivotPoint(source,pivot_index,pivot_prop,pivot_num);
                       }
//--- Change the specified pivot point of the base object for calculating the coordinate of a dependent one
   bool              ChangeBasePivotPoint(const string source,const int pivot_index,const int pivot_prop,const int pivot_num)
                       {
                        //--- Get the array size. If it is zero, inform of that and return 'false'
                        int n=this.GetBasePivotsNum();
                        if(n==0)
                          {
                           CMessage::ToLog(source,(this.IsAxisX() ?MSG_GRAPH_OBJ_EXT_NOT_ANY_PIVOTS_X : MSG_GRAPH_OBJ_EXT_NOT_ANY_PIVOTS_Y));
                           return false;
                          }
                        //--- If the specified index goes beyond the array range, inform of that and return 'false'
                        if(pivot_index<0 || pivot_index>n-1)
                          {
                           CMessage::ToLog(source,MSG_LIB_SYS_REQUEST_OUTSIDE_ARRAY);
                           return false;
                          }
                        //--- Set the values, passed to the method, in the specified array cells by index
                        this.m_property_x[pivot_index][0]=pivot_prop;
                        this.m_property_x[pivot_index][1]=pivot_num;
                        return true;
                       }

//--- Constructor/destructor
                     CPivotPointData(void){;}
                    ~CPivotPointData(void){;}
  };
//+------------------------------------------------------------------+

このクラスには、2次元配列とサイズを変更(新しいピボットポイントを追加する)して指定された最初の配列次元に値を設定するための2つのメソッドが含まれています。このクラスには、配列に設定されている座標データ(XまたはY)を示すメソッドもあります。クラスからのメッセージを表示すると、フラグが確認され、適切なエラーメッセージが表示されます

複合オブジェクトのXおよびYピボットポイントに関するデータのクラスが続きます。

//+------------------------------------------------------------------+
//| Class of data on X and Y pivot points of a composite object      |
//+------------------------------------------------------------------+
class CPivotPointXY : public CObject
  {
private:
   CPivotPointData   m_pivot_point_x;            // X coordinate pivot point
   CPivotPointData   m_pivot_point_y;            // Y coordinate pivot point
public:
//--- Return the pointer to the (1) X and (2) Y coordinate pivot point data object
   CPivotPointData  *GetPivotPointDataX(void)      { return &this.m_pivot_point_x;                    }
   CPivotPointData  *GetPivotPointDataY(void)      { return &this.m_pivot_point_y;                    }
//--- Return the number of base object pivot points for calculating the (1) X and (2) Y coordinate
   int               GetBasePivotsNumX(void) const { return this.m_pivot_point_x.GetBasePivotsNum();  }
   int               GetBasePivotsNumY(void) const { return this.m_pivot_point_y.GetBasePivotsNum();  }
//--- Add the new pivot point of the base object for calculating the X coordinate of a dependent one
   bool              AddNewBasePivotPointX(const int pivot_prop,const int pivot_num)
                       {
                        return this.m_pivot_point_x.AddNewBasePivotPoint(DFUN,pivot_prop,pivot_num);
                       }
//--- Add the new pivot point of the base object for calculating the Y coordinate of a dependent one
   bool              AddNewBasePivotPointY(const int pivot_prop,const int pivot_num)
                       {
                        return this.m_pivot_point_y.AddNewBasePivotPoint(DFUN,pivot_prop,pivot_num);
                       }
//--- Add new pivot points of the base object for calculating the X and Y coordinates of a dependent one
   bool              AddNewBasePivotPointXY(const int pivot_prop_x,const int pivot_num_x,
                                            const int pivot_prop_y,const int pivot_num_y)
                       {
                        bool res=true;
                        res &=this.m_pivot_point_x.AddNewBasePivotPoint(DFUN,pivot_prop_x,pivot_num_x);
                        res &=this.m_pivot_point_y.AddNewBasePivotPoint(DFUN,pivot_prop_y,pivot_num_y);
                        return res;
                       }
//--- Change the specified pivot point of the base object for calculating the X coordinate of a dependent one
   bool              ChangeBasePivotPointX(const int pivot_index,const int pivot_prop,const int pivot_num)
                       {
                        return this.m_pivot_point_x.ChangeBasePivotPoint(DFUN,pivot_index,pivot_prop,pivot_num);
                       }
//--- Change the specified pivot point of the base object for calculating the Y coordinate of a dependent one
   bool              ChangeBasePivotPointY(const int pivot_index,const int pivot_prop,const int pivot_num)
                       {
                        return this.m_pivot_point_y.ChangeBasePivotPoint(DFUN,pivot_index,pivot_prop,pivot_num);
                       }
//--- Change specified pivot points of the base object for calculating the X and Y coordinates
   bool              ChangeBasePivotPointXY(const int pivot_index,
                                            const int pivot_prop_x,const int pivot_num_x,
                                            const int pivot_prop_y,const int pivot_num_y)
                       {
                        bool res=true;
                        res &=this.m_pivot_point_x.ChangeBasePivotPoint(DFUN,pivot_index,pivot_prop_x,pivot_num_x);
                        res &=this.m_pivot_point_y.ChangeBasePivotPoint(DFUN,pivot_index,pivot_prop_y,pivot_num_y);
                        return res;
                       }
                       
//--- Constructor/destructor
                     CPivotPointXY(void){ this.m_pivot_point_x.SetAxisX(true); this.m_pivot_point_y.SetAxisX(false); }
                    ~CPivotPointXY(void){;}
  };  
//+------------------------------------------------------------------+

このクラスには、上記で検討した2つのオブジェクト(X座標および Y座標)と、これらのオブジェクトを操作するためのメソッドが含まれています。これらのオブジェクトは、実際には、1番目のクラスのメソッド処理の結果を返すだけです。X軸フラグまたはY軸フラグは、コンストラクタ内の各オブジェクトに設定されます。
このクラスには、X座標とY座標のプロパティ値を同時に設定するためのメソッドもあります。最初の2つのクラスのメソッドがすぐに呼び出され、それらを呼び出した累積結果が返されます。少なくとも1つのメソッドがfalseを返す場合、結果はfalseになります。

このクラスの後には、3番目のクラスである複合オブジェクトピボットポイント上の接続されたデータのクラスが続きます。

//+------------------------------------------------------------------+
//| Class of connected data on composite object pivot points         |
//+------------------------------------------------------------------+
class CLinkedPivotPoint
  {
private:
   CArrayObj         m_list;                       // List of pivot points of the bound object X and Y coordinates
   int               m_base_obj_index;             // Base object index
public:
//--- (1) Set and (2) return the base object index
   void              SetBaseObjIndex(const int index)       { this.m_base_obj_index=index;                  }
   int               GetBaseObjIndex(void)            const { return this.m_base_obj_index;                 }
//--- Create a new object of the class of data on X and Y pivot points of a composite object and add it to the object list
   bool              CreateNewLinkedPivotPoint(const int pivot_prop_x,const int pivot_num_x,const int pivot_prop_y,const int pivot_num_y)
                       {
                        //--- Create an object of data on X and Y pivot points
                        CPivotPointXY *obj=new CPivotPointXY();
                        if(obj==NULL)
                           return false;
                        //--- Add a single dimension with data on pivot points of the base object by X and Y to each object
                        if(!obj.AddNewBasePivotPointXY(pivot_prop_x,pivot_num_x,pivot_prop_y,pivot_num_y))
                           return false;
                        //--- If failed to add the newly created object to the list, inform of that, remove the object and return 'false'
                        if(!this.m_list.Add(obj))
                          {
                           CMessage::ToLog(DFUN,MSG_LIB_SYS_FAILED_OBJ_ADD_TO_LIST);
                           delete obj;
                           return false;
                          }
                        //--- If all is successful, return 'true'
                        return true;
                       }
   
//--- Return the amount of data on pivot points of X and Y coordinates
   int               GetNumLinkedPivotPoints(void)    const {  return this.m_list.Total();                  }
//--- Return the pointer to the (1) first and (2) the last object of data on X and Y pivot points (3) by index
   CPivotPointXY    *GetLinkedPivotPointXYFirst(void)       const { return this.m_list.At(0);                     }
   CPivotPointXY    *GetLinkedPivotPointXYLast(void)        const { return this.m_list.At(this.m_list.Total()-1); }
   CPivotPointXY    *GetLinkedPivotPointXY(const int index) const { return this.m_list.At(index);                 }
//--- Return the pointer to the X coordinate pivot point data object by index
   CPivotPointData  *GetBasePivotPointDataX(const int index) const
                       {
                        CPivotPointXY *obj=this.GetLinkedPivotPointXY(index);
                        if(obj==NULL)
                           return NULL;
                        return obj.GetPivotPointDataX();
                       }
//--- Return the pointer to the Y coordinate pivot point data object by index
   CPivotPointData  *GetBasePivotPointDataY(const int index) const
                       {
                        CPivotPointXY *obj=this.GetLinkedPivotPointXY(index);
                        if(obj==NULL)
                           return NULL;
                        return obj.GetPivotPointDataY();
                       }
//--- Return the number of base object pivot points for calculating the X coordinate by index
   int               GetBasePivotsNumX(const int index) const
                       {
                        CPivotPointData *obj=this.GetBasePivotPointDataX(index);
                        if(obj==NULL)
                           return NULL;
                        return obj.GetBasePivotsNum();
                       }
//--- Return the number of base object pivot points for calculating the Y coordinate by index
   int               GetBasePivotsNumY(const int index) const
                       {
                        CPivotPointData *obj=this.GetBasePivotPointDataY(index);
                        if(obj==NULL)
                           return NULL;
                        return obj.GetBasePivotsNum();
                       }

//--- Constructor/destructor
                     CLinkedPivotPoint(void){;}
                    ~CLinkedPivotPoint(void){;}
  };  
//+------------------------------------------------------------------+

このクラスを使用すると、複合オブジェクトXおよびYピボットポイントにデータクラスのオブジェクトを作成し、処理するクラスオブジェクトへのポインタを返すことができます。そのようなオブジェクトの1つは、X座標とY座標を使用して、基本オブジェクトの単一のアンカーポイントを完全に記述し、新しいアンカーポイントを追加したり、既存のアンカーポイントを変更したりできるようにします。さらに、オブジェクトには基本オブジェクトIDが含まれているため、グラフィカルオブジェクトが接続されているオブジェクトを定義できます。

抽象標準グラフィカルオブジェクトクラスのprivateセクションで、依存オブジェクトのリスト(それに接続されている)および上記で検討した接続されたピボットポイントのクラスのオブジェクトを宣言します。

//+------------------------------------------------------------------+
//| The class of the abstract standard graphical object              |
//+------------------------------------------------------------------+
class CGStdGraphObj : public CGBaseObj
  {
private:
   CArrayObj         m_list;                                            // List of dependent graphical objects
   CProperties      *Prop;                                              // Pointer to the property object
   CLinkedPivotPoint m_linked_pivots;                                   // Connected pivot points
   int               m_pivots;                                          // Number of object reference points
//--- Read and set (1) the time and (2) the price of the specified object pivot point
   void              SetTimePivot(const int index);
   void              SetPricePivot(const int index);
//--- Read and set (1) color, (2) style, (3) width, (4) value, (5) text of the specified object level
   void              SetLevelColor(const int index);
   void              SetLevelStyle(const int index);
   void              SetLevelWidth(const int index);
   void              SetLevelValue(const int index);
   void              SetLevelText(const int index);
//--- Read and set the BMP file name for the "Bitmap Level" object. Index: 0 - ON, 1 - OFF
   void              SetBMPFile(const int index);

public:

クラスのpublicセクションで、バインドされたグラフィカルオブジェクトのリストを処理するためのメソッド接続されたピボットポイントのオブジェクトを追加します。

//--- Set the object previous name
   bool              SetNamePrev(const string name)
                       {
                        if(!this.Prop.SetSizeRange(GRAPH_OBJ_PROP_NAME,this.Prop.CurrSize(GRAPH_OBJ_PROP_NAME)+1))
                           return false;
                        this.SetProperty(GRAPH_OBJ_PROP_NAME,this.Prop.CurrSize(GRAPH_OBJ_PROP_NAME)-1,name);
                        return true;
                       }
                       
//--- Return (1) the list of dependent objects and (2) dependent graphical object by index
   CArrayObj        *GetListDependentObj(void)        { return &this.m_list;           }
   CGStdGraphObj    *GetDependentObj(const int index) { return this.m_list.At(index);  }
//--- Return the name of the dependent object by index
   string            NameDependent(const int index);
//--- Add the dependent graphical object to the list
   bool              AddDependentObj(CGStdGraphObj *obj);

//--- Return the object of data on pivot points
   CLinkedPivotPoint*GetLinkedPivotPoint(void)        { return &this.m_linked_pivots;  }
   
//--- Add a new pivot point for calculating X and Y coordinates to the current object
   bool              AddNewLinkedPivotPointXY(const int pivot_prop_x,const int pivot_num_x,const int pivot_prop_y,const int pivot_num_y)
                       {
                        //--- If the current object is not bound to the base one, display the appropriate message and return 'false'
                        if(this.BaseObjectID()==0)
                          {
                           CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_EXT_NOT_ATACHED_TO_BASE);
                           return false;
                          }
                        //--- Return the result of adding a new connected pivot point from the CLinkedPivotPoint class to the current object
                        return this.m_linked_pivots.CreateNewLinkedPivotPoint(pivot_prop_x,pivot_num_x,pivot_prop_y,pivot_num_y);
                       }
//--- Add a new pivot point for calculating X and Y coordinates to the specified object
   bool              AddNewLinkedPivotPointXY(CGStdGraphObj *obj,const int pivot_prop_x,const int pivot_num_x,const int pivot_prop_y,const int pivot_num_y)
                       {
                        //--- If the current object is not an extended one, display the appropriate message and return 'false'
                        if(this.TypeGraphElement()!=GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)
                          {
                           CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_NOT_EXT_OBJ);
                           return false;
                          }
                        //--- If a zero pointer to the object is passed, return 'false'
                        if(obj==NULL)
                           return false;
                        //--- Return the result of adding a new connected pivot point from the CLinkedPivotPoint class to the specified object
                        return obj.AddNewLinkedPivotPointXY(pivot_prop_x,pivot_num_x,pivot_prop_y,pivot_num_y);
                       }
                       
//--- Add the new base object anchor point for calculating the X coordinate
   bool              AddNewBaseLinkedPivotX(const int index,const int pivot_prop,const int pivot_num)
                       {
                        //--- If the current object is not bound to the base one, display the appropriate message and return 'false'
                        if(this.BaseObjectID()==0)
                          {
                           CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_EXT_NOT_ATACHED_TO_BASE);
                           return false;
                          }
                        //--- Get the pointer to the necessary pivot point data
                        CPivotPointData *data=m_linked_pivots.GetBasePivotPointDataX(index); 
                        if(data==NULL)
                           return false;
                        //--- Return the result of adding a new anchor point to the current object
                        return data.AddNewBasePivotPoint(DFUN,pivot_prop,pivot_num);
                       }
//--- Add the new base object anchor point for calculating the Y coordinate
   bool              AddNewBaseLinkedPivotY(const int index,const int pivot_prop,const int pivot_num)
                       {
                        //--- If the current object is not bound to the base one, display the appropriate message and return 'false'
                        if(this.BaseObjectID()==0)
                          {
                           CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_EXT_NOT_ATACHED_TO_BASE);
                           return false;
                          }
                        //--- Get the pointer to the necessary pivot point data
                        CPivotPointData *data=m_linked_pivots.GetBasePivotPointDataY(index); 
                        if(data==NULL)
                           return false;
                        //--- Return the result of adding a new anchor point to the current object
                        return data.AddNewBasePivotPoint(DFUN,pivot_prop,pivot_num);
                       }

//--- Add the new base object anchor point for calculating the X coordinate to the specified subordinate graphical object
   bool              AddNewBaseLinkedPivotX(CGStdGraphObj *obj,const int index,const int pivot_prop,const int pivot_num)
                       {
                        //--- If the current object is not an extended one, display the appropriate message and return 'false'
                        if(this.TypeGraphElement()!=GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)
                          {
                           CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_NOT_EXT_OBJ);
                           return false;
                          }
                        //--- If a zero pointer to the object is passed, return 'false'
                        if(obj==NULL)
                           return false;
                        //--- Return the result of adding a new anchor point to the specified object
                        return obj.AddNewBaseLinkedPivotX(index,pivot_prop,pivot_num);
                       }
//--- Add the new base object anchor point for calculating the Y coordinate to the specified subordinate graphical object
   bool              AddNewBaseLinkedPivotY(CGStdGraphObj *obj,const int index,const int pivot_prop,const int pivot_num)
                       {
                        //--- If the current object is not an extended one, display the appropriate message and return 'false'
                        if(this.TypeGraphElement()!=GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)
                          {
                           CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_NOT_EXT_OBJ);
                           return false;
                          }
                        //--- If a zero pointer to the object is passed, return 'false'
                        if(obj==NULL)
                           return false;
                        //--- Return the result of adding a new anchor point to the specified object
                        return obj.AddNewBaseLinkedPivotY(index,pivot_prop,pivot_num);
                       }

//--- Return the number of base object pivot points for calculating the (1) X and (2) Y coordinate in the current object
   int               GetBasePivotsNumX(const int index)           { return this.m_linked_pivots.GetBasePivotsNumX(index);  }
   int               GetBasePivotsNumY(const int index)           { return this.m_linked_pivots.GetBasePivotsNumY(index);  }
//--- Return the number of base object pivot points for calculating the (1) X and (2) Y coordinate in the specified object
   int               GetBasePivotsNumX(CGStdGraphObj *obj,const int index) const { return(obj!=NULL ? obj.GetBasePivotsNumX(index): 0); }
   int               GetBasePivotsNumY(CGStdGraphObj *obj,const int index) const { return(obj!=NULL ? obj.GetBasePivotsNumY(index): 0); }
//--- Return the number of base object pivot points for calculating the coordinates in the (1) current (2) object
   int               GetLinkedPivotsNum(void)               const { return this.m_linked_pivots.GetNumLinkedPivotPoints(); }
   int               GetLinkedPivotsNum(CGStdGraphObj *obj) const { return(obj!=NULL ? obj.GetLinkedPivotsNum() : 0);      }
   
//--- Default constructor
                     CGStdGraphObj(){ this.m_type=OBJECT_DE_TYPE_GSTD_OBJ; this.m_species=WRONG_VALUE; }
//--- Destructor
                    ~CGStdGraphObj()
                       {
                        if(this.Prop!=NULL)
                           delete this.Prop;
                       }
protected:

すべてのメソッドは、以前に検討されたクラスの同じ名前のメソッドを呼び出した結果を返し、これらのオブジェクトを操作するためのアクセスを提供します。一部のメソッドはコードでコメント化されているため、すべてが明確である必要があります。質問がある場合は、コメント欄でお気軽にお問い合わせください。

protectedパラメトリックコンストラクタは作成されたグラフィカル要素のタイプを受け取るようになりました

//--- Default constructor
                     CGStdGraphObj(){ this.m_type=OBJECT_DE_TYPE_GSTD_OBJ; this.m_species=WRONG_VALUE; }
//--- Destructor
                    ~CGStdGraphObj()
                       {
                        if(this.Prop!=NULL)
                           delete this.Prop;
                       }
protected:
//--- Protected parametric constructor
                     CGStdGraphObj(const ENUM_OBJECT_DE_TYPE obj_type,
                                   const ENUM_GRAPH_ELEMENT_TYPE elm_type,
                                   const ENUM_GRAPH_OBJ_BELONG belong,
                                   const ENUM_GRAPH_OBJ_SPECIES species,
                                   const long chart_id, const int pivots,
                                   const string name);
                     
public:

オブジェクトを作成するときに、ENUM_GRAPH_ELEMENT_TYPE列挙型からGRAPH_ELEMENT_TYPE_STANDARD_EXTENDEDを要素タイプとして渡すことにより、拡張された標準グラフィカルオブジェクトを作成するように指定できるようになりました。これは、その子孫クラスのコンストラクタで行われます。

簡略化されたアクセスとグラフィカルオブジェクトプロパティの設定のためのメソッドのブロックに、基本オブジェクトIDを処理するためのメソッド基本オブジェクト名を処理するためのメソッドを追加します。

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,0);                            }
   void              SetNumber(const int number)         { this.SetProperty(GRAPH_OBJ_PROP_NUM,0,number);                                 }
//--- Flag of storing the change history
   bool              AllowChangeHistory(void)      const { return (bool)this.GetProperty(GRAPH_OBJ_PROP_CHANGE_HISTORY,0);                }
   void              SetAllowChangeMemory(const bool flag){ this.SetProperty(GRAPH_OBJ_PROP_CHANGE_HISTORY,0,flag);                       }
//--- Object ID
   long              ObjectID(void)                const { return this.GetProperty(GRAPH_OBJ_PROP_ID,0);                                  }
   void              SetObjectID(const long obj_id)
                       {
                        CGBaseObj::SetObjectID(obj_id);
                        this.SetProperty(GRAPH_OBJ_PROP_ID,0,obj_id);
                        this.SetPropertyPrev(GRAPH_OBJ_PROP_ID,0,obj_id);
                       }
//--- Base object ID
   long              BaseObjectID(void)            const { return this.GetProperty(GRAPH_OBJ_PROP_BASE_ID,0);                                  }
   void              SetBaseObjectID(const long obj_id)
                       {
                        this.SetProperty(GRAPH_OBJ_PROP_BASE_ID,0,obj_id);
                        this.SetPropertyPrev(GRAPH_OBJ_PROP_BASE_ID,0,obj_id);
                       }
//--- Graphical object type
   ENUM_OBJECT       GraphObjectType(void)         const { return (ENUM_OBJECT)this.GetProperty(GRAPH_OBJ_PROP_TYPE,0);                   }
   void              SetGraphObjectType(const ENUM_OBJECT obj_type)
                       {
                        CGBaseObj::SetTypeGraphObject(obj_type);
                        this.SetProperty(GRAPH_OBJ_PROP_TYPE,0,obj_type);
                       }

...

//--- Object name
   string            Name(void)                    const { return this.GetProperty(GRAPH_OBJ_PROP_NAME,0);                                }
   bool              SetName(const string name)
                       {
                        if(CGBaseObj::Name()==name)
                           return true;
                        if(CGBaseObj::Name()=="")
                          {
                           CGBaseObj::SetName(name);
                           this.SetProperty(GRAPH_OBJ_PROP_NAME,0,name);
                           return true;
                          }
                        else
                          {
                           if(!::ObjectSetString(CGBaseObj::ChartID(),CGBaseObj::Name(),OBJPROP_NAME,name))
                              return false;
                           CGBaseObj::SetName(name);
                           this.SetProperty(GRAPH_OBJ_PROP_NAME,0,name);
                           return true;
                          }
                       }
//--- Base object name
   string            BaseName(void)                const { return this.GetProperty(GRAPH_OBJ_PROP_BASE_NAME,0);                           }
   bool              SetBaseName(const string name)
                       {
                        this.SetProperty(GRAPH_OBJ_PROP_BASE_NAME,0,name);
                        return true;
                       }
//--- Object description (text contained in the object)

このメソッドを使用すると、基本オブジェクトIDと名前をオブジェクトプロパティに設定し、データを返すことができます。

次に、オブジェクトインデックスの説明をバインドされたグラフィカルオブジェクトのリストに返すメソッドの宣言を挿入します

//--- Return the flags indicating object visibility on timeframes
   bool              IsVisibleOnTimeframeM1(void)  const { return IsVisibleOnTimeframe(PERIOD_M1, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM2(void)  const { return IsVisibleOnTimeframe(PERIOD_M2, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM3(void)  const { return IsVisibleOnTimeframe(PERIOD_M3, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM4(void)  const { return IsVisibleOnTimeframe(PERIOD_M4, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM5(void)  const { return IsVisibleOnTimeframe(PERIOD_M5, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM6(void)  const { return IsVisibleOnTimeframe(PERIOD_M6, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM10(void) const { return IsVisibleOnTimeframe(PERIOD_M10,(int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM12(void) const { return IsVisibleOnTimeframe(PERIOD_M12,(int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM15(void) const { return IsVisibleOnTimeframe(PERIOD_M15,(int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM20(void) const { return IsVisibleOnTimeframe(PERIOD_M20,(int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeM30(void) const { return IsVisibleOnTimeframe(PERIOD_M30,(int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeH1(void)  const { return IsVisibleOnTimeframe(PERIOD_H1, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeH2(void)  const { return IsVisibleOnTimeframe(PERIOD_H2, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeH3(void)  const { return IsVisibleOnTimeframe(PERIOD_H3, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeH4(void)  const { return IsVisibleOnTimeframe(PERIOD_H4, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeH6(void)  const { return IsVisibleOnTimeframe(PERIOD_H6, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeH8(void)  const { return IsVisibleOnTimeframe(PERIOD_H8, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeH12(void) const { return IsVisibleOnTimeframe(PERIOD_H12,(int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeD1(void)  const { return IsVisibleOnTimeframe(PERIOD_D1, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeW1(void)  const { return IsVisibleOnTimeframe(PERIOD_W1, (int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }
   bool              IsVisibleOnTimeframeMN1(void) const { return IsVisibleOnTimeframe(PERIOD_MN1,(int)this.GetProperty(GRAPH_OBJ_PROP_TIMEFRAMES,0)); }

//--- Return the description of the (1) object visibility on timeframes and (2) the index in the composite graphical object list
   string            VisibleOnTimeframeDescription(void);
   string            NumberDescription(void);

//--- Re-write all graphical object properties


protectedパラメトリックコンストラクタで、グラフィカル要素タイプの変数を追加し、渡された値を基本グラフィカルオブジェクトに書き込みます、 また、上記で作成した新しいグラフィカルオブジェクトプロパティのデフォルト値を設定します。

//+------------------------------------------------------------------+
//| Protected parametric constructor                                 |
//+------------------------------------------------------------------+
CGStdGraphObj::CGStdGraphObj(const ENUM_OBJECT_DE_TYPE obj_type,
                             const ENUM_GRAPH_ELEMENT_TYPE elm_type,
                             const ENUM_GRAPH_OBJ_BELONG belong,
                             const ENUM_GRAPH_OBJ_SPECIES species,
                             const long chart_id,const int pivots,
                             const string name)
  {
   //--- Create the property object with the default values
   this.Prop=new CProperties(GRAPH_OBJ_PROP_INTEGER_TOTAL,GRAPH_OBJ_PROP_DOUBLE_TOTAL,GRAPH_OBJ_PROP_STRING_TOTAL);
   
//--- Set the number of pivot points and object levels
   this.m_pivots=pivots;
   int levels=(int)::ObjectGetInteger(chart_id,name,OBJPROP_LEVELS);

//--- Set the property array dimensionalities according to the number of pivot points and levels
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_TIME,this.m_pivots);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_PRICE,this.m_pivots);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELCOLOR,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELSTYLE,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELWIDTH,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELVALUE,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_LEVELTEXT,levels);
   this.Prop.SetSizeRange(GRAPH_OBJ_PROP_BMPFILE,2);
   
//--- 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;
   this.SetName(name);
   CGBaseObj::SetChartID(chart_id);
   CGBaseObj::SetTypeGraphObject(CGBaseObj::GraphObjectType(obj_type));
   CGBaseObj::SetTypeElement(elm_type);
   CGBaseObj::SetBelong(belong);
   CGBaseObj::SetSpecies(species);
   CGBaseObj::SetSubwindow(chart_id,name);
   CGBaseObj::SetDigits((int)::SymbolInfoInteger(::ChartSymbol(chart_id),SYMBOL_DIGITS));
   
//--- Save the integer properties inherent in all graphical objects but not present in the current one
   this.SetProperty(GRAPH_OBJ_PROP_CHART_ID,0,CGBaseObj::ChartID());                // Chart ID
   this.SetProperty(GRAPH_OBJ_PROP_WND_NUM,0,CGBaseObj::SubWindow());               // Chart subwindow index
   this.SetProperty(GRAPH_OBJ_PROP_TYPE,0,CGBaseObj::TypeGraphObject());            // Graphical object type (ENUM_OBJECT)
   this.SetProperty(GRAPH_OBJ_PROP_ELEMENT_TYPE,0,CGBaseObj::TypeGraphElement());   // Graphical element type (ENUM_GRAPH_ELEMENT_TYPE)
   this.SetProperty(GRAPH_OBJ_PROP_BELONG,0,CGBaseObj::Belong());                   // Graphical object affiliation
   this.SetProperty(GRAPH_OBJ_PROP_SPECIES,0,CGBaseObj::Species());                 // Graphical object species
   this.SetProperty(GRAPH_OBJ_PROP_GROUP,0,0);                                      // Graphical object group
   this.SetProperty(GRAPH_OBJ_PROP_ID,0,0);                                         // Object ID
   this.SetProperty(GRAPH_OBJ_PROP_BASE_ID,0,0);                                    // Base object ID
   this.SetProperty(GRAPH_OBJ_PROP_NUM,0,0);                                        // Object index in the list
   this.SetProperty(GRAPH_OBJ_PROP_CHANGE_HISTORY,0,false);                         // Flag of storing the change history
   this.SetProperty(GRAPH_OBJ_PROP_BASE_NAME,0,this.Name());                        // Base object name
   
//--- Save the properties inherent in all graphical objects and present in a graphical object
   this.PropertiesRefresh();
   
//--- Save basic properties in the parent object
   this.m_create_time=(datetime)this.GetProperty(GRAPH_OBJ_PROP_CREATETIME,0);
   this.m_back=(bool)this.GetProperty(GRAPH_OBJ_PROP_BACK,0);
   this.m_selected=(bool)this.GetProperty(GRAPH_OBJ_PROP_SELECTED,0);
   this.m_selectable=(bool)this.GetProperty(GRAPH_OBJ_PROP_SELECTABLE,0);
   this.m_hidden=(bool)this.GetProperty(GRAPH_OBJ_PROP_HIDDEN,0);

//--- Save the current properties to the previous ones
   this.PropertiesCopyToPrevData();
  }
//+-------------------------------------------------------------------+

デフォルトでは、基本オブジェクトIDはゼロ(存在しない)ですが、基本オブジェクト名は現在のグラフィカルオブジェクトの名前と同じです。つまり、オブジェクトはそれ自体を指し、基本オブジェクトへの接続がないことを意味します。

オブジェクト整数プロパティの説明を返すメソッドで、基本オブジェクトIDの説明の表示を追加します。バインドされたオブジェクトのリストでオブジェクトインデックスの説明を返すブロックで、メソッドの呼び出しを追加してそれを実行します(少し後で追加されます)。

//+------------------------------------------------------------------+
//| 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,0)
         )  :
      property==GRAPH_OBJ_PROP_BASE_ID    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_BASE_ID)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property,0)
         )  :
      property==GRAPH_OBJ_PROP_TYPE       ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_TYPE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.TypeDescription()
         )  :
      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_SPECIES    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_SPECIES)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+CGBaseObj::SpeciesDescription()
         )  :
      property==GRAPH_OBJ_PROP_GROUP    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_GROUP)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(CGBaseObj::Group()>0 ? (string)this.GetProperty(property,0) : CMessage::Text(MSG_LIB_PROP_EMPTY))
         )  :
      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,0)
         )  :
      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,0)
         )  :
      property==GRAPH_OBJ_PROP_CHANGE_HISTORY ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_CHANGE_MEMORY)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property,0) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO))
         )  :
      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,0),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) :
          ": "+this.VisibleOnTimeframeDescription()
         )  :
      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,0)
         )  :
      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) :
          ": "+this.NumberDescription()
         )  :
      property==GRAPH_OBJ_PROP_TIME       ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_TIME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+"\n"+this.TimesDescription()
         )  :
      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,0),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,0))
         )  :
      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,0)
         )  :
      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,0) ? 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,0) ? 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,0)
         )  :
      property==GRAPH_OBJ_PROP_LEVELCOLOR ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELCOLOR)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ":\n"+this.LevelsColorDescription()
         )  :
      property==GRAPH_OBJ_PROP_LEVELSTYLE ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELSTYLE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ":\n"+this.LevelsStyleDescription()
         )  :
      property==GRAPH_OBJ_PROP_LEVELWIDTH ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELWIDTH)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ":\n"+this.LevelsWidthDescription()
         )  :
      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,0))
         )  :
      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,0)
         )  :
      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,0) ? 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,0) ? 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,0) ? 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,0) ? 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,0)
         )  :
      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,0)
         )  :
      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,0)
         )  :
      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,0))
         )  :
      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,0))
         )  :
      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,0) ? 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,0) ? CMessage::Text(MSG_LIB_TEXT_BUTTON_STATE_PRESSED) : CMessage::Text(MSG_LIB_TEXT_BUTTON_STATE_DEPRESSED))
         )  :
      property==GRAPH_OBJ_PROP_CHART_OBJ_CHART_ID  ?  CMessage::Text(MSG_CHART_OBJ_ID)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property,0)
         )  :
      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,0))
         )  :
      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,0) ? 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,0) ? 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,0)
         )  :
      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,0)
         )  :
      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,0)
         )  :
      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,0)
         )  :
      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,0)
         )  :
      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,0),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,0))
         )  :
      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,0))
         )  :
      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,0),true)
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+


オブジェクト文字列プロパティの説明を返すメソッドに、基本オブジェクト名の説明を返すためのコードブロックを追加します

//+------------------------------------------------------------------+
//| 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,0)+"\""
         )  :
      property==GRAPH_OBJ_PROP_BASE_NAME  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_BASE_NAME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+"\""+this.GetProperty(property,0)+"\""
         )  :
      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,0)=="" ? CMessage::Text(MSG_LIB_PROP_EMPTY) : "\""+this.GetProperty(property,0)+"\"")
         )  :
      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,0)=="" ? CMessage::Text(MSG_LIB_PROP_AUTO) : 
                this.GetProperty(property,0)=="\n" ? CMessage::Text(MSG_LIB_PROP_EMPTY) :
                "\""+this.GetProperty(property,0)+"\"")
         )  :
      property==GRAPH_OBJ_PROP_LEVELTEXT  ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_LEVELTEXT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ":\n"+this.LevelsTextDescription()
         )  :
      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,0)+"\""
         )  :
      property==GRAPH_OBJ_PROP_BMPFILE    ?  CMessage::Text(MSG_GRAPH_OBJ_PROP_BMPFILE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ":\n"+this.BMPFilesDescription()
         )  :
      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,0)
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+


以下は、複合グラフィカルオブジェクトのオブジェクトのリストでグラフィカルオブジェクトインデックスの説明を返すメソッドです。

//+------------------------------------------------------------------+
//| Return the description of the graphical object index             |
//| in the list of objects of a composite graphical object           |
//+------------------------------------------------------------------+
string CGStdGraphObj::NumberDescription(void)
  {
   if(CGBaseObj::TypeGraphElement()==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)
     {
      if(this.Number()==0)
         return CMessage::Text(MSG_GRAPH_OBJ_PROP_NUM_EXT_BASE_OBJ);
     }
   return (string)this.Number();
  }
//+------------------------------------------------------------------+

拡張された標準グラフィカルオブジェクトの場合そのインデックスを確認します。ゼロに等しい場合「拡張グラフィカルオブジェクトの基本オブジェクト」というテキストを表示します。それ以外の場合、インデックスはオブジェクトのプロパティに記述された文字列として表示されます。


以下は、インデックスによって従属するグラフィカルオブジェクトの名前を返すメソッドです

//+------------------------------------------------------------------+
//| Return the name of a subordinate graphical object by index       |
//+------------------------------------------------------------------+
string CGStdGraphObj::NameDependent(const int index)
  {
   CGStdGraphObj *obj=this.GetDependentObj(index);
   return(obj!=NULL ? obj.Name() : "");
  }
//+------------------------------------------------------------------+

指定されたインデックスでリスト内の接続されたグラフィカルオブジェクトへのポインタを取得しその名前を返しますオブジェクトの取得に失敗した場合は、空の文字列を返します

以下は、下位の標準グラフィカルオブジェクトをリストに追加するメソッドです。

//+------------------------------------------------------------------+
//| Add a subordinate standard graphical object to the list          |
//+------------------------------------------------------------------+
bool CGStdGraphObj::AddDependentObj(CGStdGraphObj *obj)
  {
   //--- If the current object is not an extended one, inform of that and return 'false'
   if(this.TypeGraphElement()!=GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)
     {
      CMessage::ToLog(MSG_GRAPH_OBJ_NOT_EXT_OBJ);
      return false;
     }
   //--- If failed to add the pointer to the passed object into the list, inform of that and return 'false'
   if(!this.m_list.Add(obj))
     {
      CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_FAILED_ADD_DEP_EXT_OBJ_TO_LIST);
      return false;
     }
   //--- Object added to the list - set its number in the list,
   //--- name and ID of the current object as the base one
   obj.SetNumber(this.m_list.Total()-1);
   obj.SetBaseName(this.Name());
   obj.SetBaseObjectID(this.ObjectID());
   return true;
  }
//+------------------------------------------------------------------+

拡張されていないすべてのグラフィカルオブジェクトは、依存オブジェクトを操作できません。したがって、変更が必要な依存オブジェクトへのポインタを受け取るすべてのメソッドをチェックする必要があります。オブジェクトが拡張されていない場合、適切なメッセージが表示され、メソッドはfalseを返します。同様に、依存オブジェクトパラメータを処理する現在のオブジェクトのメソッドで、オブジェクトが従属しているかどうか(ベースオブジェクトにバインドされているかどうか)のチェックを実行する必要があります。オブジェクトがバインドされていない場合、それは従属ではありません。適切なメッセージが表示され、falseが返されます。

これが行われるのは、任意のグラフィカルオブジェクトが同時にベースまたは従属またはベースと従属のいずれかになる可能性があるためです。したがって、それ自体の依存オブジェクトを処理するためのメソッド(基本オブジェクトモード)と、外部からそのプロパティを変更するためのメソッド(依存オブジェクトモード)を備えています。


\MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqhのグラフィカル要素のコレクションクラスを改善しましょう。

チャートオブジェクトを管理するためのクラスのpublicセクションで、標準グラフィカルオブジェクトクラスの新しいオブジェクトを作成するメソッドに、拡張グラフィカルオブジェクトを作成する必要があることを示すフラグを追加します。

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;    }
//--- Create a new standard (or extended) graphical object
   CGStdGraphObj    *CreateNewGraphObj(const ENUM_OBJECT obj_type,const string name,const bool extended);
//--- Return the list of newly added objects

チャートオブジェクトをチェックするクラスのメソッドで、新しいオブジェクトを作成するときにfalseを設定します

//+------------------------------------------------------------------+
//| CChartObjectsControl: Check objects on a chart                   |
//+------------------------------------------------------------------+
void CChartObjectsControl::Refresh(void)
  {
//--- Clear the list of newly added objects
   this.m_list_new_graph_obj.Clear();
//--- Calculate the number of new 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 an object is added to the chart

   if(this.m_delta_graph_obj>0)
     {
      //--- Create the list of added graphical objects
      for(int i=0;i<this.m_delta_graph_obj;i++)
        {
         //--- Get the name of the last added object (if a single new object is added),
         //--- or a name from the terminal object list by index (if several objects have been added)
         string name=(this.m_delta_graph_obj==1 ? this.LastAddedGraphObjName() : ::ObjectName(this.m_chart_id,i));
         //--- Handle only non-programmatically created objects
         if(name==NULL || ::StringFind(name,this.m_name_program)>WRONG_VALUE)
            continue;
         //--- Create the object of the graphical object class corresponding to the added graphical object type
         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=this.CreateNewGraphObj(type,name,false);
         //--- If failed to create an object, inform of that and move on to the new iteration
         if(obj==NULL)
           {
            CMessage::ToLog(DFUN,MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_CLASS_OBJ);
            continue;
           }
         //--- Set the object affiliation and add the created object to the list of new objects
         obj.SetBelong(GRAPH_OBJ_BELONG_NO_PROGRAM); 
         //--- If failed to add the object to the list, inform of that, remove the object and move on to the next iteration
         if(!this.m_list_new_graph_obj.Add(obj))
           {
            CMessage::ToLog(DFUN_ERR_LINE,MSG_LIB_SYS_FAILED_OBJ_ADD_TO_LIST);
            delete obj;
            continue;
           }
        }
      //--- Send events to the control program chart from the created list
      for(int i=0;i<this.m_list_new_graph_obj.Total();i++)
        {
         CGStdGraphObj *obj=this.m_list_new_graph_obj.At(i);
         if(obj==NULL)
            continue;
         //--- Send an event to the control program chart
         ::EventChartCustom(this.m_chart_id_main,GRAPH_OBJ_EVENT_CREATE,this.ChartID(),obj.TimeCreate(),obj.Name());
        }
     }
//--- 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;
  }
//+------------------------------------------------------------------+

このメソッドは、チャート上でのグラフィカルオブジェクトの手動作成のみを追跡するため、グラフィカルオブジェクトクラスのオブジェクトを拡張しません。したがって、通常の標準グラフィカルオブジェクトを作成するためのメソッドにfalseフラグを渡します。

新しい標準グラフィカルオブジェクトを作成するメソッドで、拡張グラフィカルオブジェクトのフラグを入力に追加します。次のフラグは、標準グラフィカルオブジェクトクラスの新しいオブジェクトを作成するすべての文字列に渡されます。

//+------------------------------------------------------------------+
//| CChartObjectsControl:                                            |
//| Create a new standard graphical object                           |
//+------------------------------------------------------------------+
CGStdGraphObj *CChartObjectsControl::CreateNewGraphObj(const ENUM_OBJECT obj_type,const string name,const bool extended)
  {

   switch((int)obj_type)
     {
      //--- Lines
      case OBJ_VLINE             : return new CGStdVLineObj(this.ChartID(),name,extended);
      case OBJ_HLINE             : return new CGStdHLineObj(this.ChartID(),name,extended);
      case OBJ_TREND             : return new CGStdTrendObj(this.ChartID(),name,extended);
      case OBJ_TRENDBYANGLE      : return new CGStdTrendByAngleObj(this.ChartID(),name,extended);
      case OBJ_CYCLES            : return new CGStdCyclesObj(this.ChartID(),name,extended);
      case OBJ_ARROWED_LINE      : return new CGStdArrowedLineObj(this.ChartID(),name,extended);
      //--- Channels
      case OBJ_CHANNEL           : return new CGStdChannelObj(this.ChartID(),name,extended);
      case OBJ_STDDEVCHANNEL     : return new CGStdStdDevChannelObj(this.ChartID(),name,extended);
      case OBJ_REGRESSION        : return new CGStdRegressionObj(this.ChartID(),name,extended);
      case OBJ_PITCHFORK         : return new CGStdPitchforkObj(this.ChartID(),name,extended);
      //--- Gann
      case OBJ_GANNLINE          : return new CGStdGannLineObj(this.ChartID(),name,extended);
      case OBJ_GANNFAN           : return new CGStdGannFanObj(this.ChartID(),name,extended);
      case OBJ_GANNGRID          : return new CGStdGannGridObj(this.ChartID(),name,extended);
      //--- Fibo
      case OBJ_FIBO              : return new CGStdFiboObj(this.ChartID(),name,extended);
      case OBJ_FIBOTIMES         : return new CGStdFiboTimesObj(this.ChartID(),name,extended);
      case OBJ_FIBOFAN           : return new CGStdFiboFanObj(this.ChartID(),name,extended);
      case OBJ_FIBOARC           : return new CGStdFiboArcObj(this.ChartID(),name,extended);
      case OBJ_FIBOCHANNEL       : return new CGStdFiboChannelObj(this.ChartID(),name,extended);
      case OBJ_EXPANSION         : return new CGStdExpansionObj(this.ChartID(),name,extended);
      //--- Elliott
      case OBJ_ELLIOTWAVE5       : return new CGStdElliotWave5Obj(this.ChartID(),name,extended);
      case OBJ_ELLIOTWAVE3       : return new CGStdElliotWave3Obj(this.ChartID(),name,extended);
      //--- Shapes
      case OBJ_RECTANGLE         : return new CGStdRectangleObj(this.ChartID(),name,extended);
      case OBJ_TRIANGLE          : return new CGStdTriangleObj(this.ChartID(),name,extended);
      case OBJ_ELLIPSE           : return new CGStdEllipseObj(this.ChartID(),name,extended);
      //--- Arrows
      case OBJ_ARROW_THUMB_UP    : return new CGStdArrowThumbUpObj(this.ChartID(),name,extended);
      case OBJ_ARROW_THUMB_DOWN  : return new CGStdArrowThumbDownObj(this.ChartID(),name,extended);
      case OBJ_ARROW_UP          : return new CGStdArrowUpObj(this.ChartID(),name,extended);
      case OBJ_ARROW_DOWN        : return new CGStdArrowDownObj(this.ChartID(),name,extended);
      case OBJ_ARROW_STOP        : return new CGStdArrowStopObj(this.ChartID(),name,extended);
      case OBJ_ARROW_CHECK       : return new CGStdArrowCheckObj(this.ChartID(),name,extended);
      case OBJ_ARROW_LEFT_PRICE  : return new CGStdArrowLeftPriceObj(this.ChartID(),name,extended);
      case OBJ_ARROW_RIGHT_PRICE : return new CGStdArrowRightPriceObj(this.ChartID(),name,extended);
      case OBJ_ARROW_BUY         : return new CGStdArrowBuyObj(this.ChartID(),name,extended);
      case OBJ_ARROW_SELL        : return new CGStdArrowSellObj(this.ChartID(),name,extended);
      case OBJ_ARROW             : return new CGStdArrowObj(this.ChartID(),name,extended);
      //--- Graphical objects
      case OBJ_TEXT              : return new CGStdTextObj(this.ChartID(),name,extended);
      case OBJ_LABEL             : return new CGStdLabelObj(this.ChartID(),name,extended);
      case OBJ_BUTTON            : return new CGStdButtonObj(this.ChartID(),name,extended);
      case OBJ_CHART             : return new CGStdChartObj(this.ChartID(),name,extended);
      case OBJ_BITMAP            : return new CGStdBitmapObj(this.ChartID(),name,extended);
      case OBJ_BITMAP_LABEL      : return new CGStdBitmapLabelObj(this.ChartID(),name,extended);
      case OBJ_EDIT              : return new CGStdEditObj(this.ChartID(),name,extended);
      case OBJ_EVENT             : return new CGStdEventObj(this.ChartID(),name,extended);
      case OBJ_RECTANGLE_LABEL   : return new CGStdRectangleLabelObj(this.ChartID(),name,extended);
      default                    : return NULL;
     }
  }
//+------------------------------------------------------------------+

これで、標準グラフィカルオブジェクトクラスのオブジェクトを作成するときに、構築されたオブジェクトのタイプ(通常または拡張)をすぐに指定できるようになりました。通常のグラフィカルオブジェクトを拡張オブジェクトに、またはその逆にいつでも変換できます。

グラフィカル要素のコレクションクラスのprivateセクションで、新しい標準グラフィカルオブジェクトを作成し、作成されたオブジェクトの名前をクラスリストから返すメソッドを削除します。メソッドはサービス関数ファイルに再配置されるため、グラフィカルオブジェクトのコレクションクラスに基づいているか、他のクラスに基づいているか、プログラム自体に基づいているかに関係なく、チャート上に任意のグラフィカルオブジェクトを常に作成できます。

//+------------------------------------------------------------------+
//| Collection of graphical objects                                  |
//+------------------------------------------------------------------+
#resource "\\"+PATH_TO_EVENT_CTRL_IND;          // Indicator for controlling graphical object events packed into the program resources
class CGraphElementsCollection : public CBaseObj
  {
private:
   CArrayObj         m_list_charts_control;     // List of chart management objects
   CListObj          m_list_all_canv_elm_obj;   // List of all graphical elements on canvas
   CListObj          m_list_all_graph_obj;      // List of all graphical objects
   CArrayObj         m_list_deleted_obj;        // List of removed graphical objects
   bool              m_is_graph_obj_event;      // Event flag in the list of graphical objects
   int               m_total_objects;           // Number of graphical objects
   int               m_delta_graph_obj;         // Difference in the number of graphical objects compared to the previous check
   
//--- Return the flag indicating the graphical element class object presence in the collection list of graphical elements
   bool              IsPresentGraphElmInList(const int id,const ENUM_GRAPH_ELEMENT_TYPE type_obj);
//--- Return the flag indicating the presence of the graphical object class in the graphical object collection list
   bool              IsPresentGraphObjInList(const long chart_id,const string name);
//--- Return the flag indicating the presence of a graphical object on a chart by name
   bool              IsPresentGraphObjOnChart(const long chart_id,const string name);
//--- Return the pointer to the object of managing objects of the specified chart
   CChartObjectsControl *GetChartObjectCtrlObj(const long chart_id);
//--- Create a new object of managing graphical objects of a specified chart and add it to the list
   CChartObjectsControl *CreateChartObjectCtrlObj(const long chart_id);
//--- Update the list of graphical objects by chart ID
   CChartObjectsControl *RefreshByChartID(const long chart_id);
//--- Check if the chart window is present
   bool              IsPresentChartWindow(const long chart_id);
//--- Handle removing the chart window
   void              RefreshForExtraObjects(void);
//--- Return the first free ID of the graphical (1) object and (2) element on canvas
   long              GetFreeGraphObjID(bool program_object);
   long              GetFreeCanvElmID(void);
//--- Add a graphical object to the collection
   bool              AddGraphObjToCollection(const string source,CChartObjectsControl *obj_control);
//--- Find an object present in the collection but not on a chart
   CGStdGraphObj    *FindMissingObj(const long chart_id);
   CGStdGraphObj    *FindMissingObj(const long chart_id,int &index);
//--- Find the graphical object present on a chart but not in the collection
   string            FindExtraObj(const long chart_id);
//--- Remove the graphical object class object from the graphical object collection list: (1) specified object, (2) by chart ID
   bool              DeleteGraphObjFromList(CGStdGraphObj *obj);
   void              DeleteGraphObjectsFromList(const long chart_id);
//--- Move the graphical object class object to the list of removed graphical objects: (1) specified object, (2) by index
   bool              MoveGraphObjToDeletedObjList(CGStdGraphObj *obj);
   bool              MoveGraphObjToDeletedObjList(const int index);
//--- Move all objects by chart ID to the list of removed graphical objects
   void              MoveGraphObjectsToDeletedObjList(const long chart_id);
//--- Remove the object of managing charts from the list
   bool              DeleteGraphObjCtrlObjFromList(CChartObjectsControl *obj);
//--- Create a new standard graphical object, return an object name
   bool              CreateNewStdGraphObject(const long chart_id,
                                             const string name,
                                             const ENUM_OBJECT type,
                                             const int subwindow,
                                             const datetime time1,
                                             const double price1,
                                             const datetime time2=0,
                                             const double price2=0,
                                             const datetime time3=0,
                                             const double price3=0,
                                             const datetime time4=0,
                                             const double price4=0,
                                             const datetime time5=0,
                                             const double price5=0);
public:


クラスのpublicセクションで、標準および拡張グラフィカルオブジェクトのリストを返す2つのメソッドを設定します。

//--- Return an (1) existing and (2) removed graphical object by chart name and ID
   CGStdGraphObj    *GetStdGraphObject(const string name,const long chart_id);
   CGStdGraphObj    *GetStdDelGraphObject(const string name,const long chart_id);
//--- Return the list of (1) chart management objects and (2) removed graphical objects
   CArrayObj        *GetListChartsControl(void)                                                          { return &this.m_list_charts_control;  }
   CArrayObj        *GetListDeletedObj(void)                                                             { return &this.m_list_deleted_obj;     }
//--- Return the list of (1) standard and (2) extended graphical objects
   CArrayObj        *GetListStdGraphObject(void)                              { return CSelect::ByGraphicStdObjectProperty(this.GetListGraphObj(),GRAPH_OBJ_PROP_ELEMENT_TYPE,0,GRAPH_ELEMENT_TYPE_STANDARD,EQUAL);           }
   CArrayObj        *GetListStdGraphObjectExt(void)                           { return CSelect::ByGraphicStdObjectProperty(this.GetListGraphObj(),GRAPH_OBJ_PROP_ELEMENT_TYPE,0,GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED,EQUAL);  }
//--- Return (1) the last removed graphical object and (2) the array size of graphical object properties

メソッドは、すべてのグラフィカルオブジェクトのリストをグラフィカル要素タイププロパティで並べ替えたときに作成されたリストへのポインタを返すだけです。

新しいグラフィカルオブジェクトを作成し、チャート管理オブジェクトへのポインタを返すprivateメソッドは、クラスコンテキストからではなく、DELib.mqhからグラフィカルオブジェクトを作成するメソッドを呼び出すようになりました(単にメソッド呼び出し文字列から「this.」を削除)

private:
//--- Create a new graphical object, return the pointer to the chart management object
   CChartObjectsControl *CreateNewStdGraphObjectAndGetCtrlObj(const long chart_id,
                                                              const string name,
                                                              int subwindow,
                                                              const ENUM_OBJECT type_object,
                                                              const datetime time1,
                                                              const double price1,
                                                              const datetime time2=0,
                                                              const double price2=0,
                                                              const datetime time3=0,
                                                              const double price3=0,
                                                              const datetime time4=0,
                                                              const double price4=0,
                                                              const datetime time5=0,
                                                              const double price5=0)
                       {
                        //--- If an object with a chart ID and name is already present in the collection, inform of that and return NULL
                        if(this.IsPresentGraphObjInList(chart_id,name))
                          {
                           ::Print(DFUN,CMessage::Text(MSG_GRAPH_ELM_COLLECTION_ERR_GR_OBJ_ALREADY_EXISTS)," ChartID ",(string)chart_id,", ",name);
                           return NULL;
                          }
                        //--- If failed to create a new standard graphical object, inform of that and return NULL
                        if(!CreateNewStdGraphObject(chart_id,name,type_object,subwindow,time1,price1,time2,price2,time3,price3,time4,price4,time5,price5))
                          {
                           ::Print(DFUN,CMessage::Text(MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_STD_GRAPH_OBJ),StdGraphObjectTypeDescription(type_object));
                           CMessage::ToLog(::GetLastError(),true);
                           return NULL;
                          }
                        //--- If failed to get a chart management object, inform of that
                        CChartObjectsControl *ctrl=this.GetChartObjectCtrlObj(chart_id);
                        if(ctrl==NULL)
                           ::Print(DFUN,CMessage::Text(MSG_GRAPH_ELM_COLLECTION_ERR_FAILED_GET_CTRL_OBJ),(string)chart_id);
                        //--- Return the pointer to a chart management object or NULL in case of a failed attempt to get it
                        return ctrl;
                       }


グラフィカルオブジェクトを作成するためのすべてのpublicメソッドに同様の変更を追加します。メソッド入力の拡張オブジェクトフラグおよび標準グラフィカルオブジェクトクラスの新しいオブジェクトを作成するメソッドにフラグを渡します

public:
//--- Create the "Vertical line" graphical object
   bool              CreateLineVertical(const long chart_id,const string name,const int subwindow,const bool extended,const datetime time)
                       {
                        //--- Set the name and type of a created object
                        string nm=this.m_name_program+"_"+name;
                        ENUM_OBJECT type_object=OBJ_VLINE;
                        //--- Create a new graphical object and get the pointer to the chart management object
                        CChartObjectsControl *ctrl=this.CreateNewStdGraphObjectAndGetCtrlObj(chart_id,nm,subwindow,type_object,time,0);
                        if(ctrl==NULL)
                           return false;
                        //--- Create a new class object corresponding to the newly created graphical object
                        CGStdVLineObj *obj=ctrl.CreateNewGraphObj(type_object,nm,extended);
                        if(obj==NULL)
                          {
                           ::Print(DFUN,CMessage::Text(MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_CLASS_OBJ),StdGraphObjectTypeDescription(type_object));
                           return false;
                          }
                        //--- Set the necessary minimal parameters for an object
                        obj.SetBelong(GRAPH_OBJ_BELONG_PROGRAM);
                        obj.SetFlagSelectable(true,false);
                        obj.SetFlagSelected(true,false);
                        obj.SetObjectID(this.GetFreeGraphObjID(true));
                        obj.PropertiesCopyToPrevData();
                        //--- Return the result of adding the object to the list
                        return this.AddCreatedObjToList(DFUN,chart_id,nm,obj);
                       }

//--- Create the "Horizontal line" graphical object
   bool              CreateLineHorizontal(const long chart_id,const string name,const int subwindow,const bool extended,const double price)
                       {
                        string nm=this.m_name_program+"_"+name;
                        ENUM_OBJECT type_object=OBJ_HLINE;
                        CChartObjectsControl *ctrl=this.CreateNewStdGraphObjectAndGetCtrlObj(chart_id,nm,subwindow,type_object,0,price);
                        if(ctrl==NULL)
                           return false;
                        CGStdHLineObj *obj=ctrl.CreateNewGraphObj(type_object,nm,extended);

                        if(obj==NULL)
                          {
                           ::Print(DFUN,CMessage::Text(MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_CLASS_OBJ),StdGraphObjectTypeDescription(type_object));
                           return false;
                          }
                        //--- Set the necessary minimal parameters for an object
                        obj.SetBelong(GRAPH_OBJ_BELONG_PROGRAM);
                        obj.SetFlagSelectable(true,false);
                        obj.SetFlagSelected(true,false);
                        obj.SetObjectID(this.GetFreeGraphObjID(true));
                        obj.PropertiesCopyToPrevData();
                        //--- Return the result of adding the object to the list
                        return this.AddCreatedObjToList(DFUN,chart_id,nm,obj);
                       }
 
//--- Create the "Trend line" graphical object

ここに、同様の変更を加えた2つのメソッドの例を示します。残りのメソッドも同じように変更されます。以下の添付ファイルでご覧ください。

新しい標準グラフィカルオブジェクトを作成するメソッドを実装するリストを、クラスから \MQL5\Include\DoEasy\Services\DELib.mqhライブラリサービス関数ファイルの最後に移動します。

//+------------------------------------------------------------------+
//| Create a new standard graphical object                           |
//+------------------------------------------------------------------+
bool CreateNewStdGraphObject(const long chart_id,
                             const string name,
                             const ENUM_OBJECT type,
                             const int subwindow,
                             const datetime time1,
                             const double price1,
                             const datetime time2=0,
                             const double price2=0,
                             const datetime time3=0,
                             const double price3=0,
                             const datetime time4=0,
                             const double price4=0,
                             const datetime time5=0,
                             const double price5=0)
  {
   ::ResetLastError();
   switch(type)
     {
      //--- Lines
      case OBJ_VLINE             : return ::ObjectCreate(chart_id,name,OBJ_VLINE,subwindow,time1,0);
      case OBJ_HLINE             : return ::ObjectCreate(chart_id,name,OBJ_HLINE,subwindow,0,price1);
      case OBJ_TREND             : return ::ObjectCreate(chart_id,name,OBJ_TREND,subwindow,time1,price1,time2,price2);
      case OBJ_TRENDBYANGLE      : return ::ObjectCreate(chart_id,name,OBJ_TRENDBYANGLE,subwindow,time1,price1,time2,price2);
      case OBJ_CYCLES            : return ::ObjectCreate(chart_id,name,OBJ_CYCLES,subwindow,time1,price1,time2,price2);
      case OBJ_ARROWED_LINE      : return ::ObjectCreate(chart_id,name,OBJ_ARROWED_LINE,subwindow,time1,price1,time2,price2);
      //--- Channels
      case OBJ_CHANNEL           : return ::ObjectCreate(chart_id,name,OBJ_CHANNEL,subwindow,time1,price1,time2,price2,time3,price3);
      case OBJ_STDDEVCHANNEL     : return ::ObjectCreate(chart_id,name,OBJ_STDDEVCHANNEL,subwindow,time1,price1,time2,price2);
      case OBJ_REGRESSION        : return ::ObjectCreate(chart_id,name,OBJ_REGRESSION,subwindow,time1,price1,time2,price2);
      case OBJ_PITCHFORK         : return ::ObjectCreate(chart_id,name,OBJ_PITCHFORK,subwindow,time1,price1,time2,price2,time3,price3);
      //--- Gann
      case OBJ_GANNLINE          : return ::ObjectCreate(chart_id,name,OBJ_GANNLINE,subwindow,time1,price1,time2,price2);
      case OBJ_GANNFAN           : return ::ObjectCreate(chart_id,name,OBJ_GANNFAN,subwindow,time1,price1,time2,price2);
      case OBJ_GANNGRID          : return ::ObjectCreate(chart_id,name,OBJ_GANNGRID,subwindow,time1,price1,time2,price2);
      //--- Fibo
      case OBJ_FIBO              : return ::ObjectCreate(chart_id,name,OBJ_FIBO,subwindow,time1,price1,time2,price2);
      case OBJ_FIBOTIMES         : return ::ObjectCreate(chart_id,name,OBJ_FIBOTIMES,subwindow,time1,price1,time2,price2);
      case OBJ_FIBOFAN           : return ::ObjectCreate(chart_id,name,OBJ_FIBOFAN,subwindow,time1,price1,time2,price2);
      case OBJ_FIBOARC           : return ::ObjectCreate(chart_id,name,OBJ_FIBOARC,subwindow,time1,price1,time2,price2);
      case OBJ_FIBOCHANNEL       : return ::ObjectCreate(chart_id,name,OBJ_FIBOCHANNEL,subwindow,time1,price1,time2,price2,time3,price3);
      case OBJ_EXPANSION         : return ::ObjectCreate(chart_id,name,OBJ_EXPANSION,subwindow,time1,price1,time2,price2,time3,price3);
      //--- Elliott
      case OBJ_ELLIOTWAVE5       : return ::ObjectCreate(chart_id,name,OBJ_ELLIOTWAVE5,subwindow,time1,price1,time2,price2,time3,price3,time4,price4,time5,price5);
      case OBJ_ELLIOTWAVE3       : return ::ObjectCreate(chart_id,name,OBJ_ELLIOTWAVE3,subwindow,time1,price1,time2,price2,time3,price3);
      //--- Shapes
      case OBJ_RECTANGLE         : return ::ObjectCreate(chart_id,name,OBJ_RECTANGLE,subwindow,time1,price1,time2,price2);
      case OBJ_TRIANGLE          : return ::ObjectCreate(chart_id,name,OBJ_TRIANGLE,subwindow,time1,price1,time2,price2,time3,price3);
      case OBJ_ELLIPSE           : return ::ObjectCreate(chart_id,name,OBJ_ELLIPSE,subwindow,time1,price1,time2,price2,time3,price3);
      //--- Arrows
      case OBJ_ARROW_THUMB_UP    : return ::ObjectCreate(chart_id,name,OBJ_ARROW_THUMB_UP,subwindow,time1,price1);
      case OBJ_ARROW_THUMB_DOWN  : return ::ObjectCreate(chart_id,name,OBJ_ARROW_THUMB_DOWN,subwindow,time1,price1);
      case OBJ_ARROW_UP          : return ::ObjectCreate(chart_id,name,OBJ_ARROW_UP,subwindow,time1,price1);
      case OBJ_ARROW_DOWN        : return ::ObjectCreate(chart_id,name,OBJ_ARROW_DOWN,subwindow,time1,price1);
      case OBJ_ARROW_STOP        : return ::ObjectCreate(chart_id,name,OBJ_ARROW_STOP,subwindow,time1,price1);
      case OBJ_ARROW_CHECK       : return ::ObjectCreate(chart_id,name,OBJ_ARROW_CHECK,subwindow,time1,price1);
      case OBJ_ARROW_LEFT_PRICE  : return ::ObjectCreate(chart_id,name,OBJ_ARROW_LEFT_PRICE,subwindow,time1,price1);
      case OBJ_ARROW_RIGHT_PRICE : return ::ObjectCreate(chart_id,name,OBJ_ARROW_RIGHT_PRICE,subwindow,time1,price1);
      case OBJ_ARROW_BUY         : return ::ObjectCreate(chart_id,name,OBJ_ARROW_BUY,subwindow,time1,price1);
      case OBJ_ARROW_SELL        : return ::ObjectCreate(chart_id,name,OBJ_ARROW_SELL,subwindow,time1,price1);
      case OBJ_ARROW             : return ::ObjectCreate(chart_id,name,OBJ_ARROW,subwindow,time1,price1);
      //--- Graphical objects
      case OBJ_TEXT              : return ::ObjectCreate(chart_id,name,OBJ_TEXT,subwindow,time1,price1);
      case OBJ_LABEL             : return ::ObjectCreate(chart_id,name,OBJ_LABEL,subwindow,0,0);
      case OBJ_BUTTON            : return ::ObjectCreate(chart_id,name,OBJ_BUTTON,subwindow,0,0);
      case OBJ_CHART             : return ::ObjectCreate(chart_id,name,OBJ_CHART,subwindow,0,0);
      case OBJ_BITMAP            : return ::ObjectCreate(chart_id,name,OBJ_BITMAP,subwindow,time1,price1);
      case OBJ_BITMAP_LABEL      : return ::ObjectCreate(chart_id,name,OBJ_BITMAP_LABEL,subwindow,0,0);
      case OBJ_EDIT              : return ::ObjectCreate(chart_id,name,OBJ_EDIT,subwindow,0,0);
      case OBJ_EVENT             : return ::ObjectCreate(chart_id,name,OBJ_EVENT,subwindow,time1,0);
      case OBJ_RECTANGLE_LABEL   : return ::ObjectCreate(chart_id,name,OBJ_RECTANGLE_LABEL,subwindow,0,0);
      //---
      default: return false;
     }
  }
//+------------------------------------------------------------------+


それでは、\MQL5\Include\DoEasy\Engine.mqhのCEngineライブラリのメインクラスを改善しましょう。

プログラム名を返すメソッドは、かなり機能のないName()からより正確なProgramName()に名前が変更されています。

//--- Return event (1) milliseconds, (2) reason and (3) source from its 'long' value
   ushort               EventMSC(const long lparam)               const { return this.LongToUshortFromByte(lparam,0);         }
   ushort               EventReason(const long lparam)            const { return this.LongToUshortFromByte(lparam,1);         }
   ushort               EventSource(const long lparam)            const { return this.LongToUshortFromByte(lparam,2);         }

//--- Return the program name
   string               ProgramName(void)                         const { return this.m_name;                                 }

//--- Set the new (1) pause countdown start time and (2) pause in milliseconds

オブジェクト名は、グラフィカルオブジェクトの作成方法(手動またはプログラム)によって異なるため、標準グラフィカルオブジェクトのオブジェクトクラスをチャート名とIDで返すメソッドを変更して、オブジェクトをプログラム名で検索および選択できるようにします。

//--- Return the class of the object of the standard graphical object by chart name and ID
   CGStdGraphObj       *GraphGetStdGraphObject(const string name,const long chart_id)
                          {
                           CGStdGraphObj *obj=this.m_graph_objects.GetStdGraphObject(name,chart_id);
                           if(obj==NULL)
                              obj=this.m_graph_objects.GetStdGraphObject(this.ProgramName()+"_"+name,chart_id);
                           return obj;
                          }

オブジェクトが手動で作成された場合、その名前はライブラリによって変更されません。グラフィカルオブジェクトをプログラムで作成する場合、その作成メソッドは、プログラム名のプレフィックスをオブジェクト名に追加します。たとえば、カスタムプログラムから「object_name」という名前のオブジェクトを作成し、後でそれを見つけようとすると、名前にプログラム名のプレフィックスが付いているため、オブジェクト名は 「program_name_object_name」のようになります。これを考慮して、最初にメソッドに渡された名前の検索を実行します。次に、そのような名前のオブジェクトが見つからない場合プログラム名のプレフィックスが名前に追加されたオブジェクトを検索しようとします。

また、拡張された標準グラフィックオブジェクトのオブジェクトのクラスをチャート名とIDで返すメソッドを追加します。

//--- Return the class of the object of the extended standard graphical object by chart name and ID
   CGStdGraphObj       *GraphGetStdGraphObjectExt(const string name,const long chart_id)
                          {
                           CArrayObj *list=this.m_graph_objects.GetListStdGraphObjectExt();
                           string nm=(::StringFind(name,this.ProgramName()+"_")==WRONG_VALUE ? this.ProgramName()+"_"+name : name);
                           list=CSelect::ByGraphicStdObjectProperty(list,GRAPH_OBJ_PROP_NAME,0,nm,EQUAL);
                           return(list!=NULL ? list.At(0) : NULL);
                          }

ここでは、最初にすべての拡張グラフィカルオブジェクトのリストを受け取ります。次に、メソッドに渡された名前にプログラム名が含まれる文字列の存在を確認します文字列が見つからない場合は、プログラム名をオブジェクト名に追加しますオブジェクト名にすでにプログラム名が含まれている場合は、メソッドに渡された名前が「そのまま」使用されます。次に、以前に取得した拡張グラフィカルオブジェクトのリストから、必要な名前のオブジェクトを受け取りリストから唯一のオブジェクトが見つかった場合はそれを返し または検索が失敗した場合NULLを返します。

拡張オブジェクトフラグが、グラフィカルオブジェクトを作成するためのすべてのメソッドに渡されるようになりました。フラグは、グラフィカル要素のコレクションクラスの適切な呼び出されたメソッドにも渡されます

//--- Create the "Vertical line" graphical object
   bool              CreateLineVertical(const long chart_id,const string name,const int subwindow,const bool extended,const datetime time)
                       { return this.m_graph_objects.CreateLineVertical(chart_id,name,subwindow,extended,time); }
   bool              CreateLineVertical(const string name,const int subwindow,const bool extended,const datetime time)
                       { return this.m_graph_objects.CreateLineVertical(::ChartID(),name,subwindow,extended,time); }

//--- Create the "Horizontal line" graphical object
   bool              CreateLineHorizontal(const long chart_id,const string name,const int subwindow,const bool extended,const double price)
                       { return this.m_graph_objects.CreateLineHorizontal(chart_id,name,subwindow,extended,price); }
   bool              CreateLineHorizontal(const string name,const int subwindow,const bool extended,const double price)
                       { return this.m_graph_objects.CreateLineHorizontal(::ChartID(),name,subwindow,extended,price); }

これらの改善は、すべてのグラフィカルオブジェクト作成メソッドについて上記で説明した4つの改善と同じです。したがって、他のメソッドを考慮する必要はありません。以下の添付ファイルでご覧ください。

これでライブラリの改善は終わりです。ほとんどすべてが、拡張された標準グラフィカルオブジェクトを作成する準備ができています。


テスト

テストを実行するには、前の記事のEAを\MQL5\Experts\TestDoEasy\Part93\TestDoEasyPart93.mq5として保存します。

「トレンドライン」標準グラフィカルオブジェクトを作成し、「左価格ラベル」と「右価格ラベル」をそのエッジに沿って(2つのピボットポイントで)、それぞれポイント0とポイント1に配置します。Ctrlキーを押しながらチャートをクリックすると、トレンドラインが作成されます。線の左側のアンカーポイントはチャートをクリックしたときに配置され、右側のアンカーポイントは最初のチャートバーの始値に配置されます。
トレンドラインのプロパティの完全な説明と、操作ログの価格ラベルオブジェクト(つまり、接続されたピボットポイントクラスのオブジェクト)に設定された値を表示します。拡張された標準グラフィカルオブジェクトを本格的に作成するには、オブジェクトのプロパティと機能をいくつか改善する必要があるため、残りの部分をテストしても意味がありません。これは、今後の記事で行われます。

OnChartEvent()EAハンドラーのグラフのクリックを処理するために、次のコードをブロックに追加します。

   if(id==CHARTEVENT_CLICK)
     {
      if(!IsCtrlKeyPressed())
         return;
      //--- Get the chart click coordinates
      datetime time=0;
      double price=0;
      int sw=0;
      if(ChartXYToTimePrice(ChartID(),(int)lparam,(int)dparam,sw,time,price))
        {
         //--- Get the right point coordinates for a trend line
         datetime time2=iTime(Symbol(),PERIOD_CURRENT,1);
         double price2=iOpen(Symbol(),PERIOD_CURRENT,1);
         
         //--- Create the "Trend line" object
         string name_base="TrendLineExt";
         engine.CreateLineTrend(name_base,0,true,time,price,time2,price2);
         //--- Get the object from the list of graphical objects by chart name and ID and pass its properties to the journal
         CGStdGraphObj *obj=engine.GraphGetStdGraphObjectExt(name_base,ChartID());
         obj.Print();
         
         //--- Create the "Left price label" object
         string name_dep="PriceLeft";
         engine.CreatePriceLabelLeft(name_dep,0,false,time,price);
         //--- Get the object from the list of graphical objects by chart name and ID and
         CGStdGraphObj *dep=engine.GraphGetStdGraphObject(name_dep,ChartID());
         //--- add it to the list of graphical objects bound to the "Trend line" object
         obj.AddDependentObj(dep);
         //--- Set its pivot point by X and Y axis to the trend line left point
         obj.AddNewLinkedPivotPointXY(dep,GRAPH_OBJ_PROP_TIME,0,GRAPH_OBJ_PROP_PRICE,0);
         //--- Send the number of pivot anchor points by both axes (one point per axis) to the journal
         Print(DFUN,"PriceLeft: Num linked coord X: ",dep.GetBasePivotsNumX(0),", Num linked coord Y: ",dep.GetBasePivotsNumY(0));
         
         //--- Create the "Right price label" object
         name_dep="PriceRight";
         engine.CreatePriceLabelRight(name_dep,0,false,time2,price2);
         //--- Get the object from the list of graphical objects by chart name and ID and
         dep=engine.GraphGetStdGraphObject(name_dep,ChartID());
         //--- add it to the list of graphical objects bound to the "Trend line" object
         obj.AddDependentObj(dep);
         //--- Set its pivot point by X and Y axis to the trend line right point
         obj.AddNewLinkedPivotPointXY(dep,GRAPH_OBJ_PROP_TIME,1,GRAPH_OBJ_PROP_PRICE,1);
         //--- Send the number of pivot anchor points by both axes (one point per axis) to the journal
         Print(DFUN,"PriceRight: Num linked coord X: ",dep.GetBasePivotsNumX(0),", Num linked coord Y: ",dep.GetBasePivotsNumY(0));
        }
     }

ここでのロジック全体がリストにコメントされています。すべてが明確なはずです。

EAをコンパイルし、チャート上で起動して、チャートの右端から離れた場所をクリックします。

結果は、そのエッジに沿って価格ラベルオブジェクトを伴うトレンドラインです。


操作ログには、トレンドラインのプロパティと、両方の価格ラベルのX座標とY座標を計算するためのトレンドラインピボットポイントの数が表示されます。ラベルごとに1つのピボットポイントが指定されているため、これは操作ログに表示されます。

2022.01.20 16:37:29.340 ============= The beginning of the parameter list (Trend Line) =============
2022.01.20 16:37:29.340 Object ID: 1
2022.01.20 16:37:29.340 Base object ID: 0
2022.01.20 16:37:29.340 Object type: Trend Line
2022.01.20 16:37:29.340 Graphic element type: Extended standard graphic object
2022.01.20 16:37:29.340 Object belongs to: The graphic object belongs to the program
2022.01.20 16:37:29.340 Object chart ID: 131733844391938630
2022.01.20 16:37:29.340 Chart subwindow number: 0
2022.01.20 16:37:29.340 Object number in the list: The base object of the extended graphical object
2022.01.20 16:37:29.340 Change history: No
2022.01.20 16:37:29.340 Object group: Not set
2022.01.20 16:37:29.340 Time of creation: 2022.01.20 16:37:29
2022.01.20 16:37:29.340 Visibility of an object at timeframes: Drawn on all timeframes
2022.01.20 16:37:29.340 Object in the background: No
2022.01.20 16:37:29.340 Priority of a graphical object for receiving events of clicking on a chart: 0
2022.01.20 16:37:29.340 Prohibit showing of the name of a graphical object in the terminal objects list: Yes
2022.01.20 16:37:29.340 Object is selected: Yes
2022.01.20 16:37:29.340 Object availability: Yes
2022.01.20 16:37:29.340 Time coordinate: 
2022.01.20 16:37:29.340  - Pivot point 0: 2022.01.13 09:00
2022.01.20 16:37:29.340  - Pivot point 1: 2022.01.20 10:00
2022.01.20 16:37:29.340 Color: clrRed
2022.01.20 16:37:29.340 Style: Solid line
2022.01.20 16:37:29.340 Line thickness: 1
2022.01.20 16:37:29.340 Ray goes to the left: No
2022.01.20 16:37:29.340 Ray goes to the right: No
2022.01.20 16:37:29.340 ------
2022.01.20 16:37:29.340 Price coordinate: 
2022.01.20 16:37:29.340  - Pivot point 0: 1.14728
2022.01.20 16:37:29.340  - Pivot point 1: 1.13598
2022.01.20 16:37:29.340 ------
2022.01.20 16:37:29.340 Name: "TestDoEasyPart93_TrendLineExt"
2022.01.20 16:37:29.340 Base object name: "TestDoEasyPart93_TrendLineExt"
2022.01.20 16:37:29.340 Description: Not set
2022.01.20 16:37:29.340 The text of a tooltip: Formed by the terminal
2022.01.20 16:37:29.340 ============= End of the parameter list (Trend Line) =============
2022.01.20 16:37:29.340 
2022.01.20 16:37:29.352 OnChartEvent: PriceLeft: Num linked coord X: 1, Num linked coord Y: 1
2022.01.20 16:37:29.364 OnChartEvent: PriceRight: Num linked coord X: 1, Num linked coord Y: 1

現在、個別のグラフィカルオブジェクトを作成し、オブジェクトが同じ拡張された標準グラフィカルオブジェクトに属していることを示すプロパティを設定するだけです。 トレンドラインを移動すると、価格ラベルはそれに従わなくなります。ただし、何にしても現在の目的ではありませんでした。目的は、本格的な拡張グラフィカルオブジェクトを作成するために必要な機能を準備することでした。

次の段階

次の記事では、拡張された標準グラフィカルオブジェクトの作業を続け、それらの「アニメーション化」を開始します。

現在のライブラリバージョン、テストEA、およびMQL5のチャートイベントコントロール指標のすべてのファイルが、テストおよびダウンロードできるように以下に添付されています。質問、コメント、提案はコメント欄にお願いします。

目次に戻る

*連載のこれまでの記事:

DoEasyライブラリのグラフィックス(第89部): 抽象標準グラフィカルオブジェクトのプログラミング基本機能
DoEasyライブラリのグラフィックス(第90部): 標準グラフィカルオブジェクトのイベント基本機能
DoEasyライブラリのグラフィックス(第91部): 標準グラフィカルオブジェクトのイベントオブジェクト名変更履歴
DoEasyライブラリのグラフィックス(第92部): 標準グラフィカルオブジェクトのメモリクラス。オブジェクトプロパティの変更履歴