
DoEasyライブラリのグラフィックス(第92部): 標準グラフィカルオブジェクトのメモリクラスオブジェクトプロパティの変更履歴
目次
概念
グラフィカルオブジェクトの名前変更履歴のプロパティへの実装はすでにテストしました。実際、前の記事で作成した機能を使用すると、グラフィカルオブジェクトの名前変更のシーケンス全体を定義できますが、それがどれほど有用であるかを予測するのは難しいです。ただし、名前変更中に前のオブジェクトが削除され、別の名前の新しいオブジェクトが作成されることを考慮すると、過去にチャートに存在していたオブジェクトについて知ることが役立つ場合があります。オブジェクトの変更履歴全体を保存する可能性を考慮に入れた場合、あらゆるグラフィカルオブジェクトで以前の名前を含むすべての状態を取得できるようになるので、オブジェクトの以前の名前を知ることができます。必要な名前とメモリに保存されているそのプロパティを照合することで、チャート上のオブジェクトを簡単に復元できます。
どこでどのように役立つかについては触れませんが、これがテクニカル分析を行うための追加のツールであることは確かです。たとえば、オブジェクト名を使用して、グラフィカルオブジェクトが構築されている日、週、月、またはその他の期間を指定することができます。新しい時間間隔が到達すると、古いオブジェクトの名前が新しい時間間隔と一致するように変更され、オブジェクトがチャート上に再構築されます。したがって、名前変更の履歴を含め、すべてのプロパティがメモリに保存されます(本稿ではこのような機能を実装します)。グラフィカルオブジェクトを使用してチャート上に何かをマークし、そのオブジェクトを毎日再構築する場合、名前は新しい日付に一致するように変更できます。チャートを手動でスクロールすると、表示されているバーの時刻を確認してそのメモリからグラフィックオブジェクトのステータスを「取得」できます。ステータスは、スクロールされたチャートのバーの時間に対応し、そのプロパティが現在のオブジェクトに適用されます。したがって、チャートに表示されているバーの時間に応じて、ステータスを自動的に変更するスマートなオブジェクトを作成できます。
上記の例では、取引週内で毎日、グラフィカルオブジェクトのプロパティを現在の市場の状態に調整することができます。週の終わりには、チャートをスクロールして戻すだけで、グラフィカルオブジェクトはチャートの表示部分に過去の各取引日を表示します。オブジェクトには独自のメモリがあるため、オブジェクトのプロパティが変更されるたびにすべての変更が保存されます。特定のグラフィックオブジェクトがチャートに表示されている日に対応するステータスの「スナップショット」を取得してこれらのパラメータをそれ自体に適用することを必要にするようなライブラリ制御のEAがチャートにある場合、チャートのスクロールは、グラフィックオブジェクトのプロパティを変更する条件として使用され、取引週の間に行われたすべての変更が表示されます。
これは何故必要なのでしょうか。この機能は、取引週の分析に便利だと思います。それにこれは一例にすぎません。すぐに頭に浮かび、役に立つように思われたのです。
ライブラリクラスの改善
標準のグラフィカルオブジェクトプロパティの列挙にはGroupプロパティがあって、現在、グラフィカルオブジェクトが属するグループを指定するために使用されています。
ただし、他のライブラリオブジェクトにもグループがあり、特定のプロパティに従ってオブジェクトを並べ替えるために使用されることを考えると、グラフィカルオブジェクトにも同じものを設定するのが妥当です。現在のGroupプロパティの名前はSpeciesに変更され、新しいGroupプロパティは、一部のプロパティでオブジェクトを並べ替えるために使用されます。ここで作成している機能をテストするために、チャート上に作成されたグラフィカルオブジェクトにグループ#1を割り当てます。グループのすべてのオブジェクトで、変更されたときにステータスを保存します。
\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_ELEMENT, // Element GRAPH_ELEMENT_TYPE_SHADOW_OBJ, // Shadow object GRAPH_ELEMENT_TYPE_FORM, // Form GRAPH_ELEMENT_TYPE_WINDOW, // Window }; //+------------------------------------------------------------------+ //| Graphical object group | //+------------------------------------------------------------------+ enum ENUM_GRAPH_OBJ_GROUP { GRAPH_OBJ_GROUP_LINES, // Lines GRAPH_OBJ_GROUP_CHANNELS, // Channels GRAPH_OBJ_GROUP_GANN, // Gann GRAPH_OBJ_GROUP_FIBO, // Fibo GRAPH_OBJ_GROUP_ELLIOTT, // Elliott GRAPH_OBJ_GROUP_SHAPES, // Shapes GRAPH_OBJ_GROUP_ARROWS, // Arrows GRAPH_OBJ_GROUP_GRAPHICAL, // Graphical objects }; //+------------------------------------------------------------------+ //| Integer properties of a standard graphical object | //+------------------------------------------------------------------+
をグラフィックオブジェクトのspeciesの列挙で置き換えます。
//+------------------------------------------------------------------+
//| Graphical object species |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_OBJ_SPECIES
{
GRAPH_OBJ_SPECIES_LINES, // Lines
GRAPH_OBJ_SPECIES_CHANNELS, // Channels
GRAPH_OBJ_SPECIES_GANN, // Gann
GRAPH_OBJ_SPECIES_FIBO, // Fibo
GRAPH_OBJ_SPECIES_ELLIOTT, // Elliott
GRAPH_OBJ_SPECIES_SHAPES, // Shapes
GRAPH_OBJ_SPECIES_ARROWS, // Arrows
GRAPH_OBJ_SPECIES_GRAPHICAL, // Graphical objects
};
//+------------------------------------------------------------------+
標準のグラフィカルオブジェクトの整数プロパティの列挙で、Groupプロパティ
//--- Additional properties GRAPH_OBJ_PROP_ID = 0, // Object ID GRAPH_OBJ_PROP_TYPE, // Graphical object type (ENUM_OBJECT) GRAPH_OBJ_PROP_ELEMENT_TYPE, // Graphical element type (ENUM_GRAPH_ELEMENT_TYPE) GRAPH_OBJ_PROP_GROUP, // Graphical object group (ENUM_GRAPH_OBJ_GROUP) 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
をSpeciesプロパティで置き換え、変更履歴保存フラグとオブジェクトグループの2つの新しいパラメータを追加します。
//+------------------------------------------------------------------+ //| Integer properties of a standard graphical object | //+------------------------------------------------------------------+ enum ENUM_GRAPH_OBJ_PROP_INTEGER { //--- Additional properties GRAPH_OBJ_PROP_ID = 0, // Object ID GRAPH_OBJ_PROP_TYPE, // Graphical object type (ENUM_OBJECT) GRAPH_OBJ_PROP_ELEMENT_TYPE, // Graphical element type (ENUM_GRAPH_ELEMENT_TYPE) GRAPH_OBJ_PROP_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
デフォルトでは、プロパティの変更履歴はどのグラフィカルオブジェクトにも保存されません。そのため、グラフィカルオブジェクトが変更履歴を記録するかどうかを示すフラグを格納するプロパティを実装しました。上記のように、Groupプロパティの名前をSpeciesに変更し、特定のプロパティで並べ替えられたオブジェクトのグループのインデックスを格納するための新しいGroupプロパティを作成しました。
整数のグラフィカルオブジェクトプロパティの列挙に2つの新しいプロパティを追加したので、それらの新しい数を指定します(52ではなく54)。
#define GRAPH_OBJ_PROP_INTEGER_TOTAL (54) // Total number of integer properties #define GRAPH_OBJ_PROP_INTEGER_SKIP (0) // Number of integer properties not used in sorting //+------------------------------------------------------------------+ //| Real properties of a standard graphical object | //+------------------------------------------------------------------+
並べ替えを可能なグラフィカルオブジェクトの並べ替え基準のリストに新しいプロパティを追加します。
//+------------------------------------------------------------------+ //| Possible sorting criteria of graphical objects | //+------------------------------------------------------------------+ #define FIRST_GRAPH_OBJ_DBL_PROP (GRAPH_OBJ_PROP_INTEGER_TOTAL-GRAPH_OBJ_PROP_INTEGER_SKIP) #define FIRST_GRAPH_OBJ_STR_PROP (GRAPH_OBJ_PROP_INTEGER_TOTAL-GRAPH_OBJ_PROP_INTEGER_SKIP+GRAPH_OBJ_PROP_DOUBLE_TOTAL-GRAPH_OBJ_PROP_DOUBLE_SKIP) enum ENUM_SORT_GRAPH_OBJ_MODE { //--- Sort by integer properties SORT_BY_GRAPH_OBJ_ID = 0, // Sort by object ID SORT_BY_GRAPH_OBJ_TYPE, // Sort by object type SORT_BY_GRAPH_OBJ_ELEMENT_TYPE, // Sort by graphical element type SORT_BY_GRAPH_OBJ_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_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で、新しいメッセージインデックスを追加し、列挙定数の名前を修正します。
//--- GStdGraphObj MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_CLASS_OBJ, // Failed to create the class object for a graphical object MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_STD_GRAPH_OBJ, // Failed to create a graphical object MSG_GRAPH_STD_OBJ_ERR_NOT_FIND_SUBWINDOW, // Failed to find the chart subwindow MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_SNAPSHOT, // Failed to create a snapshot of the graphical object change history MSG_GRAPH_STD_OBJ_SUCCESS_CREATE_SNAPSHOT, // Created a snapshot of the graphical object change history
...
MSG_GRAPH_OBJ_PROP_ID, // Object ID MSG_GRAPH_OBJ_PROP_TYPE, // Graphical object type (ENUM_OBJECT) MSG_GRAPH_OBJ_PROP_ELEMENT_TYPE, // Graphical element type (ENUM_GRAPH_ELEMENT_TYPE) MSG_GRAPH_OBJ_PROP_BELONG, // Graphical object affiliation MSG_GRAPH_OBJ_PROP_CHART_ID, // Chart ID MSG_GRAPH_OBJ_PROP_WND_NUM, // Chart subwindow index MSG_GRAPH_OBJ_PROP_CHANGE_MEMORY, // Change history MSG_GRAPH_OBJ_PROP_CREATETIME, // Creation time MSG_GRAPH_OBJ_PROP_TIMEFRAMES, // Object visibility on timeframes
...
MSG_GRAPH_OBJ_PROP_SPECIES, // Graphical object species MSG_GRAPH_OBJ_PROP_SPECIES_LINES, // Lines MSG_GRAPH_OBJ_PROP_SPECIES_CHANNELS, // Channels MSG_GRAPH_OBJ_PROP_SPECIES_GANN, // Gann MSG_GRAPH_OBJ_PROP_SPECIES_FIBO, // Fibo MSG_GRAPH_OBJ_PROP_SPECIES_ELLIOTT, // Elliott MSG_GRAPH_OBJ_PROP_SPECIES_SHAPES, // Shapes MSG_GRAPH_OBJ_PROP_SPECIES_ARROWS, // Arrows MSG_GRAPH_OBJ_PROP_SPECIES_GRAPHICAL, // Graphical objects MSG_GRAPH_OBJ_PROP_GROUP, // Group of objects MSG_GRAPH_OBJ_TEXT_CLICK_COORD, // (Chart click coordinate) MSG_GRAPH_OBJ_TEXT_ANCHOR_TOP, // Arrow anchor point is located at the top MSG_GRAPH_OBJ_TEXT_ANCHOR_BOTTOM, // Arrow anchor point is located at the bottom
...
//--- CDataPropObj MSG_DATA_PROP_OBJ_OUT_OF_PROP_RANGE, // Passed property is out of object property range MSG_GRAPH_OBJ_FAILED_CREATE_NEW_HIST_OBJ, // Failed to create an object of the graphical object change history MSG_GRAPH_OBJ_FAILED_ADD_OBJ_TO_HIST_LIST, // Failed to add the change history object to the list MSG_GRAPH_OBJ_FAILED_GET_HIST_OBJ, // Failed to receive the change history object MSG_GRAPH_OBJ_FAILED_INC_ARRAY_SIZE, // Failed to increase the array size
また、新しく追加されたインデックスに対応するテキストメッセージも追加します。
//--- GStdGraphObj {"Не удалось создать объект класса для графического объекта ","Failed to create class object for graphic object"}, {"Не удалось создать графический объект ","Failed to create graphic object "}, {"Не удалось найти подокно графика","Could not find chart subwindow"}, {"Не удалось создать снимок истории изменений графического объекта","Failed to create a snapshot of the change history of a graphic object"}, {"Создан снимок истории изменений графического объекта","A snapshot of the history of changes to a graphical object has been created"},
...
{"Идентификатор объекта","Object ID"}, {"Тип объекта","Object type"}, {"Тип графического элемента","Graphic element type"}, {"Принадлежность объекта","Object belongs to"}, {"Идентификатор графика объекта","Object chart ID"}, {"Номер подокна графика","Chart subwindow number"}, {"История изменений","Change history"}, {"Время создания","Time of creation"}, {"Видимость объекта на таймфреймах","Visibility of an object at timeframes"},
...
{"Вид графического объекта","Graphic object species"}, {"Линии","Lines"}, {"Каналы","Channels"}, {"Ганн","Gann"}, {"Фибоначчи","Fibonacci"}, {"Эллиотт","Elliott"}, {"Фигуры","Shapes"}, {"Стрелки","Arrows"}, {"Графические объекты","Graphical"}, {"Группа объектов","Object group"},
...
//--- CDataPropObj {"Переданное свойство находится за пределами диапазона свойств объекта","The passed property is outside the range of the object's properties"}, {"Не удалось создать объект истории изменений графического объекта","Failed to create a graphical object change history object"}, {"Не удалось добавить объект истории изменений в список","Failed to add change history object to the list"}, {"Не удалось получить объект истории изменений","Failed to get change history object"}, {"Не удалось увеличить размер массива","Failed to increase array size"},
\MQL5\Include\DoEasy\Objects\Graph\Standard\の抽象標準グラフィカルオブジェクトから派生したすべてのオブジェクトに変更を実装する必要があります(例としてGStdArrowBuyObj.mqhが使用されています)。
クラスコンストラクタの初期化リストで、列挙定数の名前を修正して、グラフィカルオブジェクトのspeciesを示します。
//--- Constructor CGStdArrowBuyObj(const long chart_id,const string name) : CGStdGraphObj(OBJECT_DE_TYPE_GSTD_ARROW_BUY,GRAPH_OBJ_BELONG_NO_PROGRAM,GRAPH_OBJ_SPECIES_ARROWS,chart_id,1,name) { //--- Specify the object property CGStdGraphObj::SetProperty(GRAPH_OBJ_PROP_ANCHOR,0,ANCHOR_TOP); }
他のファイルには、他の種類のグラフィックオブジェクトがありますが、_GROUP_を_SPECIES_にすべて置き換える必要があります。
オブジェクトによって整数プロパティをサポートするフラグを返すメソッドで、「オブジェクト変更履歴の保存のフラグ」プロパティを追加します。
//+------------------------------------------------------------------+ //| 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_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; } //+------------------------------------------------------------------+
指定されたフォルダですべての変更がすでに行われています。それらは考慮されたものと同一であるため、それらについては説明しません。以下の添付ファイルでご覧ください。
すべてのライブラリグラフィカルオブジェクトの基本グラフィカルオブジェクトファイル(\MQL5\Include\DoEasy\Objects\Graph\GBaseObj.mqh)に、グラフィカルオブジェクトのspeciesとグループを格納するための変数を追加します。
//+------------------------------------------------------------------+ //| Class of the base object of the library graphical objects | //+------------------------------------------------------------------+ class CGBaseObj : public CObject { protected: CArrayObj m_list_events; // Object event list ENUM_OBJECT m_type_graph_obj; // Graphical object type ENUM_GRAPH_ELEMENT_TYPE m_type_element; // Graphical element type ENUM_GRAPH_OBJ_BELONG m_belong; // Program affiliation ENUM_GRAPH_OBJ_SPECIES m_species; // Graphical object species string m_name_prefix; // Object name prefix string m_name; // Object name long m_chart_id; // Object chart ID long m_object_id; // Object ID long m_zorder; // Priority of a graphical object for receiving the mouse click event int m_subwindow; // Subwindow index int m_shift_y; // Subwindow Y coordinate shift int m_type; // Object type int m_timeframes_visible; // Visibility of an object on timeframes (a set of flags) int m_digits; // Number of decimal places in a quote int m_group; // Graphical object group bool m_visible; // Object visibility bool m_back; // "Background object" flag bool m_selected; // "Object selection" flag bool m_selectable; // "Object availability" flag bool m_hidden; // "Disable displaying the name of a graphical object in the terminal object list" flag datetime m_create_time; // Object creation time
これらの変数を設定するメソッドと値を返すメソッドも追加します。
public: //--- Set the values of the class variables void SetObjectID(const long value) { this.m_object_id=value; } void SetBelong(const ENUM_GRAPH_OBJ_BELONG belong){ this.m_belong=belong; } void SetTypeGraphObject(const ENUM_OBJECT obj) { this.m_type_graph_obj=obj; } void SetTypeElement(const ENUM_GRAPH_ELEMENT_TYPE type) { this.m_type_element=type; } void SetSpecies(const ENUM_GRAPH_OBJ_SPECIES species){ this.m_species=species; } void SetGroup(const int group) { this.m_group=group; } void SetName(const string name) { this.m_name=name; } void SetChartID(const long chart_id) { this.m_chart_id=chart_id; } void SetDigits(const int value) { this.m_digits=value; }
...
//--- Return the values of class variables ENUM_GRAPH_ELEMENT_TYPE TypeGraphElement(void) const { return this.m_type_element; } ENUM_GRAPH_OBJ_BELONG Belong(void) const { return this.m_belong; } ENUM_GRAPH_OBJ_SPECIES Species(void) const { return this.m_species; } ENUM_OBJECT TypeGraphObject(void) const { return this.m_type_graph_obj; } datetime TimeCreate(void) const { return this.m_create_time; } string Name(void) const { return this.m_name; } long ChartID(void) const { return this.m_chart_id; } long ObjectID(void) const { return this.m_object_id; } long Zorder(void) const { return this.m_zorder; } int SubWindow(void) const { return this.m_subwindow; } int ShiftY(void) const { return this.m_shift_y; } int VisibleOnTimeframes(void) const { return this.m_timeframes_visible; } int Digits(void) const { return this.m_digits; } int Group(void) const { return this.m_group; } bool IsBack(void) const { return this.m_back; } bool IsSelected(void) const { return this.m_selected; } bool IsSelectable(void) const { return this.m_selectable; } bool IsHidden(void) const { return this.m_hidden; } bool IsVisible(void) const { return this.m_visible; }
以前にグラフィカルオブジェクトの説明を返していたメソッドをグラフィカルオブジェクトのspeciesの説明を返すメソッドに名前変更します。
//--- Return the description of the type of the graphical object (1) type, (2) element, (3) affiliation and (4) species string TypeGraphObjectDescription(void); string TypeElementDescription(void); string BelongDescription(void); string SpeciesDescription(void);
オブジェクトspecies列挙定数の新しい名前に従って、その実装を修正します。
//+------------------------------------------------------------------+ //| Return the description of the graphical object group | //+------------------------------------------------------------------+ string CGBaseObj::SpeciesDescription(void) { return ( this.Species()==GRAPH_OBJ_SPECIES_LINES ? CMessage::Text(MSG_GRAPH_OBJ_PROP_SPECIES_LINES) : this.Species()==GRAPH_OBJ_SPECIES_CHANNELS ? CMessage::Text(MSG_GRAPH_OBJ_PROP_SPECIES_CHANNELS) : this.Species()==GRAPH_OBJ_SPECIES_GANN ? CMessage::Text(MSG_GRAPH_OBJ_PROP_SPECIES_GANN) : this.Species()==GRAPH_OBJ_SPECIES_FIBO ? CMessage::Text(MSG_GRAPH_OBJ_PROP_SPECIES_FIBO) : this.Species()==GRAPH_OBJ_SPECIES_ELLIOTT ? CMessage::Text(MSG_GRAPH_OBJ_PROP_SPECIES_ELLIOTT) : this.Species()==GRAPH_OBJ_SPECIES_SHAPES ? CMessage::Text(MSG_GRAPH_OBJ_PROP_SPECIES_SHAPES) : this.Species()==GRAPH_OBJ_SPECIES_ARROWS ? CMessage::Text(MSG_GRAPH_OBJ_PROP_SPECIES_ARROWS) : this.Species()==GRAPH_OBJ_SPECIES_GRAPHICAL ? CMessage::Text(MSG_GRAPH_OBJ_PROP_SPECIES_GRAPHICAL) : "Unknown" ); }
クラスコンストラクタで、デフォルトのオブジェクトグループを0に設定します。これは、グループがないことに対応します。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CGBaseObj::CGBaseObj() : m_shift_y(0),m_visible(false), m_name_prefix(::MQLInfoString(MQL_PROGRAM_NAME)+"_"),m_belong(GRAPH_OBJ_BELONG_PROGRAM) { this.m_list_events.Clear(); // Clear the event list this.m_list_events.Sort(); // Sorted list flag this.m_type=OBJECT_DE_TYPE_GBASE; // Object type this.m_type_graph_obj=WRONG_VALUE; // Graphical object type this.m_type_element=WRONG_VALUE; // Graphical object type this.m_belong=WRONG_VALUE; // Program/terminal affiliation this.m_group=0; // Graphical object group this.m_name_prefix=""; // Object name prefix this.m_name=""; // Object name this.m_chart_id=0; // Object chart ID this.m_object_id=0; // Object ID this.m_zorder=0; // Priority of a graphical object for receiving the mouse click event this.m_subwindow=0; // Subwindow index this.m_shift_y=0; // Subwindow Y coordinate shift this.m_timeframes_visible=OBJ_ALL_PERIODS; // Visibility of an object on timeframes (a set of flags) this.m_visible=true; // Object visibility this.m_back=false; // "Background object" flag this.m_selected=false; // "Object selection" flag this.m_selectable=false; // "Object availability" flag this.m_hidden=true; // "Disable displaying the name of a graphical object in the terminal object list" flag this.m_create_time=0; // Object creation time } //+------------------------------------------------------------------+
標準グラフィカルオブジェクトのメモリクラス
グラフィカルオブジェクトメモリクラスは、いずれかが変更された時点でのすべてのグラフィカルオブジェクトプロパティ(整数、実数、文字列のプロパティ)を備えたオブジェクトのリストです。変更されたプロパティだけではないのはなぜでしょうか。どのプロパティが変更されたかを知るだけでは不十分です。すべてのプロパティをオブジェクトに設定して、そのステータスを取得できるようにする必要があります。したがって、そのプロパティの完全なスナップショットを保存します。その場合、メモリから取得するプロパティと現在のステータスから取得するプロパティを計算することなく、これらすべてのプロパティをオブジェクトメモリから実際のプロパティにコピーできます。
変更されたオブジェクトプロパティスナップショットクラスを実装するためにCDataPropObjオブジェクトプロパティクラスを使用します。ただし、いくつかの追加パラメータ(変更時間、銘柄と桁数)を把握して考慮する必要があるため、変更されたオブジェクトプロパティスナップショットクラスは、グラフィカルオブジェクトプロパティオブジェクトクラスから継承されます。
グラフィカルオブジェクトメモリクラスには、変更されたプロパティスナップショットオブジェクトのリストが含まれ、これらのリストとそれに含まれるオブジェクトを処理するためのアクセスが提供されます。
これらのクラスは両方とも、\MQL5\Include\DoEasy\Services\Properties.mqhオブジェクトプロパティクラスファイルに配置されます。
ライブラリサービス関数のファイルをそれにインクルードします。
//+------------------------------------------------------------------+ //| Properties.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" #property strict // Necessary for mql4 //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "DELib.mqh" #include "XDimArray.mqh" //+------------------------------------------------------------------+
オブジェクトプロパティクラスのpublicセクションに、整数、実数、文字列のオブジェクトプロパティの数を返すメソッドを追加します。
//--- Return the number of (1) integer, (2) real and (3) string parameters int TotalLong(void) const { return this.m_total_int; } int TotalDouble(void) const { return this.m_total_dbl; } int TotalString(void) const { return this.m_total_str; } //--- Constructor
これらのメソッドは、変更履歴クラスのオブジェクトのプロパティ数を設定するのに役立ちます。
オブジェクトプロパティクラスの後には、オブジェクト変更プロパティスナップショットクラスが続きます。
//+------------------------------------------------------------------+ //| Object changed property snapshot class | //+------------------------------------------------------------------+ class CChangedProps : public CDataPropObj { private: long m_time_change; // Property modification time string m_symbol; // Chart window symbol int m_digits; // Symbol's Digits public: //--- Set the (1) change time value, (2) symbol and (3) symbol's Digits void SetTimeChanged(const long time) { this.m_time_change=time; } void SetSymbol(const string symbol) { this.m_symbol=symbol; } void SetDigits(const int digits) { this.m_digits=digits; } //--- Return the (1) change time value, (2) change time, (3) symbol and (4) symbol's Digits long TimeChanged(void) const { return this.m_time_change; } string TimeChangedToString(void) const { return TimeMSCtoString(this.m_time_change);} string Symbol(void) const { return this.m_symbol; } int Digits(void) const { return this.m_digits; } //--- Constructor/destructor CChangedProps (const int prop_total_integer,const int prop_total_double,const int prop_total_string,const long time_changed) : CDataPropObj(prop_total_integer,prop_total_double,prop_total_string) { this.m_time_change=time_changed;} ~CChangedProps (void){;} }; //+------------------------------------------------------------------+
ご覧のとおり、このクラスはグラフィカルオブジェクトプロパティオブジェクトクラスから派生しています 。したがって、親のすべてのプロパティと、クラスに設定された追加のプロパティがあります。ここでは、オブジェクトの変更時間(ミリ秒)、グラフィカルオブジェクトが変更されたチャートの銘柄、オブジェクトの価格プロパティの小数点以下の桁数を正しく表示するための数字のみが表示されます。
クラスコンストラクタで、整数、実数、文字列のプロパティの数とそれらの変更時間(ミリ秒単位)を渡します。
グラフィカルオブジェクトパラメータのコピーを作成し、それをパラメータ変更履歴クラスオブジェクトのリストに配置することができます。クラスは同じファイルでオブジェクト変更プロパティスナップショットのクラスのすぐ下に書き込まれます。
//+------------------------------------------------------------------+ //| Class of the history of graphical object property changes | //+------------------------------------------------------------------+ class CChangeHistory { private: CArrayObj m_list_changes; // List of the property change history public: //--- Return (1) the pointer to the property change history object and (2) the number of changes CChangedProps *GetChangedPropsObj(const string source,const int index) { CChangedProps *props=this.m_list_changes.At(index<0 ? 0 : index); if(props==NULL) CMessage::ToLog(source,MSG_GRAPH_OBJ_FAILED_GET_HIST_OBJ); return props; } int TotalChanges(void) { return this.m_list_changes.Total(); } //--- Create a new object of the graphical object property change history bool CreateNewElement(CDataPropObj *element,const long time_change) { //--- Create a new object of the graphical object property snapshot CChangedProps *obj=new CChangedProps(element.TotalLong(),element.TotalDouble(),element.TotalString(),time_change); //--- If failed to create an object, inform of that and return 'false' if(obj==NULL) { CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_FAILED_CREATE_NEW_HIST_OBJ); return false; } //--- If failed to add the object to the list, inform of that, remove the object and return 'false' if(!this.m_list_changes.Add(obj)) { CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_FAILED_ADD_OBJ_TO_HIST_LIST); delete obj; return false; } //--- Get the ID of the chart the graphical object is located on long chart_id=element.GetLong(GRAPH_OBJ_PROP_CHART_ID,0); //--- Set a chart symbol and symbol's Digits for the graphical object property snapshot object obj.SetSymbol(::ChartSymbol(chart_id)); obj.SetDigits((int)::SymbolInfoInteger(obj.Symbol(),SYMBOL_DIGITS)); //--- Copy all integer properties for(int i=0;i<element.TotalLong();i++) { int total=element.Long().Size(i); if(obj.SetSizeRange(i,total)) { for(int r=0;r<total;r++) obj.Long().Set(i,r,element.Long().Get(i,r)); } else CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_FAILED_INC_ARRAY_SIZE); } //--- Copy all real properties for(int i=0;i<element.TotalDouble();i++) { int total=element.Double().Size(i); if(obj.Double().SetSizeRange(i,total)) { for(int r=0;r<total;r++) obj.Double().Set(i,r,element.Double().Get(i,r)); } else CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_FAILED_INC_ARRAY_SIZE); } //--- Copy all string properties for(int i=0;i<element.TotalString();i++) { int total=element.String().Size(i); if(obj.String().SetSizeRange(i,total)) { for(int r=0;r<total;r++) obj.String().Set(i,r,element.String().Get(i,r)); } else CMessage::ToLog(DFUN,MSG_GRAPH_OBJ_FAILED_INC_ARRAY_SIZE); } return true; } //--- Return by index in the list of the graphical object change history object //--- the value from the specified index of the (1) long, (2) double and (3) string array long GetLong(const int time_index,const ENUM_GRAPH_OBJ_PROP_INTEGER prop,const int index) { CChangedProps *properties=this.GetChangedPropsObj(DFUN,time_index); if(properties==NULL) return 0; return properties.GetLong(prop,index); } double GetDouble(const int time_index,const ENUM_GRAPH_OBJ_PROP_DOUBLE prop,const int index) { CChangedProps *properties=this.GetChangedPropsObj(DFUN,time_index); if(properties==NULL) return 0; return properties.GetDouble(prop,index); } string GetString(const int time_index,const ENUM_GRAPH_OBJ_PROP_STRING prop,const int index) { CChangedProps *properties=this.GetChangedPropsObj(DFUN,time_index); if(properties==NULL) return ""; return properties.GetString(prop,index); } //--- Constructor/destructor CChangeHistory(void){;} ~CChangeHistory(void){;} }; //+------------------------------------------------------------------+
クラスもシンプルです。ここには、グラフィカルオブジェクト変更プロパティスナップショットクラスのオブジェクトによって表されるすべのグラフィカルオブジェクトの変更を含むリストがあります。
変更されたプロパティの新しいスナップショットを作成するメソッドは、現在の(すでに変更されている)グラフィカルオブジェクトのプロパティと変更時間をミリ秒単位で受け取ります。新しいプロパティスナップショットオブジェクトが作成され、リストに追加されます。さらに、オブジェクトに追加のパラメータが設定されます。次に、メソッドに渡された変更済みグラフィカルオブジェクトプロパティオブジェクトのすべてのプロパティが、3つのループで作成されたオブジェクトにコピーされます。
各グラフィックオブジェクトを変更すると、そのプロパティのコピーが作成されてリストに追加されるので、保存されたプロパティオブジェクトへのポインタを取得し、それをプログラムに使用できますようになります。
すべてのクラスメソッドは同じです。それらのロジックは非常に透過的です。リストから必要なプロパティオブジェクトを取得し、そこから要求されたプロパティを返るということです。
メソッドに関する質問がありましたら、下のコメント欄にお願いします。ここで説明しても意味がないと思います。このようなメソッドの論理は、以前の記事で繰り返し検討されています。
現在および以前のプロパティデータのクラスは、変更履歴オブジェクトへのポインタとグラフィカルオブジェクトの変更数を返すメソッドを受け取ります。クラスコンストラクタで、新しい変更履歴を作成してデストラクタで削除します。
//+------------------------------------------------------------------+ //| Data class of the current and previous properties | //+------------------------------------------------------------------+ class CProperties : public CObject { private: CArrayObj m_list; // List for storing the pointers to property objects public: CDataPropObj *Curr; // Pointer to the current properties object CDataPropObj *Prev; // Pointer to the previous properties object CChangeHistory *History; // Pointer to the change history object //--- Set the array size ('size') in the specified dimension ('range') bool SetSizeRange(const int range,const int size) { return(this.Curr.SetSizeRange(range,size) && this.Prev.SetSizeRange(range,size) ? true : false); } //--- Return the size of the specified array of the (1) current and (2) previous first dimension data int CurrSize(const int range) const { return Curr.Size(range); } int PrevSize(const int range) const { return Prev.Size(range); } //--- Copy the current data to the previous one void CurrentToPrevious(void) { //--- Copy all integer properties for(int i=0;i<this.Curr.Long().Total();i++) for(int r=0;r<this.Curr.Long().Size(i);r++) this.Prev.Long().Set(i,r,this.Curr.Long().Get(i,r)); //--- Copy all real properties for(int i=0;i<this.Curr.Double().Total();i++) for(int r=0;r<this.Curr.Double().Size(i);r++) this.Prev.Double().Set(i,r,this.Curr.Double().Get(i,r)); //--- Copy all string properties for(int i=0;i<this.Curr.String().Total();i++) for(int r=0;r<this.Curr.String().Size(i);r++) this.Prev.String().Set(i,r,this.Curr.String().Get(i,r)); } //--- Return the amount of graphical object changes since the start of recording them int TotalChanges(void) { return this.History.TotalChanges(); } //--- Constructor CProperties(const int prop_int_total,const int prop_double_total,const int prop_string_total) { //--- Create new objects of the current and previous properties this.Curr=new CDataPropObj(prop_int_total,prop_double_total,prop_string_total); this.Prev=new CDataPropObj(prop_int_total,prop_double_total,prop_string_total); //--- Add newly created objects to the list this.m_list.Add(this.Curr); this.m_list.Add(this.Prev); //--- Create the change history object this.History=new CChangeHistory(); } //--- Destructor ~CProperties() { this.m_list.Clear(); this.m_list.Shutdown(); if(this.History!=NULL) delete this.History; } }; //+------------------------------------------------------------------+
これで、各グラフィカルオブジェクトは、プロパティの変更のリストをそのプロパティに保存します。
グラフィカルオブジェクトの変更履歴を操作するには、\MQL5\Include\DoEasy\Objects\Graph\Standard\GStdGraphObj.mqhファイル(つまり、抽象標準グラフィカルオブジェクトクラス)に次のようにオブジェクトプロパティの変更履歴のリストへのポインタを返すメソッドを追加します。
public: //--- Set object's (1) integer, (2) real and (3) string properties void SetProperty(ENUM_GRAPH_OBJ_PROP_INTEGER property,int index,long value) { this.Prop.Curr.SetLong(property,index,value); } void SetProperty(ENUM_GRAPH_OBJ_PROP_DOUBLE property,int index,double value) { this.Prop.Curr.SetDouble(property,index,value); } void SetProperty(ENUM_GRAPH_OBJ_PROP_STRING property,int index,string value) { this.Prop.Curr.SetString(property,index,value); } //--- Return object’s (1) integer, (2) real and (3) string property from the properties array long GetProperty(ENUM_GRAPH_OBJ_PROP_INTEGER property,int index) const { return this.Prop.Curr.GetLong(property,index); } double GetProperty(ENUM_GRAPH_OBJ_PROP_DOUBLE property,int index) const { return this.Prop.Curr.GetDouble(property,index); } string GetProperty(ENUM_GRAPH_OBJ_PROP_STRING property,int index) const { return this.Prop.Curr.GetString(property,index); } //--- Set object's previous (1) integer, (2) real and (3) string properties void SetPropertyPrev(ENUM_GRAPH_OBJ_PROP_INTEGER property,int index,long value) { this.Prop.Prev.SetLong(property,index,value); } void SetPropertyPrev(ENUM_GRAPH_OBJ_PROP_DOUBLE property,int index,double value){ this.Prop.Prev.SetDouble(property,index,value); } void SetPropertyPrev(ENUM_GRAPH_OBJ_PROP_STRING property,int index,string value){ this.Prop.Prev.SetString(property,index,value); } //--- Return object’s (1) integer, (2) real and (3) string property from the previous properties array long GetPropertyPrev(ENUM_GRAPH_OBJ_PROP_INTEGER property,int index) const { return this.Prop.Prev.GetLong(property,index); } double GetPropertyPrev(ENUM_GRAPH_OBJ_PROP_DOUBLE property,int index) const { return this.Prop.Prev.GetDouble(property,index); } string GetPropertyPrev(ENUM_GRAPH_OBJ_PROP_STRING property,int index) const { return this.Prop.Prev.GetString(property,index); } //--- Return (1) itself, (2) properties and (3) the change history CGStdGraphObj *GetObject(void) { return &this; } CProperties *Properties(void) { return this.Prop; } CChangeHistory *History(void) { return this.Prop.History;} //--- Return the flag of the object supporting this property
クラスのデフォルトコンストラクタで、オブジェクトグループの表示を種の表示に置き換えます。閉じたパラメトリックコンストラクタで、グループではなくオブジェクトの種類を渡します。
//--- 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_OBJ_BELONG belong, const ENUM_GRAPH_OBJ_SPECIES species, const long chart_id, const int pivots, const string name);
簡略化されたアクセスとグラフィカルオブジェクトプロパティの設定のためのメソッドのブロックで、変更履歴を保存するフラグを設定および返すためのメソッドとグラフィカルオブジェクトのグループを追加します。
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); } //--- 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); } //--- Graphical element type ENUM_GRAPH_ELEMENT_TYPE GraphElementType(void) const { return (ENUM_GRAPH_ELEMENT_TYPE)this.GetProperty(GRAPH_OBJ_PROP_ELEMENT_TYPE,0);} void SetGraphElementType(const ENUM_GRAPH_ELEMENT_TYPE elm_type) { CGBaseObj::SetTypeElement(elm_type); this.SetProperty(GRAPH_OBJ_PROP_ELEMENT_TYPE,0,elm_type); } //--- Graphical object affiliation ENUM_GRAPH_OBJ_BELONG Belong(void) const { return (ENUM_GRAPH_OBJ_BELONG)this.GetProperty(GRAPH_OBJ_PROP_BELONG,0); } void SetBelong(const ENUM_GRAPH_OBJ_BELONG belong) { CGBaseObj::SetBelong(belong); this.SetProperty(GRAPH_OBJ_PROP_BELONG,0,belong); } //--- Group of graphical objects int Group(void) const { return (int)this.GetProperty(GRAPH_OBJ_PROP_GROUP,0); } void SetGroup(const int group) { CGBaseObj::SetGroup(group); this.SetProperty(GRAPH_OBJ_PROP_GROUP,0,group); } //--- Chart ID
デフォルトでは、グラフの各グラフィックオブジェクトはその変更履歴を記録しません。これを開始するには、変更履歴の記録を許可するフラグを設定するメソッドを使用します。グラフィックオブジェクトのグループには、チャート上のさまざまなグラフィックオブジェクトが含まれ、それらを選択して必要なアクションを実行するために使用されるグループに結合されます。
オブジェクト変更履歴を操作するためのメソッドを追加します。
//--- Re-write all graphical object properties void PropertiesRefresh(void); //--- Check object property changes void PropertiesCheckChanged(void); //--- Copy the current data to the previous one void PropertiesCopyToPrevData(void); //--- Return (1) the number of property changes in history specified (2) by the property index, (3) the last and (4) the first changed object int HistoryChangesTotal(void) { return this.History().TotalChanges(); } CChangedProps *GetHistoryChangedProps(const string source,const int index) { return this.History().GetChangedPropsObj(source,index); } CChangedProps *GetHistoryChangedPropsLast(const string source) { return this.History().GetChangedPropsObj(source,this.HistoryChangesTotal()-1); } CChangedProps *GetHistoryChangedPropsFirst(const string source) { return this.History().GetChangedPropsObj(source,0); } //--- Using the specified index in the list of change history objects, return //--- the specified value of (1) integer, (2) real and (3) string property long HistoryChangedObjGetLong(const int time_index,const ENUM_GRAPH_OBJ_PROP_INTEGER prop,const int prop_index) { CChangedProps *obj=this.GetHistoryChangedProps(DFUN,time_index); return(obj!=NULL ? obj.GetLong(prop,prop_index) : 0); } double HistoryChangedObjGetDouble(const int time_index,const ENUM_GRAPH_OBJ_PROP_DOUBLE prop,const int prop_index) { CChangedProps *obj=this.GetHistoryChangedProps(DFUN,time_index); return(obj!=NULL ? obj.GetDouble(prop,prop_index) : 0); } string HistoryChangedObjGetString(const int time_index,const ENUM_GRAPH_OBJ_PROP_STRING prop,const int prop_index) { CChangedProps *obj=this.GetHistoryChangedProps(DFUN,time_index); return(obj!=NULL ? obj.GetString(prop,prop_index) : "ERROR"); } //--- Return (1) a symbol, (2) symbol's Digits and (3) the time of changing the change history object string HistoryChangedObjSymbol(const int time_index) { CChangedProps *obj=this.GetHistoryChangedProps(DFUN,time_index); return(obj!=NULL ? obj.Symbol() : "ERROR"); } int HistoryChangedObjDigits(const int time_index) { CChangedProps *obj=this.GetHistoryChangedProps(DFUN,time_index); return(obj!=NULL ? obj.Digits() : 0); } long HistoryChangedObjTimeChanged(const int time_index) { CChangedProps *obj=this.GetHistoryChangedProps(DFUN,time_index); return(obj!=NULL ? obj.TimeChanged() : 0); } string HistoryChangedObjTimeChangedToString(const int time_index) { CChangedProps *obj=this.GetHistoryChangedProps(DFUN,time_index); return(obj!=NULL ? obj.TimeChangedToString() : "ERROR"); } //--- Set object parameters from the specified history snapshot bool SetPropertiesFromHistory(const int time_index) { CChangedProps *obj=this.GetHistoryChangedProps(DFUN,time_index); if(obj==NULL) return false; int begin=0, end=GRAPH_OBJ_PROP_INTEGER_TOTAL; for(int i=begin; i<end; i++) { ENUM_GRAPH_OBJ_PROP_INTEGER prop=(ENUM_GRAPH_OBJ_PROP_INTEGER)i; for(int j=0;j<this.Prop.CurrSize(prop);j++) if(this.GetProperty(prop,j)!=obj.GetLong(prop,j)) this.SetHistoryINT(prop,obj.GetLong(prop,j),j); } begin=end; end+=GRAPH_OBJ_PROP_DOUBLE_TOTAL; for(int i=begin; i<end; i++) { ENUM_GRAPH_OBJ_PROP_DOUBLE prop=(ENUM_GRAPH_OBJ_PROP_DOUBLE)i; for(int j=0;j<this.Prop.CurrSize(prop);j++) { if(this.GetProperty(prop,j)!=obj.GetDouble(prop,j)) this.SetHistoryDBL(prop,obj.GetDouble(prop,j),j); } } begin=end; end+=GRAPH_OBJ_PROP_STRING_TOTAL; for(int i=begin; i<end; i++) { ENUM_GRAPH_OBJ_PROP_STRING prop=(ENUM_GRAPH_OBJ_PROP_STRING)i; for(int j=0;j<this.Prop.CurrSize(prop);j++) if(this.GetProperty(prop,j)!=obj.GetString(prop,j)) this.SetHistorySTR(prop,obj.GetString(prop,j),j); } return true; }
ほとんどすべてのメソッドは、グラフィカルオブジェクト変更履歴クラスの同じ名前のメソッドを呼び出した結果を返します。
指定された履歴スナップショットからグラフィカルオブジェクトのプロパティを設定するメソッドは、3つのループで、インデックスによってオブジェクトを受け取り、SetHistoryINT()、SetHistoryDBL()、およびSetHistorySTR()メソッド(以下で検討)を使用して、履歴スナップショットオブジェクトからグラフィカルオブジェクトにすべてのプロパティを設定します。
クラスのprivateセクションにメソッドを追加します。
private: //--- Get and save (1) integer, (2) real and (3) string properties void GetAndSaveINT(void); void GetAndSaveDBL(void); void GetAndSaveSTR(void); //--- Create a new object of the graphical object change history bool CreateNewChangeHistoryObj(const bool first) { bool res=true; if(first) res &=this.History().CreateNewElement(this.Prop.Prev,this.GetMarketWatchTime()); res &=this.History().CreateNewElement(this.Prop.Curr,this.GetMarketWatchTime()); if(!res) CMessage::ToLog(DFUN,MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_SNAPSHOT); return res; } //--- Set (1) integer, (2) real and (3) string property values from the change history void SetHistoryINT(const ENUM_GRAPH_OBJ_PROP_INTEGER prop,const long value,const int modifier); void SetHistoryDBL(const ENUM_GRAPH_OBJ_PROP_DOUBLE prop,const double value,const int modifier); void SetHistorySTR(const ENUM_GRAPH_OBJ_PROP_STRING prop,const string value,const int modifier); //--- Return the time of the last symbol tick long GetSymbolTime(const string symbol) { MqlTick tick; return(::SymbolInfoTick(symbol,tick) ? tick.time_msc : 0); } //--- Return the time of the last Market Watch tick long GetMarketWatchTime(void) { long res=0; for(int i=::SymbolsTotal(true)-1;i>WRONG_VALUE;i--) { const long time=this.GetSymbolTime(::SymbolName(i,true)); if(time>res) res=time; } return res; } }; //+------------------------------------------------------------------+
グラフィカルオブジェクトの変更履歴の新しいオブジェクトを作成するメソッドは、最初のグラフィカルオブジェクトの変更のフラグを渡します。
フラグが設定されている場合、これが最初の変更です。まず、以前のグラフィックオブジェクトのステータスを履歴に保存する必要があります(プロパティを変更する前に)。次に、現在のオブジェクトのステータスを履歴に書き込みます。フラグが設定されていない場合は、現在のオブジェクトのステータスを変更履歴に保存します。
//--- Create a new object of the graphical object change history bool CreateNewChangeHistoryObj(const bool first) { bool res=true; if(first) res &=this.History().CreateNewElement(this.Prop.Prev,this.GetMarketWatchTime()); res &=this.History().CreateNewElement(this.Prop.Curr,this.GetMarketWatchTime()); if(!res) CMessage::ToLog(DFUN,MSG_GRAPH_STD_OBJ_ERR_FAILED_CREATE_SNAPSHOT); return res; }
呼び出されたメソッドの結果は、結果のres変数に追加され、呼び出されたメソッドのいずれかがfalseを返す場合にのみfalseと等しくなります。その結果、変数値を返します。
気配値表示での最後のティックの時刻を返すメソッドは、気配値表示ウィンドウ内のすべての銘柄を繰り返し処理して、現在の時刻をミリ秒単位で読み取り、各銘柄の時刻を比較して最も再送された時刻を返します。
//--- Return the time of the last Market Watch tick long GetMarketWatchTime(void) { long res=0; for(int i=::SymbolsTotal(true)-1;i>WRONG_VALUE;i--) { const long time=this.GetSymbolTime(::SymbolName(i,true)); if(time>res) res=time; } return res; }
protectedパラメトリックコンストラクタで、グラフィカルオブジェクトの種類(グループではなく)を渡し、すべての新しいプロパティをオブジェクトに設定します。
//+------------------------------------------------------------------+ //| Protected parametric constructor | //+------------------------------------------------------------------+ CGStdGraphObj::CGStdGraphObj(const ENUM_OBJECT_DE_TYPE obj_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(GRAPH_ELEMENT_TYPE_STANDARD); 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_NUM,0,0); // Object index in the list this.SetProperty(GRAPH_OBJ_PROP_CHANGE_HISTORY,0,false); // Flag of storing the change history< //--- 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(); } //+-------------------------------------------------------------------+
オブジェクト整数プロパティの説明を返すメソッドは新しいオブジェクトプロパティの説明を受け取ります。
//+------------------------------------------------------------------+ //| 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_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) : ": "+(string)this.GetProperty(property,0) ) : 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) ) : "" ); } //+------------------------------------------------------------------+
変更履歴の記録を許可するフラグが設定されている場合、オブジェクトのプロパティの変更を確認するメソッドに、グラフィカルオブジェクトの変更履歴の新しいオブジェクトを作成するコードブロックを追加します。
//+------------------------------------------------------------------+ //| Check object property changes | //+------------------------------------------------------------------+ void CGStdGraphObj::PropertiesCheckChanged(void) { CGBaseObj::ClearEventsList(); bool changed=false; int begin=0, end=GRAPH_OBJ_PROP_INTEGER_TOTAL; for(int i=begin; i<end; i++) { ENUM_GRAPH_OBJ_PROP_INTEGER prop=(ENUM_GRAPH_OBJ_PROP_INTEGER)i; if(!this.SupportProperty(prop)) continue; for(int j=0;j<Prop.CurrSize(prop);j++) { if(this.GetProperty(prop,j)!=this.GetPropertyPrev(prop,j)) { changed=true; this.CreateAndAddNewEvent(GRAPH_OBJ_EVENT_CHANGE,this.ChartID(),prop,this.Name()); } } } begin=end; end+=GRAPH_OBJ_PROP_DOUBLE_TOTAL; for(int i=begin; i<end; i++) { ENUM_GRAPH_OBJ_PROP_DOUBLE prop=(ENUM_GRAPH_OBJ_PROP_DOUBLE)i; if(!this.SupportProperty(prop)) continue; for(int j=0;j<Prop.CurrSize(prop);j++) { if(this.GetProperty(prop,j)!=this.GetPropertyPrev(prop,j)) { changed=true; this.CreateAndAddNewEvent(GRAPH_OBJ_EVENT_CHANGE,this.ChartID(),prop,this.Name()); } } } begin=end; end+=GRAPH_OBJ_PROP_STRING_TOTAL; for(int i=begin; i<end; i++) { ENUM_GRAPH_OBJ_PROP_STRING prop=(ENUM_GRAPH_OBJ_PROP_STRING)i; if(!this.SupportProperty(prop)) continue; for(int j=0;j<Prop.CurrSize(prop);j++) { if(this.GetProperty(prop,j)!=this.GetPropertyPrev(prop,j) && prop!=GRAPH_OBJ_PROP_NAME) { changed=true; this.CreateAndAddNewEvent(GRAPH_OBJ_EVENT_CHANGE,this.ChartID(),prop,this.Name()); } } } if(changed) { for(int i=0;i<this.m_list_events.Total();i++) { CGBaseEvent *event=this.m_list_events.At(i); if(event==NULL) continue; ::EventChartCustom(::ChartID(),event.ID(),event.Lparam(),event.Dparam(),event.Sparam()); } if(this.AllowChangeHistory()) { int total=HistoryChangesTotal(); if(this.CreateNewChangeHistoryObj(total<1)) ::Print ( DFUN,CMessage::Text(MSG_GRAPH_STD_OBJ_SUCCESS_CREATE_SNAPSHOT)," #",(total==0 ? "0-1" : (string)total), ": ",this.HistoryChangedObjTimeChangedToString(total-1) ); } this.PropertiesCopyToPrevData(); } } //+------------------------------------------------------------------+
ここで、グラフィカルオブジェクトの変更量を取得し、それらをboolフラグの形式でオブジェクトプロパティの新しいスナップショットオブジェクトを作成するメソッドに渡します( totalが1未満の場合、渡される値はtrueです。これは、これがグラフィカルオブジェクトの最初の変更であることを意味します。オブジェクトが作成されて変更リストに追加されると、適切なメッセージが変更インデックスとともに操作ログに表示されます。これが最初の変更である場合、メッセージには「0-1」が含まれます。これは、2つのオブジェクトが同時に作成されたことを意味します(0-プロパティを変更する前のグラフィカルオブジェクトステータス、1-オブジェクトの現在のステータス)。
以下は、グラフィックオブジェクトの変更履歴から整数、実数、文字列プロパティ値を設定するメソッドです。
//+------------------------------------------------------------------+ //| Set integer property values from the change history | //| for the graphical object | //+------------------------------------------------------------------+ void CGStdGraphObj::SetHistoryINT(const ENUM_GRAPH_OBJ_PROP_INTEGER prop,const long value,const int modifier) { switch(prop) { case GRAPH_OBJ_PROP_TIMEFRAMES : this.SetVisibleOnTimeframes((int)value,false); break; // Object visibility on timeframes case GRAPH_OBJ_PROP_BACK : this.SetFlagBack(value,false); break; // Background object case GRAPH_OBJ_PROP_ZORDER : this.SetZorder(value,false); break; // Priority of a graphical object for receiving the event of clicking on a chart case GRAPH_OBJ_PROP_HIDDEN : this.SetFlagHidden(value,false); break; // Disable displaying the name of a graphical object in the terminal object list case GRAPH_OBJ_PROP_SELECTED : this.SetFlagSelected(value,false); break; // Object selection case GRAPH_OBJ_PROP_SELECTABLE : this.SetFlagSelectable(value,false); break; // Object availability case GRAPH_OBJ_PROP_TIME : this.SetTime(value,modifier); break; // Time coordinate case GRAPH_OBJ_PROP_COLOR : this.SetColor((color)value); break; // Color case GRAPH_OBJ_PROP_STYLE : this.SetStyle((ENUM_LINE_STYLE)value); break; // Style case GRAPH_OBJ_PROP_WIDTH : this.SetWidth((int)value); break; // Line width case GRAPH_OBJ_PROP_FILL : this.SetFlagFill(value); break; // Filling an object with color case GRAPH_OBJ_PROP_READONLY : this.SetFlagReadOnly(value); break; // Ability to edit text in the Edit object case GRAPH_OBJ_PROP_LEVELS : this.SetLevels((int)value); break; // Number of levels case GRAPH_OBJ_PROP_LEVELCOLOR : this.SetLevelColor((color)value,modifier); break; // Level line color case GRAPH_OBJ_PROP_LEVELSTYLE : this.SetLevelStyle((ENUM_LINE_STYLE)value,modifier); break; // Level line style case GRAPH_OBJ_PROP_LEVELWIDTH : this.SetLevelWidth((int)value,modifier); break; // Level line width case GRAPH_OBJ_PROP_ALIGN : this.SetAlign((ENUM_ALIGN_MODE)value); break; // Horizontal text alignment in the Edit object (OBJ_EDIT) case GRAPH_OBJ_PROP_FONTSIZE : this.SetFontSize((int)value); break; // Font size case GRAPH_OBJ_PROP_RAY_LEFT : this.SetFlagRayLeft(value); break; // Ray goes to the left case GRAPH_OBJ_PROP_RAY_RIGHT : this.SetFlagRayRight(value); break; // Ray goes to the right case GRAPH_OBJ_PROP_RAY : this.SetFlagRay(value); break; // Vertical line goes through all windows of a chart case GRAPH_OBJ_PROP_ELLIPSE : this.SetFlagEllipse(value); break; // Display the full ellipse of the Fibonacci Arc object case GRAPH_OBJ_PROP_ARROWCODE : this.SetArrowCode((uchar)value); break; // Arrow code for the Arrow object case GRAPH_OBJ_PROP_ANCHOR : this.SetAnchor((int)value); break; // Position of the binding point of the graphical object case GRAPH_OBJ_PROP_XDISTANCE : this.SetXDistance((int)value); break; // Distance from the base corner along the X axis in pixels case GRAPH_OBJ_PROP_YDISTANCE : this.SetYDistance((int)value); break; // Distance from the base corner along the Y axis in pixels case GRAPH_OBJ_PROP_DIRECTION : this.SetDirection((ENUM_GANN_DIRECTION)value); break; // Gann object trend case GRAPH_OBJ_PROP_DEGREE : this.SetDegree((ENUM_ELLIOT_WAVE_DEGREE)value); break; // Elliott wave markup level case GRAPH_OBJ_PROP_DRAWLINES : this.SetFlagDrawLines(value); break; // Display lines for Elliott wave markup case GRAPH_OBJ_PROP_STATE : this.SetFlagState(value); break; // Button state (pressed/released) case GRAPH_OBJ_PROP_CHART_OBJ_CHART_ID : this.SetChartObjChartID(value); break; // Chart object ID (OBJ_CHART) case GRAPH_OBJ_PROP_CHART_OBJ_PERIOD : this.SetChartObjPeriod((ENUM_TIMEFRAMES)value); break; // Chart object period case GRAPH_OBJ_PROP_CHART_OBJ_DATE_SCALE : this.SetChartObjChartScale((int)value); break; // Time scale display flag for the Chart object case GRAPH_OBJ_PROP_CHART_OBJ_PRICE_SCALE : this.SetFlagChartObjPriceScale(value); break; // Price scale display flag for the Chart object case GRAPH_OBJ_PROP_CHART_OBJ_CHART_SCALE : this.SetFlagChartObjDateScale(value); break; // Chart object scale case GRAPH_OBJ_PROP_XSIZE : this.SetXSize((int)value); break; // Object distance along the X axis in pixels case GRAPH_OBJ_PROP_YSIZE : this.SetYSize((int)value); break; // Object height along the Y axis in pixels case GRAPH_OBJ_PROP_XOFFSET : this.SetXOffset((int)value); break; // X coordinate of the upper-left corner of the visibility area case GRAPH_OBJ_PROP_YOFFSET : this.SetYOffset((int)value); break; // Y coordinate of the upper-left corner of the visibility area case GRAPH_OBJ_PROP_BGCOLOR : this.SetBGColor((color)value); break; // Background color for OBJ_EDIT, OBJ_BUTTON, OBJ_RECTANGLE_LABEL case GRAPH_OBJ_PROP_CORNER : this.SetCorner((ENUM_BASE_CORNER)value); break; // Chart corner for binding a graphical object case GRAPH_OBJ_PROP_BORDER_TYPE : this.SetBorderType((ENUM_BORDER_TYPE)value); break; // Border type for "Rectangle border" case GRAPH_OBJ_PROP_BORDER_COLOR : this.SetBorderColor((color)value); break; // Border color for the OBJ_EDIT and OBJ_BUTTON objects case GRAPH_OBJ_PROP_ID : // Object ID case GRAPH_OBJ_PROP_TYPE : // Graphical object type (ENUM_OBJECT) case GRAPH_OBJ_PROP_ELEMENT_TYPE : // Graphical element type (ENUM_GRAPH_ELEMENT_TYPE) case GRAPH_OBJ_PROP_SPECIES : // Graphical object species (ENUM_GRAPH_OBJ_SPECIES) case GRAPH_OBJ_PROP_GROUP : // Graphical object group case GRAPH_OBJ_PROP_BELONG : // Graphical object affiliation case GRAPH_OBJ_PROP_CHART_ID : // Chart ID case GRAPH_OBJ_PROP_WND_NUM : // Chart subwindow index case GRAPH_OBJ_PROP_NUM : // Object index in the list case GRAPH_OBJ_PROP_CHANGE_HISTORY : // Flag of storing the change history case GRAPH_OBJ_PROP_CREATETIME : // Object creation time default : break; } } //+------------------------------------------------------------------+ //| Set real property values from the change history | //| for the graphical object | //+------------------------------------------------------------------+ void CGStdGraphObj::SetHistoryDBL(const ENUM_GRAPH_OBJ_PROP_DOUBLE prop,const double value,const int modifier) { switch(prop) { case GRAPH_OBJ_PROP_PRICE : this.SetPrice(value,modifier); break; // Price coordinate case GRAPH_OBJ_PROP_LEVELVALUE : this.SetLevelValue(value,modifier); break; // Level value case GRAPH_OBJ_PROP_SCALE : this.SetScale(value); break; // Scale (property of Gann objects and Fibonacci Arcs objects) case GRAPH_OBJ_PROP_ANGLE : this.SetAngle(value); break; // Angle case GRAPH_OBJ_PROP_DEVIATION : this.SetDeviation(value); break; // Deviation of the standard deviation channel default: break; } } //+------------------------------------------------------------------+ //| Set string property values from the change history | //| for the graphical object | //+------------------------------------------------------------------+ void CGStdGraphObj::SetHistorySTR(const ENUM_GRAPH_OBJ_PROP_STRING prop,const string value,const int modifier) { switch(prop) { case GRAPH_OBJ_PROP_TEXT : this.SetText(value); break; // Object description (the text contained in the object) case GRAPH_OBJ_PROP_TOOLTIP : this.SetTooltip(value); break; // Tooltip text case GRAPH_OBJ_PROP_LEVELTEXT : this.SetLevelText(value,modifier); break; // Level description case GRAPH_OBJ_PROP_FONT : this.SetFont(value); break; // Font case GRAPH_OBJ_PROP_BMPFILE : this.SetBMPFile(value,modifier); break; // BMP file name for the "Bitmap Level" object case GRAPH_OBJ_PROP_CHART_OBJ_SYMBOL : this.SetChartObjSymbol(value); break; // Chart object symbol case GRAPH_OBJ_PROP_NAME : // Object name default : break; } } //+------------------------------------------------------------------+
ここではswitch演算子で、メソッドに渡されるプロパティに応じて、クラスオブジェクトとグラフィカルの両方でオブジェクトプロパティ値を設定するための適切なメソッド オブジェクトが選択されています。プロパティ変更履歴オブジェクトに必要のないプロパティにはcaseハンドラがないため、コードの実行はdefaultラベルに到達し、break演算子で終了します。
\MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqhのグラフィカル要素コレクションクラスで、チャートIDとグループごとにオブジェクトのリストを返すメソッドを追加します。
//--- Return (1) the last removed graphical object and (2) the array size of graphical object properties CGStdGraphObj *GetLastDeletedGraphObj(void) const { return this.m_list_deleted_obj.At(this.m_list_deleted_obj.Total()-1); } int GetSizeProperty(const string name,const long chart_id,const int prop) { CGStdGraphObj *obj=this.GetStdGraphObject(name,chart_id); return(obj!=NULL ? obj.Properties().CurrSize(prop) : 0); } //--- Return the list of objects by chart ID and group CArrayObj *GetListStdGraphObjByGroup(const long chart_id,const int group) { CArrayObj *list=GetList(GRAPH_OBJ_PROP_CHART_ID,0,chart_id,EQUAL); return CSelect::ByGraphicStdObjectProperty(list,GRAPH_OBJ_PROP_GROUP,0,group,EQUAL); } //--- Constructor
メソッドはチャートIDですべてのグラフィカルオブジェクトのリストを受け取り、取得したリストから指定されたグループ値を持つオブジェクトのリストを返します。
プログラムでこのメソッドを使用すると、必要な方法でオブジェクトを処理するために、単一のグループが割り当てられたグラフィックオブジェクトのリストを取得できます。
ライブラリベースのプログラムで変更履歴データ全体を取得するには、\MQL5\Include\DoEasy\Engine.mqhのCEngineライブラリメインオブジェクトに変更を加える必要があります。
既存のグラフィックオブジェクトのリストを返すメソッドとチャート名とIDで標準グラフィックオブジェクトのオブジェクトのクラスへのポインタを返すメソッドを追加します。
//--- Return the (1) collection of graphical objects, the list of (2) existing and (3) removed graphical objects CGraphElementsCollection *GetGraphicObjCollection(void) { return &this.m_graph_objects; } CArrayObj *GetListStdGraphObj(void) { return this.m_graph_objects.GetListGraphObj(); } CArrayObj *GetListDeletedObj(void) { return this.m_graph_objects.GetListDeletedObj(); } //--- Return (1) the number of removed graphical objects and (2) the size of the property array int TotalDeletedGraphObjects(void) { return this.GetListDeletedObj().Total(); } int GraphGetSizeProperty(const string name,const long chart_id,const int prop) { return this.m_graph_objects.GetSizeProperty(name,chart_id,prop); } //--- 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) { return this.m_graph_objects.GetStdGraphObject(name,chart_id); } //--- Fill in the array with IDs of the charts opened in the terminal
メソッドは、グラフィカル要素コレクションクラスの同じ名前のメソッドを呼び出した結果を返します。
グラフィカルオブジェクトの変更履歴の処理をテストするために必要なライブラリクラスの変更と改善はこれで全部です。
テスト
テストを実行するには、前の記事のEAを使用して、\MQL5\Experts\TestDoEasy\Part92\にTestDoEasyPart92.mq5として保存します。
チャート上に新しく作成されたグラフィックオブジェクトごとに変更履歴の保存を許可するフラグが設定され、グループ1が作成されます。したがって、チャートに追加されるすべてのグラフィカルオブジェクトは、1つのグループに分類され、変更履歴を書き込むことができます。次に、各グラフィックオブジェクトを変更します。すべての変更はそのメモリに書き込まれます。
変更履歴を表示するためのキーを設定します。
- 「>」(Shiftなしの「.」)は、オブジェクト変更リストのインデックスをその増加方向に1ずつ移動します。
- 「<」(Shiftなしの「,」)は、オブジェクト変更リストのインデックスを減少方向に1ずつ移動します。
- 「/」は、オブジェクト変更リストのインデックスを最初に移動します—グラフィカルオブジェクトプロパティのオブジェクトは、最初の変更前に存在していた初期値とともにそこに格納されます。
キーを押すと、グラフィカルオブジェクトが変更されるたびに持っていたすべてのプロパティをどのように受け取るかがわかります。
指定されたボタンのマクロ置換を設定します。
//+------------------------------------------------------------------+ //| TestDoEasyPart92.mq5 | //| Copyright 2021, MetaQuotes Ltd. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" //--- includes #include <DoEasy\Engine.mqh> //--- defines #define FORMS_TOTAL (4) // Number of created forms #define START_X (4) // Initial X coordinate of the shape #define START_Y (4) // Initial Y coordinate of the shape #define KEY_LEFT (188) // Left #define KEY_RIGHT (190) // Right #define KEY_ORIGIN (191) // Initial properties //--- input parameters sinput bool InpMovable = true; // Movable forms flag sinput ENUM_INPUT_YES_NO InpUseColorBG = INPUT_YES; // Use chart background color to calculate shadow color sinput color InpColorForm3 = clrCadetBlue; // Third form shadow color (if not background color) //--- global variables CEngine engine; CArrayObj list_forms; color array_clr[]; //+------------------------------------------------------------------+
イベントハンドラで、キーストロークを処理するコードブロックを追加します。グラフィカルオブジェクト作成イベントを処理するブロックで、変更履歴の保存を許可するフラグを設定するようにします。グループ1 も追加します。
//+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- If working in the tester, exit if(MQLInfoInteger(MQL_TESTER)) return; //--- If the mouse is moved /* if(id==CHARTEVENT_MOUSE_MOVE) { CForm *form=NULL; datetime time=0; double price=0; int wnd=0; //--- If Ctrl is not pressed, if(!IsCtrlKeyPressed()) { //--- clear the list of created form objects, allow scrolling a chart with the mouse and show the context menu list_forms.Clear(); ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,true); ChartSetInteger(ChartID(),CHART_CONTEXT_MENU,true); return; } //--- If X and Y chart coordinates are successfully converted into time and price, if(ChartXYToTimePrice(ChartID(),(int)lparam,(int)dparam,wnd,time,price)) { //--- get the bar index the cursor is hovered over int index=iBarShift(Symbol(),PERIOD_CURRENT,time); if(index==WRONG_VALUE) return; //--- Get the bar index by index CBar *bar=engine.SeriesGetBar(Symbol(),Period(),index); if(bar==NULL) return; //--- Convert the coordinates of a chart from the time/price representation of the bar object to the X and Y coordinates int x=(int)lparam,y=(int)dparam; if(!ChartTimePriceToXY(ChartID(),0,bar.Time(),(bar.Open()+bar.Close())/2.0,x,y)) return; //--- Disable moving a chart with the mouse and showing the context menu ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,false); ChartSetInteger(ChartID(),CHART_CONTEXT_MENU,false); //--- Create the form object name and hide all objects except one having such a name string name="FormBar_"+(string)index; HideFormAllExceptOne(name); //--- If the form object with such a name does not exist yet, if(!IsPresentForm(name)) { //--- create a new form object form=bar.CreateForm(index,name,x,y,114,16); if(form==NULL) return; //--- Set activity and unmoveability flags for the form form.SetActive(true); form.SetMovable(false); //--- Set the opacity of 200 form.SetOpacity(200); //--- The form background color is set as the first color from the color array form.SetColorBackground(array_clr[0]); //--- Form outlining frame color form.SetColorFrame(C'47,70,59'); //--- Draw the shadow drawing flag form.SetShadow(true); //--- Calculate the shadow color as the chart background color converted to the monochrome one color clrS=form.ChangeColorSaturation(form.ColorBackground(),-100); //--- If the settings specify the usage of the chart background color, replace the monochrome color with 20 units //--- Otherwise, use the color specified in the settings for drawing the shadow color clr=(InpUseColorBG ? form.ChangeColorLightness(clrS,-20) : InpColorForm3); //--- Draw the form shadow with the right-downwards offset from the form by three pixels along all axes //--- Set the shadow opacity to 200, while the blur radius is equal to 4 form.DrawShadow(2,2,clr,200,3); //--- Fill the form background with a vertical gradient form.Erase(array_clr,form.Opacity()); //--- Draw an outlining rectangle at the edges of the form form.DrawRectangle(0,0,form.Width()-1,form.Height()-1,form.ColorFrame(),form.Opacity()); //--- If failed to add the form object to the list, remove the form and exit the handler if(!list_forms.Add(form)) { delete form; return; } //--- Capture the form appearance form.Done(); } //--- If the form object exists, if(form!=NULL) { //--- draw a text with the bar type description on it and show the form. The description corresponds to the mouse cursor position form.TextOnBG(0,bar.BodyTypeDescription(),form.Width()/2,form.Height()/2-1,FRAME_ANCHOR_CENTER,C'7,28,21'); form.Show(); } //--- Re-draw the chart ChartRedraw(); } } */ //--- If a key is pressed if(id==CHARTEVENT_KEYDOWN) { //---Declare the index of the current graphical object change history object static int index=0; //--- Get the list of all graphical objects with the specified group index (1) CArrayObj *list=engine.GetListStdGraphObj(); list=CSelect::ByGraphicStdObjectProperty(list,GRAPH_OBJ_PROP_GROUP,0,1,EQUAL); if(list==NULL || list.Total()==0) return; //--- If "/" is pressed if(lparam==KEY_ORIGIN) { //--- Set the index 0 in the list of the graphical object change history object index=0; //--- In the loop by the number of group 1 objects on the chart for(int i=0;i<list.Total();i++) { //--- Get the next object from the list and set the initial properties from the change history to it CGStdGraphObj *obj=list.At(i); if(obj==NULL) continue; obj.SetPropertiesFromHistory(index); } } //--- If "." is pressed if(lparam==KEY_RIGHT) { //--- Declare the variables to search for the maximum number of changes of all group 1 graphical objects int change_max=0, changes_total=0; //--- Increase the object index in the list of the graphical object change history index++; //--- In the loop by the number of group 1 objects on the chart for(int i=0;i<list.Total();i++) { //--- Get the next object from the list CGStdGraphObj *obj=list.At(i); if(obj==NULL) continue; //--- Calculate the maximum number of changes of all group 1 graphical objects changes_total=obj.HistoryChangesTotal(); if(changes_total>change_max) change_max=changes_total; //--- Set the properties (by 'index' from the list) from the change history obj.SetPropertiesFromHistory(index>obj.HistoryChangesTotal()-1 ? obj.HistoryChangesTotal()-1 : index); } //--- If the change history object index exceeds the maximum number of changes of all objects, //--- set the index equal to the maximum amount of changes of all graphical objects if(index>change_max-1) index=change_max-1; } //--- If "," is pressed if(lparam==KEY_LEFT) { //--- Decrease the object index in the list of the graphical object change history index--; //--- If the index is less than zero, set it to 0 if(index<0) index=0; //--- In the loop by the number of group 1 objects on the chart for(int i=0;i<list.Total();i++) { //--- Get the next object from the list CGStdGraphObj *obj=list.At(i); if(obj==NULL) continue; //--- Set the properties (by 'index' from the list) from the change history obj.SetPropertiesFromHistory(index); } } //--- Re-draw the chart for displaying changes in graphical objects ChartRedraw(); } if(id==CHARTEVENT_CLICK) { if(!IsCtrlKeyPressed()) return; datetime time=0; double price=0; int sw=0; if(ChartXYToTimePrice(ChartID(),(int)lparam,(int)dparam,sw,time,price)) { long array[]; engine.GraphGetArrayChartsID(array); for(int i=0;i<ArraySize(array);i++) engine.CreateLineVertical(array[i],"LineVertical",0,time); } } engine.GetGraphicObjCollection().OnChartEvent(id,lparam,dparam,sparam); //--- Handle standard graphical object events ushort idx=ushort(id-CHARTEVENT_CUSTOM); CGStdGraphObj *obj=NULL; if(idx>GRAPH_OBJ_EVENT_NO_EVENT && idx<GRAPH_OBJ_EVENTS_NEXT_CODE) { CChartObjectsControl *chart_ctrl=NULL; int end=0; string evn=""; //--- Depending on the event type, display an appropriate message in the journal switch(idx) { //--- Graphical object creation event case GRAPH_OBJ_EVENT_CREATE : //--- Display the message about creating a new graphical object Print(DFUN,CMessage::Text(MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_CREATE),":"); //--- Get the pointer to the object by chart name and ID passed to sparam and lparam, respectively //--- display the short description of a newly created object to the journal and set the flag of storing the change history obj=engine.GraphGetStdGraphObject(sparam,lparam); if(obj!=NULL) { obj.PrintShort(); obj.SetAllowChangeMemory(true); obj.SetGroup(1); } break; //--- Event of changing the graphical object property case GRAPH_OBJ_EVENT_CHANGE : //--- Display the message about changing the graphical object property Print(DFUN,CMessage::Text(MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_CHANGE),":"); //--- Get the pointer to the object by chart name and ID passed to sparam and lparam, respectively obj=engine.GetGraphicObjCollection().GetStdGraphObject(sparam,lparam); if(obj!=NULL) { //--- Display a short description of the changed object in the journal obj.PrintShort(); //--- calculate the code of the changed property passed to dparam and get the property description if(dparam<GRAPH_OBJ_PROP_INTEGER_TOTAL) evn=obj.GetPropertyDescription((ENUM_GRAPH_OBJ_PROP_INTEGER)dparam); else if(dparam<GRAPH_OBJ_PROP_INTEGER_TOTAL+GRAPH_OBJ_PROP_DOUBLE_TOTAL) evn=obj.GetPropertyDescription((ENUM_GRAPH_OBJ_PROP_DOUBLE)dparam); else evn=obj.GetPropertyDescription((ENUM_GRAPH_OBJ_PROP_STRING)dparam); //--- Display the description of the graphical object's changed property in the journal Print(DFUN,evn); } break; //--- Graphical object renaming event case GRAPH_OBJ_EVENT_RENAME : //--- Display the message about renaming the graphical object Print(DFUN,CMessage::Text(MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_RENAME)); //--- Get the pointer to the object by chart name and ID passed to sparam and lparam, respectively obj=engine.GetGraphicObjCollection().GetStdGraphObject(sparam,lparam); if(obj!=NULL) { //--- Display the previous and new object name, as well as its entire renaming history, in the journal Print(DFUN,obj.GetProperty(GRAPH_OBJ_PROP_NAME,obj.Properties().CurrSize(GRAPH_OBJ_PROP_NAME)-1)," >>> ",obj.GetProperty(GRAPH_OBJ_PROP_NAME,0)); obj.PrintRenameHistory(); } break; //--- Graphical object deletion event case GRAPH_OBJ_EVENT_DELETE : //--- Display the message about removing the graphical object Print(DFUN,CMessage::Text(MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_DELETE),":"); //--- Get the pointer to the removed object by chart name and ID passed to sparam and lparam, respectively //--- and display a short description of the removed object in the journal obj=engine.GetGraphicObjCollection().GetStdDelGraphObject(sparam,lparam); if(obj!=NULL) { obj.PrintShort(); } break; //--- Event of removing the graphical object together with the chart window case GRAPH_OBJ_EVENT_DEL_CHART: //--- Display the message about removing graphical objects together with the chart window, whose ID and symbol are passed to lparam and sparam Print(DFUN,CMessage::Text(MSG_GRAPH_OBJ_EVN_GRAPH_OBJ_DEL_CHART),": #",lparam,", ",sparam,":"); //--- Calculate the end value for the loop by the list of removed graphical objects end=engine.TotalDeletedGraphObjects()-(int)dparam; if(end<0) end=0; //--- In the loop from the end of the removed graphical objects list up to the value calculated in the 'end' variable, for(int i=engine.TotalDeletedGraphObjects()-1;i>=end;i--) { //--- get the next removed graphical object from the list obj=engine.GetListDeletedObj().At(i); if(obj==NULL) continue; //--- and display its brief description in the journal obj.PrintShort(); } break; //--- default: break; } } } //+------------------------------------------------------------------+
キーストロークを処理するロジック全体は、コードへのコメントで説明されています。
EAをコンパイルし、チャート上で起動します。グラフィカルオブジェクトを追加し、それらのプロパティを変更して、「/」を押すと、オブジェクトは、最初の変更前の値を取ります。「.」と「,」を押すと、オブジェクトは、プロパティ変更履歴リストに対応するプロパティと外観を取ります。
次の段階
次の記事では、複合グラフィカルオブジェクトの開発を開始します。
*連載のこれまでの記事:
DoEasyライブラリのグラフィックス(第89部): 抽象標準グラフィカルオブジェクトのプログラミング基本機能
DoEasyライブラリのグラフィックス(第90部): 標準グラフィカルオブジェクトのイベント基本機能
DoEasyライブラリのグラフィックス(第91部): 標準グラフィカルオブジェクトのイベントオブジェクト名変更履歴
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/10237




- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索