English Русский 中文 Español Deutsch Português
DoEasyライブラリのグラフィックス(第82部): ライブラリオブジェクトのリファクタリングとグラフィカルオブジェクトのコレクション

DoEasyライブラリのグラフィックス(第82部): ライブラリオブジェクトのリファクタリングとグラフィカルオブジェクトのコレクション

MetaTrader 5 | 18 10月 2021, 09:26
399 0
Artyom Trishkin
Artyom Trishkin

内容


概念

前回の記事で、ライブラリオブジェクトへのグラフィックの処理の統合を開始しました。各ライブラリオブジェクトには、グラフィカルオブジェクトを処理するためのオブジェクトの独自のインスタンスがあり、適切なグラフィカルオブジェクト(標準およびCCanvasベースのオブジェクトの両方)を構築できます。

グラフィックをライブラリオブジェクトに統合するために、前回の記事ではバーオブジェクトの改良を開始しました。とりわけ、グラフィック管理クラスを実装しました。デバッグした後で、新しく作成されたデバッグ済みチャート処理メカニズムを他のオブジェクトに追加するつもりです。

次に、すべてのライブラリオブジェクトを改善します。各オブジェクトには、そのオブジェクトを定義できるようにする一意のID(Type())が必要です。各ライブラリオブジェクトでグラフィカルオブジェクトを作成できる必要がありますが、グラフィカルオブジェクトは誰に作成されたかを「知っている」必要があります。ライブラリオブジェクトを使用して作成されたグラフィカルオブジェクトは、作成した親を認識し、その親へのポインタを持っている必要があります。一方、親は、作成したグラフィカルオブジェクトを認識し、それらへのポインタを持っている必要があります。

同時に、グラフィカルオブジェクトを作成したら、グラフィカルオブジェクトの単一のコレクションリストに追加する必要があります。すべてのグラフィカルオブジェクトには、新しいプロパティ(オブジェクトの所属)が必要です。これにより、プログラムによって、またはターミナルで手動で、グラフィカルオブジェクトがどのように作成されるかを決定できます。ライブラリを使用してプログラムから作成されたオブジェクトは、作成直後にリストに追加されます。ターミナルによって作成されたグラフィック(チャートに手動で追加されたさまざまなグラフィカルオブジェクト)は、グラフィカルオブジェクトのコレクションクラスによって追跡され、リストに追加/リストから削除される必要があります。プログラムがそれらを管理できるように、グラフィカルオブジェクトクラスの個別のプログラムオブジェクトを作成する必要があります。
これを行うには、グラフィカルオブジェクトのコレクションクラスでターミナルで開いているすべてのグラフウィンドウのステータスの追跡を実装する必要があります。つまり、標準のグラフィカルオブジェクトの発生、ライブラリオブジェクトの作成、コレクションリストへの追加です。標準のグラフィカルオブジェクトの削除についても同じことが言えます。

したがって、ライブラリは最終的に、開いているチャートに存在するすべての標準グラフィカルオブジェクトを制御し、手動で作成されていることを考慮しながら、それらを独自のオブジェクトであるかのように処理できるようになります。

これは、今後のいくつかの記事の基礎です。
ここでは、タイプを割り当てることですべてのライブラリオブジェクトを改善し、グラフィカルオブジェクトコレクションクラスで作業します。つまり、ターミナルで開いているチャートで新しいグラフィカルオブジェクトの追跡/既存のグラフィカルオブジェクトの削除を調整します。


ライブラリクラスの改善

\MQL5\Include\DoEasy\Defines.mqhに新しいマクロ置換と列挙を追加しましょう。すべてのライブラリオブジェクトのタイプを追加して、作成直後にオブジェクトの「type」プロパティに値を設定する必要があります。

ただし、最初に、グラフィカルオブジェクトコレクションタイマーのパラメータを指定するためのマクロ置換を追加して、既存のコレクションのタイマーパラメータのリストの最後に追加します。

//--- Parameters of the chart collection timer
#define COLLECTION_CHARTS_PAUSE        (500)                      // Chart collection timer pause in milliseconds
#define COLLECTION_CHARTS_COUNTER_STEP (16)                       // Chart timer counter increment
#define COLLECTION_CHARTS_COUNTER_ID   (9)                        // Chart timer counter ID
//--- Parameters of the graphical objects collection timer
#define COLLECTION_GRAPH_OBJ_PAUSE        (250)                   // Graphical objects collection timer pause in milliseconds
#define COLLECTION_GRAPH_OBJ_COUNTER_STEP (16)                    // Graphical objects timer counter increment
#define COLLECTION_GRAPH_OBJ_COUNTER_ID   (10)                    // Graphical objects timer counter ID

//--- Collection list IDs


このファイルには、すでにコレクションリストIDが含まれています。
オブジェクト型IDのリストを継続することは合理的です。新しいオブジェクトコレクションを引き続き追加し、それらのIDのリストを拡張するため、オブジェクト型値の開始点として使用するラベルを追加する必要があります

//--- Collection list IDs
#define COLLECTION_HISTORY_ID          (0x777A)                   // Historical collection list ID
#define COLLECTION_MARKET_ID           (0x777B)                   // Market collection list ID
#define COLLECTION_EVENTS_ID           (0x777C)                   // Event collection list ID
#define COLLECTION_ACCOUNT_ID          (0x777D)                   // Account collection list ID
#define COLLECTION_SYMBOLS_ID          (0x777E)                   // Symbol collection list ID
#define COLLECTION_SERIES_ID           (0x777F)                   // Timeseries collection list ID
#define COLLECTION_BUFFERS_ID          (0x7780)                   // Indicator buffer collection list ID
#define COLLECTION_INDICATORS_ID       (0x7781)                   // Indicator collection list ID
#define COLLECTION_INDICATORS_DATA_ID  (0x7782)                   // Indicator data collection list ID
#define COLLECTION_TICKSERIES_ID       (0x7783)                   // Tick series collection list ID
#define COLLECTION_MBOOKSERIES_ID      (0x7784)                   // DOM series collection list ID
#define COLLECTION_MQL5_SIGNALS_ID     (0x7785)                   // MQL5 signals collection list ID
#define COLLECTION_CHARTS_ID           (0x7786)                   // Chart collection list ID
#define COLLECTION_CHART_WND_ID        (0x7787)                   // Chart window list ID
#define COLLECTION_GRAPH_OBJ_ID        (0x7788)                   // Graphical object collection list ID

#define COLLECTION_ID_LIST_END         (COLLECTION_GRAPH_OBJ_ID)  // End of collection ID list

//--- Pending request type IDs

ラベル値+1は、ここで追加するライブラリオブジェクト型列挙型最初の定数の値になります。

//--- Canvas parameters
#define PAUSE_FOR_CANV_UPDATE          (16)                       // Canvas update frequency
#define NULL_COLOR                     (0x00FFFFFF)               // Zero for the canvas with the alpha channel
#define OUTER_AREA_SIZE                (16)                       // Size of one side of the outer area around the workspace
//+------------------------------------------------------------------+
//| Enumerations                                                     |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| List of library object types                                     |
//+------------------------------------------------------------------+
enum ENUM_OBJECT_DE_TYPE
  {
//--- Graphics
   OBJECT_DE_TYPE_GBASE =  COLLECTION_ID_LIST_END+1,              // "Base object of all library graphical objects" object type
   OBJECT_DE_TYPE_GELEMENT,                                       // "Graphical element" object type
   OBJECT_DE_TYPE_GFORM,                                          // Form object type
   OBJECT_DE_TYPE_GSHADOW,                                        // Shadow object type
//--- Animation
   OBJECT_DE_TYPE_GFRAME,                                         // "Single animation frame" object type
   OBJECT_DE_TYPE_GFRAME_TEXT,                                    // "Single text animation frame" object type
   OBJECT_DE_TYPE_GFRAME_QUAD,                                    // "Single rectangular animation frame" object type
   OBJECT_DE_TYPE_GFRAME_GEOMETRY,                                // "Single geometric animation frame" object type
   OBJECT_DE_TYPE_GANIMATIONS,                                    // "Animations" object type
//--- Managing graphical objects
   OBJECT_DE_TYPE_GELEMENT_CONTROL,                               // "Managing graphical objects" object type
//--- Standard graphical objects
   OBJECT_DE_TYPE_GSTD_VLINE              =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_VLINE,             // "Vertical line" object type
   OBJECT_DE_TYPE_GSTD_HLINE              =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_HLINE,             // "Horizontal line" object type
   OBJECT_DE_TYPE_GSTD_TREND              =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TREND,             // "Trend line" object type
   OBJECT_DE_TYPE_GSTD_TRENDBYANGLE       =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TRENDBYANGLE,      // "Trend line by angle" object type
   OBJECT_DE_TYPE_GSTD_CYCLES             =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_CYCLES,            // "Cyclic lines" object type
   OBJECT_DE_TYPE_GSTD_ARROWED_LINE       =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROWED_LINE,      // "Arrowed line" object type
   OBJECT_DE_TYPE_GSTD_CHANNEL            =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_CHANNEL,           // "Equidistant channel" object type
   OBJECT_DE_TYPE_GSTD_STDDEVCHANNEL      =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_STDDEVCHANNEL,     // "Standard deviation channel" object type
   OBJECT_DE_TYPE_GSTD_REGRESSION         =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_REGRESSION,        // "Linear regression channel" object type
   OBJECT_DE_TYPE_GSTD_PITCHFORK          =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_PITCHFORK,         // "Andrews' pitchfork" object type
   OBJECT_DE_TYPE_GSTD_GANNLINE           =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_GANNLINE,          // "Gann line" object type
   OBJECT_DE_TYPE_GSTD_GANNFAN            =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_GANNFAN,           // "Gann fan" object type
   OBJECT_DE_TYPE_GSTD_GANNGRID           =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_GANNGRID,          // "Gann grid" object type
   OBJECT_DE_TYPE_GSTD_FIBO               =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBO,              // "Fibo levels" object type
   OBJECT_DE_TYPE_GSTD_FIBOTIMES          =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOTIMES,         // "Fibo time zones" object type
   OBJECT_DE_TYPE_GSTD_FIBOFAN            =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOFAN,           // "Fibo fan" object type
   OBJECT_DE_TYPE_GSTD_FIBOARC            =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOARC,           // "Fibo arcs" object type
   OBJECT_DE_TYPE_GSTD_FIBOCHANNEL        =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOCHANNEL,       // "Fibo channel" object type
   OBJECT_DE_TYPE_GSTD_EXPANSION          =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_EXPANSION,         // "Fibo expansion" object type
   OBJECT_DE_TYPE_GSTD_ELLIOTWAVE5        =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ELLIOTWAVE5,       // "Elliott 5 waves" object type
   OBJECT_DE_TYPE_GSTD_ELLIOTWAVE3        =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ELLIOTWAVE3,       // "Elliott 3 waves" object type
   OBJECT_DE_TYPE_GSTD_RECTANGLE          =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_RECTANGLE,         // "Rectangle" object type
   OBJECT_DE_TYPE_GSTD_TRIANGLE           =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TRIANGLE,          // "Triangle" object type
   OBJECT_DE_TYPE_GSTD_ELLIPSE            =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ELLIPSE,           // "Ellipse" object type
   OBJECT_DE_TYPE_GSTD_ARROW_THUMB_UP     =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_THUMB_UP,    // "Thumb up" object type
   OBJECT_DE_TYPE_GSTD_ARROW_THUMB_DOWN   =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_THUMB_DOWN,  // "Thumb down" object type
   OBJECT_DE_TYPE_GSTD_ARROW_UP           =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_UP,          // "Arrow up" object type
   OBJECT_DE_TYPE_GSTD_ARROW_DOWN         =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_DOWN,        // "Arrow down" object type
   OBJECT_DE_TYPE_GSTD_ARROW_STOP         =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_STOP,        // "Stop sign" object type
   OBJECT_DE_TYPE_GSTD_ARROW_CHECK        =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_CHECK,       // "Check mark" object type
   OBJECT_DE_TYPE_GSTD_ARROW_LEFT_PRICE   =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_LEFT_PRICE,  // "Left price label" object type
   OBJECT_DE_TYPE_GSTD_ARROW_RIGHT_PRICE  =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_RIGHT_PRICE, // "Right price label" object type
   OBJECT_DE_TYPE_GSTD_ARROW_BUY          =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_BUY,         // "Buy sign" object type
   OBJECT_DE_TYPE_GSTD_ARROW_SELL         =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_SELL,        // "Sell sign" object type
   OBJECT_DE_TYPE_GSTD_ARROW              =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW,             // "Arrow" object type
   OBJECT_DE_TYPE_GSTD_TEXT               =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TEXT,              // "Text" object type
   OBJECT_DE_TYPE_GSTD_LABEL              =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_LABEL,             // "Text label" object type
   OBJECT_DE_TYPE_GSTD_BUTTON             =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_BUTTON,            // "Button" object type
   OBJECT_DE_TYPE_GSTD_CHART              =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_CHART,             // "Chart" object type
   OBJECT_DE_TYPE_GSTD_BITMAP             =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_BITMAP,            // "Bitmap" object type
   OBJECT_DE_TYPE_GSTD_BITMAP_LABEL       =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_BITMAP_LABEL,      // "Bitmap label" object type
   OBJECT_DE_TYPE_GSTD_EDIT               =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_EDIT,              // "Input field" object type
   OBJECT_DE_TYPE_GSTD_EVENT              =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_EVENT,             // "Event object which corresponds to an event in Economic Calendar" object type
   OBJECT_DE_TYPE_GSTD_RECTANGLE_LABEL    =  OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_RECTANGLE_LABEL,   // "Rectangle Label object used to create and design the custom graphical interface" object type
   
//--- Objects
   OBJECT_DE_TYPE_BASE  =  OBJECT_DE_TYPE_GSTD_RECTANGLE_LABEL+1, // Base object for all library objects
   OBJECT_DE_TYPE_BASE_EXT,                                       // Extended base object for all library objects
   
   OBJECT_DE_TYPE_ACCOUNT,                                        // "Account" object type
   OBJECT_DE_TYPE_BOOK_ORDER,                                     // "Book order" object type
   OBJECT_DE_TYPE_BOOK_BUY,                                       // "Book buy order" object type
   OBJECT_DE_TYPE_BOOK_BUY_MARKET,                                // "Book buy order at market price" object type
   OBJECT_DE_TYPE_BOOK_SELL,                                      // "Book sell order" object type
   OBJECT_DE_TYPE_BOOK_SELL_MARKET,                               // "Book sell order at market price" object type
   OBJECT_DE_TYPE_BOOK_SNAPSHOT,                                  // "Book snapshot" object type
   OBJECT_DE_TYPE_BOOK_SERIES,                                    // "Book snapshot series" object type
   
   OBJECT_DE_TYPE_CHART,                                          // "Chart" object type
   OBJECT_DE_TYPE_CHART_WND,                                      // "Chart window" object type
   OBJECT_DE_TYPE_CHART_WND_IND,                                  // "Chart window indicator" object type
   
   OBJECT_DE_TYPE_EVENT,                                          // "Event" object type
   OBJECT_DE_TYPE_EVENT_BALANCE,                                  // "Balance operation event" object type
   OBJECT_DE_TYPE_EVENT_MODIFY,                                   // "Pending order/position modification event" object type
   OBJECT_DE_TYPE_EVENT_ORDER_PLASED,                             // "Placing a pending order event" object type
   OBJECT_DE_TYPE_EVENT_ORDER_REMOVED,                            // "Pending order removal event" object type
   OBJECT_DE_TYPE_EVENT_POSITION_CLOSE,                           // "Position closure event" object type
   OBJECT_DE_TYPE_EVENT_POSITION_OPEN,                            // "Position opening event" object type
   
   OBJECT_DE_TYPE_IND_BUFFER,                                     // "Indicator buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_ARROW,                               // "Arrow rendering buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_BAR,                                 // "Bar buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_CALCULATE,                           // "Calculated buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_CANDLE,                              // "Candle buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_FILLING,                             // "Filling buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_HISTOGRAMM,                          // "Histogram buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_HISTOGRAMM2,                         // "Histogram 2 buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_LINE,                                // "Line buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_SECTION,                             // "Section buffer" object type
   OBJECT_DE_TYPE_IND_BUFFER_ZIGZAG,                              // "Zigzag buffer" object type
   OBJECT_DE_TYPE_INDICATOR,                                      // "Indicator" object type
   OBJECT_DE_TYPE_IND_DATA,                                       // "Indicator data" object type
   OBJECT_DE_TYPE_IND_DATA_LIST,                                  // "Indicator data list" object type
   
   OBJECT_DE_TYPE_IND_AC,                                         // "Accelerator Oscillator indicator" object type
   OBJECT_DE_TYPE_IND_AD,                                         // "Accumulation/Distribution indicator" object type
   OBJECT_DE_TYPE_IND_ADX,                                        // "Average Directional Index indicator" object type
   OBJECT_DE_TYPE_IND_ADXW,                                       // "ADX indicator by Welles Wilder" object type
   OBJECT_DE_TYPE_IND_ALLIGATOR,                                  // "Alligator indicator" object type
   OBJECT_DE_TYPE_IND_AMA,                                        // "Adaptive Moving Average indicator" object type
   OBJECT_DE_TYPE_IND_AO,                                         // "Awesome Oscillator indicator" object type
   OBJECT_DE_TYPE_IND_ATR,                                        // "Average True Range" object type
   OBJECT_DE_TYPE_IND_BANDS,                                      // "Bollinger Bands® indicator" object type
   OBJECT_DE_TYPE_IND_BEARS,                                      // "Bears Power indicator" object type
   OBJECT_DE_TYPE_IND_BULLS,                                      // "Bulls Power indicator" object type
   OBJECT_DE_TYPE_IND_BWMFI,                                      // "Market Facilitation Index indicator" object type
   OBJECT_DE_TYPE_IND_CCI,                                        // "Commodity Channel Index indicator" object type
   OBJECT_DE_TYPE_IND_CHAIKIN,                                    // "Chaikin Oscillator indicator" object type
   OBJECT_DE_TYPE_IND_CUSTOM,                                     // "Custom indicator" object type
   OBJECT_DE_TYPE_IND_DEMA,                                       // "Double Exponential Moving Average indicator" object type
   OBJECT_DE_TYPE_IND_DEMARKER,                                   // "DeMarker indicator" object type
   OBJECT_DE_TYPE_IND_ENVELOPES,                                  // "Envelopes indicator" object type
   OBJECT_DE_TYPE_IND_FORCE,                                      // "Force Index indicator" object type
   OBJECT_DE_TYPE_IND_FRACTALS,                                   // "Fractals indicator" object type
   OBJECT_DE_TYPE_IND_FRAMA,                                      // "Fractal Adaptive Moving Average indicator" object type
   OBJECT_DE_TYPE_IND_GATOR,                                      // "Gator Oscillator indicator" object type
   OBJECT_DE_TYPE_IND_ICHIMOKU,                                   // "Ichimoku Kinko Hyo indicator" object type
   OBJECT_DE_TYPE_IND_MA,                                         // "Moving Average indicator" object type
   OBJECT_DE_TYPE_IND_MACD,                                       // "Moving Average Convergence/Divergence indicator" object type
   OBJECT_DE_TYPE_IND_MFI,                                        // "Money Flow Index indicator" object type
   OBJECT_DE_TYPE_IND_MOMENTUM,                                   // "Momentum indicator" object type
   OBJECT_DE_TYPE_IND_OBV,                                        // "On Balance Volume indicator" object type
   OBJECT_DE_TYPE_IND_OSMA,                                       // "Moving Average of Oscillator indicator" object type
   OBJECT_DE_TYPE_IND_RSI,                                        // "Relative Strength Index indicator" object type
   OBJECT_DE_TYPE_IND_RVI,                                        // "Relative Vigor Index indicator" object type
   OBJECT_DE_TYPE_IND_SAR,                                        // "Parabolic SAR indicator" object type
   OBJECT_DE_TYPE_IND_STDEV,                                      // "Standard Deviation indicator" object type
   OBJECT_DE_TYPE_IND_STOCH,                                      // "Stochastic Oscillator indicator" object type
   OBJECT_DE_TYPE_IND_TEMA,                                       // "Triple Exponential Moving Average indicator" object
   OBJECT_DE_TYPE_IND_TRIX,                                       // "Triple Exponential Moving Averages Oscillator indicator" object type
   OBJECT_DE_TYPE_IND_VIDYA,                                      // "Variable Index Dynamic Average indicator" object type
   OBJECT_DE_TYPE_IND_VOLUMES,                                    // "Volumes indicator" object type
   OBJECT_DE_TYPE_IND_WPR,                                        // "Williams' Percent Range indicator" object type
   
   OBJECT_DE_TYPE_MQL5_SIGNAL,                                    // "mql5 signal" object type
   
   OBJECT_DE_TYPE_ORDER_DEAL_POSITION,                            // "Order/Deal/Position" object type
   OBJECT_DE_TYPE_HISTORY_BALANCE,                                // "Historical balance operation" object type
   OBJECT_DE_TYPE_HISTORY_DEAL,                                   // "Historical deal" object type
   OBJECT_DE_TYPE_HISTORY_ORDER_MARKET,                           // "Historical market order" object type
   OBJECT_DE_TYPE_HISTORY_ORDER_PENDING,                          // "Historical removed pending order" object type
   OBJECT_DE_TYPE_MARKET_ORDER,                                   // "Market order" object type
   OBJECT_DE_TYPE_MARKET_PENDING,                                 // "Pending order" object type
   OBJECT_DE_TYPE_MARKET_POSITION,                                // "Market position" object type
   
   OBJECT_DE_TYPE_PENDING_REQUEST,                                // "Pending trading request" object type
   OBJECT_DE_TYPE_PENDING_REQUEST_POSITION_OPEN,                  // "Pending request to open a position" object type
   OBJECT_DE_TYPE_PENDING_REQUEST_POSITION_CLOSE,                 // "Pending request to close a position" object type
   OBJECT_DE_TYPE_PENDING_REQUEST_POSITION_SLTP,                  // "Pending request to modify position stop orders" object type
   OBJECT_DE_TYPE_PENDING_REQUEST_ORDER_PLACE,                    // "Pending request to place a pending order" object type
   OBJECT_DE_TYPE_PENDING_REQUEST_ORDER_REMOVE,                   // "Pending request to delete a pending order" object type
   OBJECT_DE_TYPE_PENDING_REQUEST_ORDER_MODIFY,                   // "Pending request to modify pending order parameters" object type
   
   OBJECT_DE_TYPE_SERIES_BAR,                                     // "Bar" object type
   OBJECT_DE_TYPE_SERIES_PERIOD,                                  // "Period timeseries" object type
   OBJECT_DE_TYPE_SERIES_SYMBOL,                                  // "Symbol timeseries" object type
   
   OBJECT_DE_TYPE_SYMBOL,                                         // "Symbol" object type
   OBJECT_DE_TYPE_SYMBOL_BONDS,                                   // "Bond symbol" object type
   OBJECT_DE_TYPE_SYMBOL_CFD,                                     // "CFD (contract for difference) symbol" object type
   OBJECT_DE_TYPE_SYMBOL_COLLATERAL,                              // "Non-tradable asset symbol" object type" object type
   OBJECT_DE_TYPE_SYMBOL_COMMODITY,                               // "Commodity symbol" object type
   OBJECT_DE_TYPE_SYMBOL_COMMON,                                  // "Common group symbol" object type
   OBJECT_DE_TYPE_SYMBOL_CRYPTO,                                  // "Cryptocurrency symbol" object type
   OBJECT_DE_TYPE_SYMBOL_CUSTOM,                                  // "Custom symbol" object type
   OBJECT_DE_TYPE_SYMBOL_EXCHANGE,                                // "Exchange symbol" object type
   OBJECT_DE_TYPE_SYMBOL_FUTURES,                                 // "Futures symbol" object type
   OBJECT_DE_TYPE_SYMBOL_FX,                                      // "Forex symbol" object type
   OBJECT_DE_TYPE_SYMBOL_FX_EXOTIC,                               // "Exotic Forex symbol" object type
   OBJECT_DE_TYPE_SYMBOL_FX_MAJOR,                                // "Major Forex symbol" object type
   OBJECT_DE_TYPE_SYMBOL_FX_MINOR,                                // "Minor Forex symbol" object type
   OBJECT_DE_TYPE_SYMBOL_FX_RUB,                                  // "RUB Forex symbol" object type
   OBJECT_DE_TYPE_SYMBOL_INDEX,                                   // "Index symbol" object type
   OBJECT_DE_TYPE_SYMBOL_INDICATIVE,                              // "Indicative symbol" object type
   OBJECT_DE_TYPE_SYMBOL_METALL,                                  // "Metal symbol" object type
   OBJECT_DE_TYPE_SYMBOL_OPTION,                                  // "Option symbol" object type
   OBJECT_DE_TYPE_SYMBOL_STOCKS,                                  // "Stock symbol" object type
   
   OBJECT_DE_TYPE_TICK,                                           // "Tick" object type
   OBJECT_DE_TYPE_NEW_TICK,                                       // "New tick" object type
   OBJECT_DE_TYPE_TICKSERIES,                                     // "Tick data series" object type
   
   OBJECT_DE_TYPE_TRADE,                                          // "Trading object" object type
  };

//+------------------------------------------------------------------+
//| Search and sorting data                                          |
//+------------------------------------------------------------------+

列挙定数を注意深く調べると、標準のグラフィカルオブジェクトに対応するオブジェクトのタイプライブラリオブジェクト列挙の前の定数の値+1+対応するグラフィカルオブジェクトの標準列挙値を使用していることがわかります。 標準のグラフィカルオブジェクトのリストの列挙が完了した後、最後のグラフィカルオブジェクトの定数値+1から開始して、ライブラリオブジェクト型のリストの列挙を続行します

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

したがって、標準のグラフィカルオブジェクトに基づくグラフィカルライブラリオブジェクトには、標準のグラフィカルオブジェクト型に対応するタイプ値があります。このタイプは簡単に計算できますが、後続のタイプは引き続き最後の標準グラフィカルオブジェクトの定数を超える値を取得し、列挙定数の値間で衝突を引き起こしません。

次に、グラフィカルオブジェクトプロパティのリストを少し改善する必要があります。つまり、プログラムまたはターミナル(作成方法-プログラムまたは手動)を使用してオブジェクトの所属の列挙を追加し、このプロパティをグラフィカルオブジェクトの整数プロパティの列挙に追加する必要があります

//+------------------------------------------------------------------+
//| List of graphical objects affiliations                           |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_OBJ_BELONG
  {
   GRAPH_OBJ_BELONG_PROGRAM,                          // Graphical object belongs to a program
   GRAPH_OBJ_BELONG_TERMINAL,                         // Graphical object does not belong to a program
  };
//+------------------------------------------------------------------+
//| The list of graphical element types                              |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_ELEMENT_TYPE
  {
   GRAPH_ELEMENT_TYPE_ELEMENT,                        // Element
   GRAPH_ELEMENT_TYPE_SHADOW_OBJ,                     // Shadow object
   GRAPH_ELEMENT_TYPE_FORM,                           // Form
   GRAPH_ELEMENT_TYPE_WINDOW,                         // Window
  };
//+------------------------------------------------------------------+
//| Integer properties of the graphical element on the canvas        |
//+------------------------------------------------------------------+
enum ENUM_CANV_ELEMENT_PROP_INTEGER
  {
   CANV_ELEMENT_PROP_ID = 0,                          // Element ID
   CANV_ELEMENT_PROP_TYPE,                            // Graphical element type
   CANV_ELEMENT_PROP_BELONG,                          // Graphical element affiliation
   CANV_ELEMENT_PROP_NUM,                             // Element index in the list
   CANV_ELEMENT_PROP_CHART_ID,                        // Chart ID
   CANV_ELEMENT_PROP_WND_NUM,                         // Chart subwindow index
   CANV_ELEMENT_PROP_COORD_X,                         // Form's X coordinate on the chart
   CANV_ELEMENT_PROP_COORD_Y,                         // Form's Y coordinate on the chart
   CANV_ELEMENT_PROP_WIDTH,                           // Element width
   CANV_ELEMENT_PROP_HEIGHT,                          // Element height
   CANV_ELEMENT_PROP_RIGHT,                           // Element right border
   CANV_ELEMENT_PROP_BOTTOM,                          // Element bottom border
   CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,                  // Active area offset from the left edge of the element
   CANV_ELEMENT_PROP_ACT_SHIFT_TOP,                   // Active area offset from the upper edge of the element
   CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,                 // Active area offset from the right edge of the element
   CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,                // Active area offset from the bottom edge of the element
   CANV_ELEMENT_PROP_MOVABLE,                         // Element moveability flag
   CANV_ELEMENT_PROP_ACTIVE,                          // Element activity flag
   CANV_ELEMENT_PROP_COORD_ACT_X,                     // X coordinate of the element active area
   CANV_ELEMENT_PROP_COORD_ACT_Y,                     // Y coordinate of the element active area
   CANV_ELEMENT_PROP_ACT_RIGHT,                       // Right border of the element active area
   CANV_ELEMENT_PROP_ACT_BOTTOM,                      // Bottom border of the element active area
  };
#define CANV_ELEMENT_PROP_INTEGER_TOTAL (22)          // Total number of integer properties
#define CANV_ELEMENT_PROP_INTEGER_SKIP  (0)           // Number of integer properties not used in sorting
//+------------------------------------------------------------------+

新しいプロパティが追加されたため、これらのプロパティの総数を増やす必要があります(21から22)。さらに、プロパティによる並べ替えを可能なグラフィカルオブジェクトの並べ替え基準の列挙に追加する必要があります。

//+------------------------------------------------------------------+
//| Possible sorting criteria of graphical elements on the canvas    |
//+------------------------------------------------------------------+
#define FIRST_CANV_ELEMENT_DBL_PROP  (CANV_ELEMENT_PROP_INTEGER_TOTAL-CANV_ELEMENT_PROP_INTEGER_SKIP)
#define FIRST_CANV_ELEMENT_STR_PROP  (CANV_ELEMENT_PROP_INTEGER_TOTAL-CANV_ELEMENT_PROP_INTEGER_SKIP+CANV_ELEMENT_PROP_DOUBLE_TOTAL-CANV_ELEMENT_PROP_DOUBLE_SKIP)
enum ENUM_SORT_CANV_ELEMENT_MODE
  {
//--- Sort by integer properties
   SORT_BY_CANV_ELEMENT_ID = 0,                       // Sort by element ID
   SORT_BY_CANV_ELEMENT_TYPE,                         // Sort by graphical element type
   SORT_BY_CANV_ELEMENT_BELONG,                       // Sort by a graphical element affiliation
   SORT_BY_CANV_ELEMENT_NUM,                          // Sort by form index in the list
   SORT_BY_CANV_ELEMENT_CHART_ID,                     // Sort by chart ID
   SORT_BY_CANV_ELEMENT_WND_NUM,                      // Sort by chart window index
   SORT_BY_CANV_ELEMENT_COORD_X,                      // Sort by the element X coordinate on the chart
   SORT_BY_CANV_ELEMENT_COORD_Y,                      // Sort by the element Y coordinate on the chart
   SORT_BY_CANV_ELEMENT_WIDTH,                        // Sort by the element width
   SORT_BY_CANV_ELEMENT_HEIGHT,                       // Sort by the element height
   SORT_BY_CANV_ELEMENT_RIGHT,                        // Sort by the element right border
   SORT_BY_CANV_ELEMENT_BOTTOM,                       // Sort by the element bottom border
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_LEFT,               // Sort by the active area offset from the left edge of the element
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_TOP,                // Sort by the active area offset from the top edge of the element
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_RIGHT,              // Sort by the active area offset from the right edge of the element
   SORT_BY_CANV_ELEMENT_ACT_SHIFT_BOTTOM,             // Sort by the active area offset from the bottom edge of the element
   SORT_BY_CANV_ELEMENT_MOVABLE,                      // Sort by the element moveability flag
   SORT_BY_CANV_ELEMENT_ACTIVE,                       // Sort by the element activity flag
   SORT_BY_CANV_ELEMENT_COORD_ACT_X,                  // Sort by X coordinate of the element active area
   SORT_BY_CANV_ELEMENT_COORD_ACT_Y,                  // Sort by Y coordinate of the element active area
   SORT_BY_CANV_ELEMENT_ACT_RIGHT,                    // Sort by the right border of the element active area
   SORT_BY_CANV_ELEMENT_ACT_BOTTOM,                   // Sort by the bottom border of the element active area
//--- Sort by real properties

//--- Sort by string properties
   SORT_BY_CANV_ELEMENT_NAME_OBJ = FIRST_CANV_ELEMENT_STR_PROP,// Sort by an element object name
   SORT_BY_CANV_ELEMENT_NAME_RES,                     // Sort by the graphical resource name
  };
//+------------------------------------------------------------------+


\MQL5\Include\DoEasy\Data.mqhに、グラフィカルオブジェクトの新しいメッセージインデックスを追加します

//--- CShadowObj
   MSG_SHADOW_OBJ_IMG_SMALL_BLUR_LARGE,               // Error! Image size too small or blur too extensive

//--- CGraphElementsCollection
   MSG_CHART_OBJ_COLLECTION_ERR_OBJ_ALREADY_EXISTS,   // Error. A chart control object already exists with chart id 
   MSG_CHART_OBJ_COLLECTION_ERR_FAILED_CREATE_CTRL_OBJ,// Failed to create chart control object with chart id 
   
  };
//+------------------------------------------------------------------+

また、新しく追加したインデックスに対応するメッセージテキストも追加します

//--- CShadowObj
   {"Ошибка! Размер изображения очень маленький или очень большое размытие","Error! Image size is very small or very large blur"},
      
//--- CGraphElementsCollection
   {"Ошибка. Уже существует объект управления чартами с идентификатором чарта ","Error. A chart control object already exists with chart id "},
   {"Не удалось создать объект управления чартами с идентификатором чарта ","Failed to create chart control object with chart id "},

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


次に、作成時に各重要な(補助ではない)ライブラリオブジェクトのタイプを指定する必要があります。補助オブジェクトは、メインオブジェクトの操作に必要なオブジェクトです。これらはコレクションオブジェクトではないため、このようなオブジェクトにタイプを割り当てる必要はありません。代わりに、メインライブラリオブジェクトでの作業を整理し、計算を簡素化するためにのみ使用されます。

多くのライブラリオブジェクトは、すべてのライブラリオブジェクトの基本オブジェクトから派生しており、オブジェクト型値を格納するm_type変数と、変数に設定されたオブジェクト型を返すType()仮想メソッドをすでに備えています。したがって、その子孫のコンストラクタでオブジェクト型に対応するm_type変数の値を指定するだけで十分です。

オブジェクトアフィリエーションの概念を導入しましたが、アフィリエーションは、グラフィカルオブジェクト名にプログラム名が含まれていることによって定義されます。これを実現するには、\MQL5\Include\DoEasy\Objects\BaseObj.mqh内のすべてのライブラリオブジェクトの基本オブジェクトがクラスのprotectedセクションにプログラム名を格納するための新しい変数を用意する必要があります

//+------------------------------------------------------------------+
//| Base object class for all library objects                        |
//+------------------------------------------------------------------+
class CBaseObj : public CObject
  {
protected:
   CGraphElmControl  m_graph_elm;                              // Instance of the class for managing graphical elements
   ENUM_LOG_LEVEL    m_log_level;                              // Logging level
   ENUM_PROGRAM_TYPE m_program;                                // Program type
   bool              m_first_start;                            // First launch flag
   bool              m_use_sound;                              // Flag of playing the sound set for an object
   bool              m_available;                              // Flag of using a descendant object in the program
   int               m_global_error;                           // Global error code
   long              m_chart_id_main;                          // Control program chart ID
   long              m_chart_id;                               // Chart ID
   string            m_name_program;                           // Program name
   string            m_name;                                   // Object name
   string            m_folder_name;                            // Name of the folder storing CBaseObj descendant objects 
   string            m_sound_name;                             // Object sound file name
   int               m_type;                                   // Object type (corresponds to the object type from the ENUM_OBJECT_DE_TYPE enumeration)

public:

クラスコンストラクタで、プログラム名を指定し、オブジェクト型を基本オブジェクトとして指定します

//--- Constructor
                     CBaseObj() : m_program((ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE)),
                                  m_name_program(::MQLInfoString(MQL_PROGRAM_NAME)),
                                  m_global_error(ERR_SUCCESS),
                                  m_log_level(LOG_LEVEL_ERROR_MSG),
                                  m_chart_id_main(::ChartID()),
                                  m_chart_id(::ChartID()),
                                  m_folder_name(DIRECTORY),
                                  m_sound_name(""),
                                  m_name(__FUNCTION__),
                                  m_type(OBJECT_DE_TYPE_BASE),
                                  m_use_sound(false),
                                  m_available(true),
                                  m_first_start(true) {}
  };
//+------------------------------------------------------------------+

基本オブジェクトクラスとは別に、ファイルにはすべてのライブラリオブジェクトの拡張基本オブジェクトクラスも含まれています。コンストラクタでオブジェクト型をbase-extended として指定します。

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CBaseObjExt::CBaseObjExt() : m_hash_sum(0),m_hash_sum_prev(0),
                             m_is_event(false),m_event_code(WRONG_VALUE),
                             m_long_prop_total(0),
                             m_double_prop_total(0)
  {
   this.m_type=OBJECT_DE_TYPE_BASE_EXT;
   ::ArrayResize(this.m_long_prop_event,0,100);
   ::ArrayResize(this.m_double_prop_event,0,100);
   ::ArrayResize(this.m_long_prop_event_prev,0,100);
   ::ArrayResize(this.m_double_prop_event_prev,0,100);
   ::ZeroMemory(this.m_tick);
   this.m_digits_currency=(#ifdef __MQL5__ (int)::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif);
   this.m_list_events.Clear();
   this.m_list_events.Sort();
   this.m_list_events_base.Clear();
   this.m_list_events_base.Sort();
  }
//+------------------------------------------------------------------+

これら2つのクラス(baseおよびbase-extended)の子孫であるすべてのライブラリオブジェクトの場合、コンストラクタのm_type変数でオブジェクト型を指定するだけで十分です。

\MQL5\Include\DoEasy\Objects\Accounts\Account.mqhのアカウントオブジェクトの場合、これは次のようになります(コンストラクタ全体)。

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CAccount::CAccount(void)
  {
   this.m_type=OBJECT_DE_TYPE_ACCOUNT;
//--- Initialize control data
   this.SetControlDataArraySizeLong(ACCOUNT_PROP_INTEGER_TOTAL);
   this.SetControlDataArraySizeDouble(ACCOUNT_PROP_DOUBLE_TOTAL);
   this.ResetChangesParams();
   this.ResetControlsParams();
  
//--- Save integer properties
   this.m_long_prop[ACCOUNT_PROP_LOGIN]                              = ::AccountInfoInteger(ACCOUNT_LOGIN);
   this.m_long_prop[ACCOUNT_PROP_TRADE_MODE]                         = ::AccountInfoInteger(ACCOUNT_TRADE_MODE);
   this.m_long_prop[ACCOUNT_PROP_LEVERAGE]                           = ::AccountInfoInteger(ACCOUNT_LEVERAGE);
   this.m_long_prop[ACCOUNT_PROP_LIMIT_ORDERS]                       = ::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS);
   this.m_long_prop[ACCOUNT_PROP_MARGIN_SO_MODE]                     = ::AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
   this.m_long_prop[ACCOUNT_PROP_TRADE_ALLOWED]                      = ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED);
   this.m_long_prop[ACCOUNT_PROP_TRADE_EXPERT]                       = ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT);
   this.m_long_prop[ACCOUNT_PROP_MARGIN_MODE]                        = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_MARGIN_MODE) #else ACCOUNT_MARGIN_MODE_RETAIL_HEDGING #endif ;
   this.m_long_prop[ACCOUNT_PROP_CURRENCY_DIGITS]                    = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif ;
   this.m_long_prop[ACCOUNT_PROP_SERVER_TYPE]                        = (::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4);
   this.m_long_prop[ACCOUNT_PROP_FIFO_CLOSE]                         = (#ifdef __MQL5__::TerminalInfoInteger(TERMINAL_BUILD)<2155 ? false : ::AccountInfoInteger(ACCOUNT_FIFO_CLOSE) #else false #endif );
   
//--- Save real properties
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_BALANCE)]          = ::AccountInfoDouble(ACCOUNT_BALANCE);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_CREDIT)]           = ::AccountInfoDouble(ACCOUNT_CREDIT);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_PROFIT)]           = ::AccountInfoDouble(ACCOUNT_PROFIT);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_EQUITY)]           = ::AccountInfoDouble(ACCOUNT_EQUITY);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN)]           = ::AccountInfoDouble(ACCOUNT_MARGIN);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_FREE)]      = ::AccountInfoDouble(ACCOUNT_MARGIN_FREE);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_LEVEL)]     = ::AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_CALL)]   = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_SO)]     = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_SO);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_INITIAL)]   = ::AccountInfoDouble(ACCOUNT_MARGIN_INITIAL);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_MAINTENANCE)]=::AccountInfoDouble(ACCOUNT_MARGIN_MAINTENANCE);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_ASSETS)]           = ::AccountInfoDouble(ACCOUNT_ASSETS);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_LIABILITIES)]      = ::AccountInfoDouble(ACCOUNT_LIABILITIES);
   this.m_double_prop[this.IndexProp(ACCOUNT_PROP_COMMISSION_BLOCKED)]=::AccountInfoDouble(ACCOUNT_COMMISSION_BLOCKED);
   
//--- Save string properties
   this.m_string_prop[this.IndexProp(ACCOUNT_PROP_NAME)]             = ::AccountInfoString(ACCOUNT_NAME);
   this.m_string_prop[this.IndexProp(ACCOUNT_PROP_SERVER)]           = ::AccountInfoString(ACCOUNT_SERVER);
   this.m_string_prop[this.IndexProp(ACCOUNT_PROP_CURRENCY)]         = ::AccountInfoString(ACCOUNT_CURRENCY);
   this.m_string_prop[this.IndexProp(ACCOUNT_PROP_COMPANY)]          = ::AccountInfoString(ACCOUNT_COMPANY);

//--- Account object name, object and account type (MetaTrader 5 or 4)
   this.m_name=CMessage::Text(MSG_LIB_PROP_ACCOUNT)+" "+(string)this.Login()+": "+this.Name()+" ("+this.Company()+")";
   this.m_type=COLLECTION_ACCOUNT_ID;
   this.m_type_server=(::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4);

//--- Filling in the current account data
   for(int i=0;i<ACCOUNT_PROP_INTEGER_TOTAL;i++)
      this.m_long_prop_event[i][3]=this.m_long_prop[i];
   for(int i=0;i<ACCOUNT_PROP_DOUBLE_TOTAL;i++)
      this.m_double_prop_event[i][3]=this.m_double_prop[i];

//--- Update the base object data and search for changes
   CBaseObjExt::Refresh();
  }
//+-------------------------------------------------------------------+

ご覧のとおり、m_type変数に必要なオブジェクト型のみを設定する必要があります。この場合、それは「アカウント」型です。基本オブジェクトクラスで宣言された新しいオブジェクト型値を書き込むと、オブジェクト型が「ベース」から「アカウント」に再定義されます。これで、仮想Type()メソッドは、m_type変数値を返し、基本オブジェクトにも実装され、アカウントオブジェクトクラスコンストラクタで再定義された変数値も返します。

\MQL5\Include\DoEasy\Objects\Book\MarketBookOrd.mqhの板情報抽象注文のクラスは、デフォルトとパラメトリックの2つのコンストラクタを備えています。両方のコンストラクタでオブジェクト型を設定します

以下は、デフォルトのコンストラクタです。

//--- Compare CMarketBookOrd objects by all properties (to search for equal request objects)
   bool              IsEqual(CMarketBookOrd* compared_req) const;
   
//--- Default constructor
                     CMarketBookOrd(){ this.m_type=OBJECT_DE_TYPE_BOOK_ORDER; }
protected:
//--- Protected parametric constructor
                     CMarketBookOrd(const ENUM_MBOOK_ORD_STATUS status,const MqlBookInfo &book_info,const string symbol);
                     
public:
//+-------------------------------------------------------------------+ 
//|Methods of a simplified access to the DOM request object properties|
//+-------------------------------------------------------------------+

以下はパラメトリックコンストラクタです。

//+------------------------------------------------------------------+
//| Protected parametric constructor                                 |
//+------------------------------------------------------------------+
CMarketBookOrd::CMarketBookOrd(const ENUM_MBOOK_ORD_STATUS status,const MqlBookInfo &book_info,const string symbol)
  {
   this.m_type=OBJECT_DE_TYPE_BOOK_ORDER;
//--- Save symbol’s Digits
   this.m_digits=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
//--- Save integer object properties
   this.SetProperty(MBOOK_ORD_PROP_STATUS,status);
   this.SetProperty(MBOOK_ORD_PROP_TYPE,book_info.type);
   this.SetProperty(MBOOK_ORD_PROP_VOLUME,book_info.volume);
//--- Save real object properties
   this.SetProperty(MBOOK_ORD_PROP_PRICE,book_info.price);
   this.SetProperty(MBOOK_ORD_PROP_VOLUME_REAL,book_info.volume_real);
//--- Save additional object properties
   this.SetProperty(MBOOK_ORD_PROP_SYMBOL,(symbol==NULL || symbol=="" ? ::Symbol() : symbol));
//--- Order time is not present in the parameters and is considered in the DOM snapshot class. Reset the time
   this.SetProperty(MBOOK_ORD_PROP_TIME_MSC,0);
  }
//+------------------------------------------------------------------+

板情報抽象注文の子孫で、適切なオブジェクト型を追加します。

以下は、\MQL5\Include\DoEasy\Objects\Book\MarketBookBuy.mqhの板情報買い注文です。

//+------------------------------------------------------------------+
//| Buy order in DOM                                                 |
//+------------------------------------------------------------------+
class CMarketBookBuy : public CMarketBookOrd
  {
private:

public:
   //--- Constructor
                     CMarketBookBuy(const string symbol,const MqlBookInfo &book_info) :
                        CMarketBookOrd(MBOOK_ORD_STATUS_BUY,book_info,symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_BUY; }
   //--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property);
   virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property);
//--- Return the object short name
   virtual string    Header(const bool symbol=false);
//--- Return the description of order type (ENUM_BOOK_TYPE)
   virtual string    TypeDescription(void);
  };
//+------------------------------------------------------------------+

\MQL5\Include\DoEasy\Objects\Book\MarketBookBuyMarket.mqhの市場価格での板情報買い注文

//+------------------------------------------------------------------+
//| Buy order by Market in DOM                                       |
//+------------------------------------------------------------------+
class CMarketBookBuyMarket : public CMarketBookOrd
  {
private:

public:
   //--- Constructor
                     CMarketBookBuyMarket(const string symbol,const MqlBookInfo &book_info) :
                        CMarketBookOrd(MBOOK_ORD_STATUS_BUY,book_info,symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_BUY_MARKET; }
   //--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property);
   virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property);
//--- Return the object short name
   virtual string    Header(const bool symbol=false);
//--- Return the description of order type (ENUM_BOOK_TYPE)
   virtual string    TypeDescription(void);
  };
//+------------------------------------------------------------------+

以下は、\MQL5\Include\DoEasy\Objects\Book\MarketBookSell.mqhの板情報売り注文です。

//+------------------------------------------------------------------+
//| Sell order in DOM                                                |
//+------------------------------------------------------------------+
class CMarketBookSell : public CMarketBookOrd
  {
private:

public:
   //--- Constructor
                     CMarketBookSell(const string symbol,const MqlBookInfo &book_info) :
                        CMarketBookOrd(MBOOK_ORD_STATUS_SELL,book_info,symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_SELL; }
   //--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property);
   virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property);
//--- Return the object short name
   virtual string    Header(const bool symbol=false);
//--- Return the description of order type (ENUM_BOOK_TYPE)
   virtual string    TypeDescription(void);
  };
//+------------------------------------------------------------------+

\MQL5\Include\DoEasy\Objects\Book\MarketBookSellMarket.mqhの市場価格での板情報売り注文

//+------------------------------------------------------------------+
//| Sell order by Market in DOM                                      |
//+------------------------------------------------------------------+
class CMarketBookSellMarket : public CMarketBookOrd
  {
private:

public:
   //--- Constructor
                     CMarketBookSellMarket(const string symbol,const MqlBookInfo &book_info) :
                        CMarketBookOrd(MBOOK_ORD_STATUS_SELL,book_info,symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_SELL_MARKET; }
   //--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property);
   virtual bool      SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property);
//--- Return the object short name
   virtual string    Header(const bool symbol=false);
//--- Return the description of order type (ENUM_BOOK_TYPE)
   virtual string    TypeDescription(void);
  };
//+------------------------------------------------------------------+

\MQL5\Include\DoEasy\Objects\Book\MarketBookSnapshot.mqhの「市場の深度スナップショット」クラスには2つのコンストラクタがあります(デフォルトとパラメトリック)。ここでは、両方のコンストラクタでオブジェクト型を指定する必要があります

以下は、デフォルトのコンストラクタです。

//--- Return the DOM snapshot change
   string            Header(void);
//--- Display (1) description and (2) short description of a DOM snapshot
   virtual void      Print(const bool full_prop=false,const bool dash=false);
   virtual void      PrintShort(const bool dash=false,const bool symbol=false);

//--- Constructors
                     CMBookSnapshot(){ this.m_type=OBJECT_DE_TYPE_BOOK_SNAPSHOT; }
                     CMBookSnapshot(const string symbol,const long time,MqlBookInfo &book_array[]);
//+---------------------------------------------------------------------+ 
//|Methods of a simplified access to the DOM snapshot object properties |
//+---------------------------------------------------------------------+

以下はパラメトリックコンストラクタです。

//+------------------------------------------------------------------+
//| Parametric constructor                                           |
//+------------------------------------------------------------------+
CMBookSnapshot::CMBookSnapshot(const string symbol,const long time,MqlBookInfo &book_array[]) : m_time(time)
  {
   this.m_type=OBJECT_DE_TYPE_BOOK_SNAPSHOT;
   //--- Set a symbol
   this.SetSymbol(symbol);
   //--- Clear the list
   this.m_list.Clear();
   //--- In the loop by the structure array
   int total=::ArraySize(book_array);
   this.m_volume_buy=this.m_volume_sell=0;
   this.m_volume_buy_real=this.m_volume_sell_real=0;
   for(int i=0;i<total;i++)
     {
      //--- Create order objects of the current DOM snapshot depending on the order type
      CMarketBookOrd *mbook_ord=NULL;
      switch(book_array[i].type)
        {
         case BOOK_TYPE_BUY         : mbook_ord=new CMarketBookBuy(this.m_symbol,book_array[i]);         break;
         case BOOK_TYPE_SELL        : mbook_ord=new CMarketBookSell(this.m_symbol,book_array[i]);        break;
         case BOOK_TYPE_BUY_MARKET  : mbook_ord=new CMarketBookBuyMarket(this.m_symbol,book_array[i]);   break;
         case BOOK_TYPE_SELL_MARKET : mbook_ord=new CMarketBookSellMarket(this.m_symbol,book_array[i]);  break;
         default: break;
        }
      if(mbook_ord==NULL)
         continue;
      //--- Set the DOM snapshot time for the order
      mbook_ord.SetTime(this.m_time);

      //--- Set the sorted list flag for the list (by the price value) and add the current order object to it
      //--- If failed to add the object to the DOM order list, remove the order object
      this.m_list.Sort(SORT_BY_MBOOK_ORD_PRICE);
      if(!this.m_list.InsertSort(mbook_ord))
         delete mbook_ord;
      //--- If the order object is successfully added to the DOM order list, supplement the total snapshot volumes
      else
        {
         switch(mbook_ord.TypeOrd())
           {
            case BOOK_TYPE_BUY         : 
              this.m_volume_buy+=mbook_ord.Volume(); 
              this.m_volume_buy_real+=mbook_ord.VolumeReal();
              break;
            case BOOK_TYPE_SELL        : 
              this.m_volume_sell+=mbook_ord.Volume(); 
              this.m_volume_sell_real+=mbook_ord.VolumeReal();
              break;
            case BOOK_TYPE_BUY_MARKET  : 
              this.m_volume_buy+=mbook_ord.Volume(); 
              this.m_volume_buy_real+=mbook_ord.VolumeReal();
              break;
            case BOOK_TYPE_SELL_MARKET : 
              this.m_volume_buy+=mbook_ord.Volume(); 
              this.m_volume_buy_real+=mbook_ord.VolumeReal();
              break;
            default: break;
           }
        }
     }
  }
//+------------------------------------------------------------------+

「板情報スナップショットシリーズ」クラスにも2つのコンストラクタがあります。両方にオブジェクト型を設定しましょう。

以下はデフォルトです。

//--- Display (1) description and (2) short description of a DOM snapshot series
   virtual void      Print(const bool full_prop=false,const bool dash=false);
   virtual void      PrintShort(const bool dash=false,const bool symbol=false);

//--- Constructors
                     CMBookSeries(){ this.m_type=OBJECT_DE_TYPE_BOOK_SERIES; }
                     CMBookSeries(const string symbol,const uint required=0);

//+------------------------------------------------------------------+ 
//| Methods of working with objects and accessing their properties   |
//+------------------------------------------------------------------+

以下はパラメトリックコンストラクタです。

//+------------------------------------------------------------------+
//| Parametric constructor                                           |
//+------------------------------------------------------------------+
CMBookSeries::CMBookSeries(const string symbol,const uint required=0) : m_symbol(symbol)
  {
   this.m_type=OBJECT_DE_TYPE_BOOK_SERIES;
   this.m_list.Clear();
   this.m_list.Sort(SORT_BY_MBOOK_ORD_TIME_MSC);
   this.SetRequiredUsedDays(required);
  }
//+------------------------------------------------------------------+


\MQL5\Include\DoEasy\Objects\Events\Event.mqhの抽象イベントクラスは、基本オブジェクトの子孫でも、すべてのライブラリオブジェクトの拡張基本オブジェクトの子孫でもありません。したがって、 m_type 変数はなく、変数値を返す仮想Type()メソッドもありません(このようなメソッドは CObject基本オブジェクトに存在します) クラスはから継承されますが、0を返すため、子孫で再定義する必要があります)。これは、変数とメソッドを追加し、作成した変数のクラスコンストラクタに必要な型を設定する必要があることを意味します。

//+------------------------------------------------------------------+
//| Abstract event class                                             |
//+------------------------------------------------------------------+
class CEvent : public CObject
  {
private:
   int               m_event_code;                                   // Event code
//--- Return the index of the array the event's (1) double and (2) string properties are located at
   int               IndexProp(ENUM_EVENT_PROP_DOUBLE property)const { return(int)property-EVENT_PROP_INTEGER_TOTAL;                         }
   int               IndexProp(ENUM_EVENT_PROP_STRING property)const { return(int)property-EVENT_PROP_INTEGER_TOTAL-EVENT_PROP_DOUBLE_TOTAL; }
protected:
   ENUM_TRADE_EVENT  m_trade_event;                                  // Trading event
   bool              m_is_hedge;                                     // Hedge account flag
   long              m_chart_id_main;                                // Control program chart ID
   int               m_type;                                         // Object type
   int               m_digits;                                       // Symbol's Digits()
   int               m_digits_acc;                                   // Number of decimal places for the account currency
   long              m_long_prop[EVENT_PROP_INTEGER_TOTAL];          // Event integer properties
   double            m_double_prop[EVENT_PROP_DOUBLE_TOTAL];         // Event real properties
   string            m_string_prop[EVENT_PROP_STRING_TOTAL];         // Event string properties
//--- return the flag presence in the trading event
   bool              IsPresentEventFlag(const int event_code)  const { return (this.m_event_code & event_code)==event_code;                  }
//--- Return (1) the specified magic number, the ID of (2) the first group, (3) second group, (4) pending request from the magic number value
   ushort            GetMagicID(void)                          const { return ushort(this.Magic() & 0xFFFF);                                 }
   uchar             GetGroupID1(void)                         const { return uchar(this.Magic()>>16) & 0x0F;                                }
   uchar             GetGroupID2(void)                         const { return uchar((this.Magic()>>16) & 0xF0)>>4;                           }
   uchar             GetPendReqID(void)                        const { return uchar(this.Magic()>>24) & 0xFF;                                }
//--- Protected parametric constructor
                     CEvent(const ENUM_EVENT_STATUS event_status,const int event_code,const ulong ticket);
public:
//--- Default constructor
                     CEvent(void){ this.m_type=OBJECT_DE_TYPE_EVENT; }
 
//--- Set event's (1) integer, (2) real and (3) string properties
   void              SetProperty(ENUM_EVENT_PROP_INTEGER property,long value) { this.m_long_prop[property]=value;                            }
   void              SetProperty(ENUM_EVENT_PROP_DOUBLE property,double value){ this.m_double_prop[this.IndexProp(property)]=value;          }
   void              SetProperty(ENUM_EVENT_PROP_STRING property,string value){ this.m_string_prop[this.IndexProp(property)]=value;          }
//--- Return the event's (1) integer, (2) real and (3) string properties from the property array
   long              GetProperty(ENUM_EVENT_PROP_INTEGER property)      const { return this.m_long_prop[property];                           }
   double            GetProperty(ENUM_EVENT_PROP_DOUBLE property)       const { return this.m_double_prop[this.IndexProp(property)];         }
   string            GetProperty(ENUM_EVENT_PROP_STRING property)       const { return this.m_string_prop[this.IndexProp(property)];         }

//--- Return the flag of the event supporting the property
   virtual bool      SupportProperty(ENUM_EVENT_PROP_INTEGER property)        { return true;       }
   virtual bool      SupportProperty(ENUM_EVENT_PROP_DOUBLE property)         { return true;       }
   virtual bool      SupportProperty(ENUM_EVENT_PROP_STRING property)         { return true;       }
//--- Return an object type
   virtual int       Type(void)                                         const { return this.m_type;}

//--- Decode the event code and set the trading event, (2) return the trading event
   void              SetTypeEvent(void);
   ENUM_TRADE_EVENT  TradeEvent(void)                                   const { return this.m_trade_event;                                   }
//--- Send the event to the chart (implementation in descendant classes)
   virtual void      SendEvent(void) {;}

//--- Compare CEvent objects by a specified property (to sort the lists by a specified event object property)
   virtual int       Compare(const CObject *node,const int mode=0) const;
//--- Compare CEvent objects by all properties (to search for equal event objects)
   bool              IsEqual(CEvent* compared_event);
//+------------------------------------------------------------------+
//| Methods of simplified access to event object properties          |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CEvent::CEvent(const ENUM_EVENT_STATUS event_status,const int event_code,const ulong ticket) : m_event_code(event_code),m_digits(0)
  {
   this.m_type=OBJECT_DE_TYPE_EVENT;
   this.m_long_prop[EVENT_PROP_STATUS_EVENT]       =  event_status;
   this.m_long_prop[EVENT_PROP_TICKET_ORDER_EVENT] =  (long)ticket;
   this.m_is_hedge=#ifdef __MQL4__ true #else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif;
   this.m_digits_acc=#ifdef __MQL4__ 2 #else (int)::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #endif;
   this.m_chart_id_main=::ChartID();
  }
//+------------------------------------------------------------------+

抽象イベントクラスオブジェクトの子孫では、コンストラクタで必要なオブジェクト型を指定する必要があります

以下は、\MQL5\Include\DoEasy\Objects\Events\EventBalanceOperation.mqhにある残高操作イベントのクラスです。

//+------------------------------------------------------------------+
//| Balance operation event                                          |
//+------------------------------------------------------------------+
class CEventBalanceOperation : public CEvent
  {
public:
//--- Constructor
                     CEventBalanceOperation(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_BALANCE,event_code,ticket)
                       { this.m_type=OBJECT_DE_TYPE_EVENT_BALANCE; }
//--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_EVENT_PROP_INTEGER property);
   virtual bool      SupportProperty(ENUM_EVENT_PROP_DOUBLE property);
   virtual bool      SupportProperty(ENUM_EVENT_PROP_STRING property);
//--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart
   virtual void      PrintShort(void);
   virtual void      SendEvent(void);
  };
//+------------------------------------------------------------------+

以下は、MQL5\Include\DoEasy\Objects\Events\EventModify.mqhにある未決注文またはポジション変更イベントクラスです。

//+------------------------------------------------------------------+
//| Pending order or position modification event                     |
//+------------------------------------------------------------------+
class CEventModify : public CEvent
  {
private:
   double            m_price;                               // Price sent to an event
//--- Create and return a short event message
   string            EventsMessage(void);
public:
//--- Constructor
                     CEventModify(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_MODIFY,event_code,ticket),m_price(0)
                       { this.m_type=OBJECT_DE_TYPE_EVENT_MODIFY; }
//--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_EVENT_PROP_INTEGER property);
   virtual bool      SupportProperty(ENUM_EVENT_PROP_DOUBLE property);
//--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart
   virtual void      PrintShort(void);
   virtual void      SendEvent(void);
  };
//+------------------------------------------------------------------+

以下は、\MQL5\Include\DoEasy\Objects\Events\EventOrderPlaced.mqhにある未決注文配置イベントのクラスです。

//+------------------------------------------------------------------+
//| Pending order placing event                                      |
//+------------------------------------------------------------------+
class CEventOrderPlased : public CEvent
  {
public:
//--- Constructor
                     CEventOrderPlased(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_MARKET_PENDING,event_code,ticket)
                       { this.m_type=OBJECT_DE_TYPE_EVENT_ORDER_PLASED; }
//--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_EVENT_PROP_INTEGER property);
   virtual bool      SupportProperty(ENUM_EVENT_PROP_DOUBLE property);
//--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart
   virtual void      PrintShort(void);
   virtual void      SendEvent(void);
  };
//+------------------------------------------------------------------+

以下は、\MQL5\Include\DoEasy\Objects\Events\EventOrderRemoved.mqhにある未決注文削除イベントのクラスです。

//+------------------------------------------------------------------+
//| Pending order removal event                                      |
//+------------------------------------------------------------------+
class CEventOrderRemoved : public CEvent
  {
public:
//--- Constructor
                     CEventOrderRemoved(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_HISTORY_PENDING,event_code,ticket)
                       { this.m_type=OBJECT_DE_TYPE_EVENT_ORDER_REMOVED; }
//--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_EVENT_PROP_INTEGER property);
   virtual bool      SupportProperty(ENUM_EVENT_PROP_DOUBLE property);
//--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart
   virtual void      PrintShort(void);
   virtual void      SendEvent(void);
  };
//+------------------------------------------------------------------+

以下は、\MQL5\Include\DoEasy\Objects\Events\EventPositionClose.mqhにあるポジション決済イベントのクラスです。

//+------------------------------------------------------------------+
//| Position closure event                                           |
//+------------------------------------------------------------------+
class CEventPositionClose : public CEvent
  {
private:
//--- Create and return a short event message
   string            EventsMessage(void);  
public:
//--- Constructor
                     CEventPositionClose(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_HISTORY_POSITION,event_code,ticket)
                       { this.m_type=OBJECT_DE_TYPE_EVENT_POSITION_CLOSE; }
//--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_EVENT_PROP_INTEGER property);
   virtual bool      SupportProperty(ENUM_EVENT_PROP_DOUBLE property);
//--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart
   virtual void      PrintShort(void);
   virtual void      SendEvent(void);
  };
//+------------------------------------------------------------------+

以下は、\MQL5\Include\DoEasy\Objects\Events\EventPositionOpen.mqhにあるポジションオープンイベントのクラスです。

//+------------------------------------------------------------------+
//| Position opening event                                           |
//+------------------------------------------------------------------+
class CEventPositionOpen : public CEvent
  {
private:
//--- Create and return a short event message
   string            EventsMessage(void);  
public:
//--- Constructor
                     CEventPositionOpen(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_MARKET_POSITION,event_code,ticket)
                       { this.m_type=OBJECT_DE_TYPE_EVENT_POSITION_OPEN; }
//--- Supported order properties (1) real, (2) integer
   virtual bool      SupportProperty(ENUM_EVENT_PROP_INTEGER property);
   virtual bool      SupportProperty(ENUM_EVENT_PROP_DOUBLE property);
//--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart
   virtual void      PrintShort(void);
   virtual void      SendEvent(void);
  };
//+------------------------------------------------------------------+


ご覧のとおり、以前に作成されたオブジェクトのクラスを改善することを目的としたすべてのアクションは、次のように要約されます。

  • オブジェクトがすべてのライブラリオブジェクトの基本オブジェクトまたは拡張基本オブジェクトから派生している場合は、Defines.mqhで作成されたENUM_OBJECT_DE_TYPE列挙型のコンストラクタ(デフォルトおよびパラメトリックオブジェクト)からオブジェクト型を指定します。
  • それ以外の場合は、クラスのprotectedセクションにm_type変数を追加します。変数は、オブジェクト型を格納するためのものです。publicセクションで、m_type変数値を返す仮想Type()メソッドを追加します。クラスコンストラクタ(デフォルトおよびパラメトリックコンストラクタ)で、ENUM_OBJECT_DE_TYPE列挙型からオブジェクト型を指定します。

すべての変更は、ライブラリオブジェクトクラスのファイルですでに行われています。アクションが同様なので説明は省きます。

\MQL5\Include\DoEasy\Objectsライブラリディレクトリにある改善されたクラスのリストは次のとおりです。

  • Chartフォルダ: ChartObj.mqh、ChartWnd.mqh
  • Indicatorsフォルダ: Buffer.mqh、BufferArrow.mqh、BufferBars.mqh、BufferCalculate.mqh、BufferCandles.mqh、 BufferFilling.mqh、BufferHistogram.mqh、BufferHistogram2.mqh、BufferLine.mqh、BufferSection.mqh、BufferZigZag.mqh、DataInd.mqh、IndicatorDE.mqh、SeriesDataInd.mqh
    Standartフォルダ: IndAC.mqh、IndAD.mqh、IndADX.mqh、IndADXW.mqh、IndAlligator.mqh、IndAMA.mqh、IndAO.mqh、IndATR.mqh、IndBands.mqh、IndBears.mqh、IndBulls.mqh、IndBWMFI.mqh、IndCCI.mqh、IndChaikin.mqh、IndCustom.mqh、IndDEMA.mqh、IndDeMarker.mqh、IndEnvelopes.mqh、IndForce.mqh、IndFractals.mqh、IndFRAMA.mqh、IndGator.mqh、IndIchimoku.mqh、IndMA.mqh、IndMACD.mqh、IndMFI.mqh、IndMomentum.mqh、IndOBV.mqh、IndOsMA.mqh、IndRSI.mqh、IndRVI.mqh、IndSAR.mqh、IndStDev.mqh、IndStoch.mqh、IndTEMA.mqh、IndTRIX.mqh、IndVIDYA.mqh、IndVolumes.mqh、IndWPR.mqh
  • MQLSignalBaseフォルダ: MQLSignal.mqh
  • Ordersフォルダ: HistoryBalance.mqh、HistoryDeal.mqh、HistoryOrder.mqh、HistoryPending.mqh、MarketOrder.mqh、MarketPending.mqh、MarketPosition.mqh、Order.mqh
  • PendRequestフォルダ: PendReqClose.mqh、PendReqModify.mqh、PendReqOpen.mqh、PendReqPlace.mqh、PendReqRemove.mqh、PendReqSLTP.mqh、PendRequest.mqh
  • Seriesフォルダ: Bar.mqh、SeriesDE.mqh、TimeSeriesDE.mqh
  • Symbolsフォルダ: Symbol.mqh、SymbolBonds.mqh、SymbolCFD.mqh、SymbolCollateral.mqh、SymbolCommodity.mqh、SymbolCommon.mqh、SymbolCrypto.mqh、SymbolCustom.mqh、SymbolExchange.mqh、SymbolFutures.mqh、SymbolFX.mqh、SymbolFXExotic.mqh、SymbolFXMajor.mqh、SymbolFXMinor.mqh、SymbolFXRub.mqh、SymbolIndex.mqh、SymbolIndicative.mqh、SymbolMetall.mqh、SymbolOption.mqh、SymbolStocks.mqh
  • Ticksフォルダ: DataTick.mqh、NewTickObj.mqh、TickSeries.mqh
  • Tradeフォルダ: TradeObj.mqh
  • Graphフォルダ: Form.mqh、GCnvElement.mqh、GraphElmControl.mqh、ShadowObj.mqh
    Animationsフォルダ: Animations.mqh、Frame.mqh、FrameGeometry.mqh、FrameQuad.mqh、FrameText.mqh

すべてのファイルは以下に添付されています。

また、\MQL5\Include\DoEasy\Objects\Graph\GBaseObj.mqh内のすべてのライブラリグラフィカルオブジェクトの基本オブジェクトクラスを忘れないでください。オブジェクト型の指定とは別に、は「プログラム/ターミナルに属す」プロパティも備えており、ライブラリ管理プログラムによって作成されたグラフィカルオブジェクトと ターミナルで手動でチャートに追加されたオブジェクトを定義できます。

//+------------------------------------------------------------------+
//|                                                     GBaseObj.mqh |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "..\..\Services\DELib.mqh"
#include <Graphics\Graphic.mqh>
//+------------------------------------------------------------------+
//| Class of the base object of the library graphical objects        |
//+------------------------------------------------------------------+
class CGBaseObj : public CObject
  {
private:
   
protected:
   string            m_name_prefix;                      // Object name prefix
   string            m_name;                             // Object name
   long              m_chart_id;                         // Chart ID
   int               m_subwindow;                        // Subwindow index
   int               m_shift_y;                          // Subwindow Y coordinate shift
   int               m_type;                             // Object type
   bool              m_visible;                          // Object visibility
   ENUM_GRAPH_OBJ_BELONG m_belong;                       // Program/terminal affiliation
   
//--- Create (1) the object structure and (2) the object from the structure
   virtual bool      ObjectToStruct(void)                      { return true; }
   virtual void      StructToObject(void){;}

public:
//--- Return the values of class variables
   string            Name(void)                          const { return this.m_name;      }
   long              ChartID(void)                       const { return this.m_chart_id;  }
   int               SubWindow(void)                     const { return this.m_subwindow; }
   ENUM_GRAPH_OBJ_BELONG Belong(void)                    const { return this.m_belong;    }
   
//--- (1) Set and (2) return the object visibility
   void              SetVisible(const bool flag)   
                       { 
                        long value=(flag ? OBJ_ALL_PERIODS : 0);
                        if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_TIMEFRAMES,value))
                           this.m_visible=flag;
                       }
   bool              IsVisible(void)                     const { return this.m_visible;   }

//--- The virtual method returning the object type
   virtual int       Type(void)                          const { return this.m_type;      }
//--- Set affiliation
   void              SetBelong(const ENUM_GRAPH_OBJ_BELONG belong){ this.m_belong=belong; }

//--- Constructor/destructor
                     CGBaseObj();
                    ~CGBaseObj();
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CGBaseObj::CGBaseObj() : m_shift_y(0),m_visible(false), m_name_prefix(::MQLInfoString(MQL_PROGRAM_NAME)+"_"),m_belong(GRAPH_OBJ_BELONG_PROGRAM)
  {
   this.m_type=OBJECT_DE_TYPE_GBASE;
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CGBaseObj::~CGBaseObj()
  {
  }
//+------------------------------------------------------------------+


ライブラリオブジェクトクラスファイルに実装されているものと同様の改善が、\MQL5\Include\DoEasy\Collections\にあるライブラリオブジェクトコレクションクラスのファイルに実装されました。

以下は、改善されたオブジェクトコレクションクラスのファイルのリストです。

AccountsCollection.mqh、BookSeriesCollection.mqh、BuffersCollection.mqh、ChartObjCollection.mqh、EventsCollection.mqh、HistoryCollection.mqh、IndicatorsCollection.mqh、MarketCollection.mqh、MQLSignalsCollection.mqh、ResourceCollection.mqh、SymbolsCollection.mqh、TickSeriesCollection.mqh、TimeSeriesCollection.mqh

すべてのファイルは以下に添付されています。

これで、ライブラリクラスの改善は終わりです。


グラフィカルオブジェクトのコレクションクラス

前回の記事では、ライブラリのグラフィカルオブジェクトコレクションクラス(\MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqh)のワークピースを作成しました。本稿では、その開発を続けていきます。

ターミナルで開いたチャートのいずれかでグラフィカルオブジェクトを作成する場合、ライブラリは、オブジェクトの種類、追加または削除したかどうか、およびライブラリからプログラムで、または手動で作成した方法を定義できる必要があります。プログラムで追加されたオブジェクトは、ライブラリのグラフィカルオブジェクトのコレクションに自動的に追加されるべきではありません。作成時にコレクションリストに追加されます(これについては、以降の記事で説明します)。手動で追加されたグラフィカルオブジェクトの場合、ライブラリはそれらを識別し、それらのグラフィカルオブジェクト(要素)を作成して、コレクションリストに追加する必要があります。チャートからグラフィカルオブジェクトを削除する場合も、ライブラリで同じことを行う必要があります。プログラムオブジェクトは、削除中にリストから削除されます。手動で削除された場合、ライブラリはそれらを追跡し、削除されたグラフィカルオブジェクトに一致する要素をコレクションリストから削除する必要があります。

この機能は1つの記事にはまらないので、すべてを順番に行います。現在の記事では、グラフィカルオブジェクトのコレクションクラスのターミナルチャートのいずれかでグラフィカルオブジェクトの出現を追跡することを実装します。グラフィカルオブジェクトがプログラム的であるか手動的であるかは重要ではありません。コレクションクラスは、チャートの出現と削除を追跡し、その結果を操作ログに送信します(特定のターミナルチャートに追加/削除されたグラフィカルオブジェクトの量)。

チャート上のグラフィカルオブジェクトの数を取得するには、 ObjectsTotal()関数を使用して、指定されたチャートおよびサブウィンドウ内の指定されたタイプのグラフィカルオブジェクト の数を返します。 サブウィンドウ(メインウィンドウを含む)のいずれかで指定されたチャート上の任意のタイプのグラフィカルオブジェクトの数を取得するには、残りのパラメータをデフォルト値(-1)のままにして、必要なチャートIDを関数に渡す必要があります。 )。これにより、サブウィンドウを含むすべてのチャートオブジェクトの数を取得できます。

現在追加されているオブジェクトの数を定義するには、それらの以前の数と現在の数を知る必要があります。これら2つの値の違いは、追加されたオブジェクトの数です。これには、チャート上の現在のグラフィカルオブジェクトの数と、前回のチェック時の数の2つの変数が必要です。数が変更された場合は、チャートに追加された/チャートから削除されたオブジェクトの種類を定義します。

この時点で、この値を正しく計算するという問題が発生します。ObjectsTotal()関数の説明に戻ると、すべてのチャートを一度に返すのではなく、単一のチャートのみのオブジェクトの数を返すことが明らかになります。したがって、各チャートには、現在および以前の数のグラフィカルオブジェクトを格納するための独自の変数が必要です。ここでできる最も簡単なことは、グラフィカルオブジェクトを管理するための小さなクラスを作成することです。開いている各チャートには、クラスの独自のインスタンスが必要です。この場合、他のチャートに関係なく、オブジェクト数の変化を簡単に追跡できます。

このようなクラスを、グラフィカルオブジェクトのコレクションクラス\MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqhのファイルに直接実装してみましょう。

//+------------------------------------------------------------------+
//|                                      GraphElementsCollection.mqh |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "ListObj.mqh"
#include "..\Services\Select.mqh"
#include "..\Objects\Graph\Form.mqh"
//+------------------------------------------------------------------+
//| Chart object management class                                    |
//+------------------------------------------------------------------+
class CChartObjectsControl : public CObject
  {
private:
   ENUM_TIMEFRAMES   m_chart_timeframe;         // Chart timeframe
   long              m_chart_id;                // Chart ID
   string            m_chart_symbol;            // Chart symbol
   bool              m_is_graph_obj_event;      // Event flag in the list of graphical objects
   int               m_total_objects;           // Number of graphical objects
   int               m_last_objects;            // Number of graphical objects during the previous check
   int               m_index_object;            //  Index of the last graphical object added to the collection from the terminal object list
   int               m_delta_graph_obj;         // Difference in the number of graphical objects compared to the previous check
public:
//--- Return the variable values
   ENUM_TIMEFRAMES   Timeframe(void)                           const { return this.m_chart_timeframe;    }
   long              ChartID(void)                             const { return this.m_chart_id;           }
   string            Symbol(void)                              const { return this.m_chart_symbol;       }
   bool              IsEvent(void)                             const { return this.m_is_graph_obj_event; }
   int               TotalObjects(void)                        const { return this.m_total_objects;      }
   int               Delta(void)                               const { return this.m_delta_graph_obj;    }
//--- Check the chart objects
   void              Refresh(void);
//--- Constructors
                     CChartObjectsControl(void)
                       { 
                        this.m_chart_id=::ChartID();
                        this.m_chart_timeframe=(ENUM_TIMEFRAMES)::ChartPeriod(this.m_chart_id);
                        this.m_chart_symbol=::ChartSymbol(this.m_chart_id);
                        this.m_is_graph_obj_event=false;
                        this.m_total_objects=0;
                        this.m_last_objects=0;
                        this.m_index_object=0;
                        this.m_delta_graph_obj=0;
                       }
                     CChartObjectsControl(const long chart_id)
                       {
                        this.m_chart_id=chart_id;
                        this.m_chart_timeframe=(ENUM_TIMEFRAMES)::ChartPeriod(this.m_chart_id);
                        this.m_chart_symbol=::ChartSymbol(this.m_chart_id);
                        this.m_is_graph_obj_event=false;
                        this.m_total_objects=0;
                        this.m_last_objects=0;
                        this.m_index_object=0;
                        this.m_delta_graph_obj=0;
                       }
                     
//--- Compare CChartObjectsControl objects by a chart ID (for sorting the list by an object property)
   virtual int       Compare(const CObject *node,const int mode=0) const
                       {
                        const CChartObjectsControl *obj_compared=node;
                        return(this.ChartID()>obj_compared.ChartID() ? 1 : this.ChartID()<obj_compared.ChartID() ? -1 : 0);
                       }
  };
//+------------------------------------------------------------------+
//| CChartObjectsControl Check objects on a chart                    |
//+------------------------------------------------------------------+
void CChartObjectsControl::Refresh(void)
  {
//--- Graphical objects on the chart
   this.m_total_objects=::ObjectsTotal(this.ChartID());
   int i=this.m_index_object;
   int delta=this.m_total_objects-this.m_last_objects;
   
//--- If the number of objects has changed
   if(delta!=0)
     {
      //--- Create the string and display it in the journal with the chart ID, its symbol and timeframe
      string txt=", "+(delta>0 ? "Added: " : "Deleted: ")+(string)fabs(delta)+" obj";
      Print(DFUN,"ChartID=",this.ChartID(),", ",this.Symbol(),", ",TimeframeDescription(this.Timeframe()),txt);
     }

//--- save the index of the last added order and the difference with the last check
   this.m_delta_graph_obj=i-this.m_index_object;
   this.m_index_object=i;
   this.m_last_objects=this.m_total_objects;
   this.m_is_graph_obj_event=(bool)this.m_delta_graph_obj;
  }
//+------------------------------------------------------------------+

一般に、ここではすべてが明確である必要があります。「現在」および前回のチェック中にグラフィカルオブジェクトの量を格納するための変数があります。現在のループインデックス値を格納するための変数:最初からループが常に実行されるのを避けるために、現在のインデックス値を記憶し、次回は最初からではなく保存された値からループを開始します。これは、注文、取引、およびポジション管理ループがどのように機能するかです。ここも同じです。2つのコンストラクタがあります。1つ目は現在のチャートのオブジェクトを作成し、2つ目はIDで指定されたチャートに対して同じことを行います。Compare()メソッドは、チャートIDによって2つのオブジェクトを比較します。これにより、指定されたIDを持つチャートにそのようなオブジェクトがすでに存在することを定義できます。

Refresh()メソッドで、現在および最後のチェック中にオブジェクトの数をチェックするだけです。数が変更されている場合は、操作ログエントリを表示します。次に、m_index_object変数に保存されているループインデックスからオブジェクトをループして、すべての新しいオブジェクトを追跡し、イベントオブジェクトを作成します。現時点では、リソース節約計算のためにループを次に開始するために、ループインデックスが変数にすでに保存されています。これは、将来の使用のための基礎です。

これで、コレクションクラスのターミナルで開いているチャートごとにこのようなオブジェクトを作成すると、各チャートのオブジェクト数の変化を互いに独立して追跡できるようになります。

以前に作成したCGraphElementsCollectionクラスに新しい変数とメソッドを追加します。

クラスのprivateセクションで、チャート管理オブジェクトへのポインタのリストチャート上のグラフィカルオブジェクトを追加/削除するためのイベントフラグ変数 開いているすべてのチャートにオブジェクトの数を格納するための変数および開いているすべてのターミナルチャートに追加/削除されたオブジェクトの総数を格納するための変数を宣言します。

//+------------------------------------------------------------------+
//| Collection of graphical objects                                  |
//+------------------------------------------------------------------+
class CGraphElementsCollection : public CBaseObj
  {
private:
   CArrayObj         m_list_charts_control;     // List of chart management objects
   CListObj          m_list_all_graph_obj;      // List of all 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 object in the list of graphical objects
   bool              IsPresentGraphElmInList(const int id,const ENUM_GRAPH_ELEMENT_TYPE type_obj);

同じセクションで、指定されたチャートのオブジェクトを管理するためのオブジェクトへのポインタを返すメソッド指定されたチャートのグラフィカルオブジェクトを管理するための新しいオブジェクトを作成してリストに追加するメソッドチャートIDによってグラフィカルオブジェクトのリストを更新するメソッドを宣言します。

//--- Return the flag indicating the graphical element object in the list of graphical objects
   bool              IsPresentGraphElmInList(const int id,const ENUM_GRAPH_ELEMENT_TYPE type_obj);
//--- 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
   void              RefreshByChartID(const long chart_id);

public:

publicセクションで、グラフィカルオブジェクトのリストに発生した変更のフラグを返すメソッドを追加し、チャート管理オブジェクトのリストを作成するメソッドおよび ターミナルチャート上のグラフィカルオブジェクトのリストを更新するメソッドの2つを宣言します。

public:
//--- Return itself
   CGraphElementsCollection *GetObject(void)                                                             { return &this;                        }
   //--- Return the full collection list 'as is'
   CArrayObj        *GetList(void)                                                                       { return &this.m_list_all_graph_obj;   }
   //--- Return the list by selected (1) integer, (2) real and (3) string properties meeting the compared criterion
   CArrayObj        *GetList(ENUM_CANV_ELEMENT_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode=EQUAL)  { return CSelect::ByGraphCanvElementProperty(this.GetList(),property,value,mode);  }
   CArrayObj        *GetList(ENUM_CANV_ELEMENT_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByGraphCanvElementProperty(this.GetList(),property,value,mode);  }
   CArrayObj        *GetList(ENUM_CANV_ELEMENT_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByGraphCanvElementProperty(this.GetList(),property,value,mode);  }
   //--- Return the number of new graphical objects, (3) the flag of the occurred change in the list of graphical objects
   int               NewObjects(void)   const                                                            { return this.m_delta_graph_obj;       }
   bool              IsEvent(void) const                                                                 { return this.m_is_graph_obj_event;    }
   //--- Constructor
                     CGraphElementsCollection();
//--- Display the description of the object properties in the journal (full_prop=true - all properties, false - supported ones only - implemented in descendant classes)
   virtual void      Print(const bool full_prop=false,const bool dash=false);
//--- Display a short description of the object in the journal
   virtual void      PrintShort(const bool dash=false,const bool symbol=false);

//--- Create the list of chart management objects and return the number of charts
   int               CreateChartControlList(void);
//--- Update the list of (1) all graphical objects, (2) on the specified chart, fill in the data on the number of new ones and set the event flag
   void              Refresh(void);
   void              Refresh(const long chart_id);
  };
//+------------------------------------------------------------------+

クラスコンストラクタで、オブジェクトに適切なタイプを割り当てチャート管理オブジェクトへのポインタのリストにソート済みリストフラグを設定リストをクリアすべてのチャートのオブジェクトの総数をゼロに設定し、グラフィカルオブジェクトコレクションのイベントフラグをリセットします。

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CGraphElementsCollection::CGraphElementsCollection()
  {
   this.m_type=COLLECTION_GRAPH_OBJ_ID;
   ::ChartSetInteger(::ChartID(),CHART_EVENT_MOUSE_MOVE,true);
   ::ChartSetInteger(::ChartID(),CHART_EVENT_MOUSE_WHEEL,true);
   this.m_list_all_graph_obj.Type(COLLECTION_GRAPH_OBJ_ID);
   this.m_list_all_graph_obj.Sort(SORT_BY_CANV_ELEMENT_ID);
   this.m_list_all_graph_obj.Clear();
   this.m_list_charts_control.Sort();
   this.m_list_charts_control.Clear();
   this.m_total_objects=0;
   this.m_is_graph_obj_event=false;
  }
//+------------------------------------------------------------------+

宣言されたメソッドの実装について考えてみましょう。

以下は、指定されたチャートのグラフィカルオブジェクトを管理する新しいオブジェクトを作成し、それをリストに追加するメソッドです。

//+------------------------------------------------------------------+
//| Create a new graphical object management object                  |
//| for a specified and add it to the list                           |
//+------------------------------------------------------------------+
CChartObjectsControl *CGraphElementsCollection::CreateChartObjectCtrlObj(const long chart_id)
  {
//--- Create a new object for managing chart objects by ID
   CChartObjectsControl *obj=new CChartObjectsControl(chart_id);
//--- If the object is not created, inform of the error and return NULL
   if(obj==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_CHART_OBJ_COLLECTION_ERR_FAILED_CREATE_CTRL_OBJ),(string)chart_id);
      return NULL;
     }
//--- If failed to add the object to the list, inform of the error, remove the object and return NULL
   if(!this.m_list_charts_control.Add(obj))
     {
      CMessage::ToLog(DFUN,MSG_LIB_SYS_FAILED_OBJ_ADD_TO_LIST);
      delete obj;
      return NULL;
     }
//--- Return the pointer to the object that was created and added to the list
   return obj;
  }
//+------------------------------------------------------------------+

以下は、指定されたチャートのオブジェクトを管理するオブジェクトへのポインタを返すメソッドです。

//+------------------------------------------------------------------+
//| Return the pointer to the object                                 |
//| for managing objects of a specified chart                        |
//+------------------------------------------------------------------+
CChartObjectsControl *CGraphElementsCollection::GetChartObjectCtrlObj(const long chart_id)
  {
//--- In the loop by the total number of objects in the list
   for(int i=0;i<this.m_list_charts_control.Total();i++)
     {
      //--- Get the pointer to the next object
      CChartObjectsControl *obj=this.m_list_charts_control.At(i);
      //--- If failed to get the pointer, move on to the next one
      if(obj==NULL)
         continue;
      //--- If the object chart ID is equal to the required one, return the pointer to the object in the list
      if(obj.ChartID()==chart_id)
         return obj;
     }
//--- Failed to find the object - return NULL
   return NULL;
  }
//+------------------------------------------------------------------+

以下は、チャート管理オブジェクトのリストを作成するメソッドです。

//+------------------------------------------------------------------+
//| Create the list of chart management objects                      |
//+------------------------------------------------------------------+
int CGraphElementsCollection::CreateChartControlList(void)
  {
   //--- Clear the list of chart management objects and set the sorted list flag to it
   this.m_list_charts_control.Clear();
   this.m_list_charts_control.Sort();
   //--- Declare variables to search for charts
   long chart_id=0;
   int i=0;
//--- In the loop by all open charts in the terminal (no more than 100)
   while(i<CHARTS_MAX)
     {
      //--- Get the chart ID
      chart_id=::ChartNext(chart_id);
      if(chart_id<0)
         break;
      //--- Create the object for managing chart objects based on the current chart ID in the loop and add it to the list
      CChartObjectsControl *chart_control=new CChartObjectsControl(chart_id);
      if(chart_control==NULL)
         continue;
      //--- If such an object is already present in the list, inform of that, delete the object and move on to the next chart
      if(this.m_list_charts_control.Search(chart_control)>WRONG_VALUE)
        {
         ::Print(DFUN,CMessage::Text(MSG_CHART_OBJ_COLLECTION_ERR_OBJ_ALREADY_EXISTS),(string)chart_id);
         delete chart_control;
         continue;
        }
      //--- If failed to add the object to the list, inform of that, remove the object and move on to the next chart
      if(!this.m_list_charts_control.Add(chart_control))
        {
         CMessage::ToLog(DFUN_ERR_LINE,MSG_LIB_SYS_FAILED_OBJ_ADD_TO_LIST);
         delete chart_control;
         continue;
        }
      //--- Increase the loop index
      i++;
     }
   //--- The list filled in successfully - return the number of its elements
   return this.m_list_charts_control.Total();
  }
//+------------------------------------------------------------------+

以下は、チャートIDによってグラフィカルオブジェクトのリストを更新するメソッドです。

//+------------------------------------------------------------------+
//| Update the list of graphical objects by chart ID                 |
//+------------------------------------------------------------------+
void CGraphElementsCollection::RefreshByChartID(const long chart_id)
  {
//--- Get the pointer to the object for managing graphical objects
   CChartObjectsControl *obj=GetChartObjectCtrlObj(chart_id);
//--- If there is no such an object in the list, create a new one and add it to the list
   if(obj==NULL)
      obj=this.CreateChartObjectCtrlObj(chart_id);
//--- If the pointer to the object is valid, update the list of graphical objects on a specified chart
   if(obj!=NULL)
      obj.Refresh();
  }
//+------------------------------------------------------------------+

以下は、指定されたチャートのグラフィカルオブジェクトのリストを更新するメソッドです。

//+------------------------------------------------------------------+
//| Update the list of graphical objects on a specified chart        |
//+------------------------------------------------------------------+
void CGraphElementsCollection::Refresh(const long chart_id)
  {
//--- Get the pointer to the object for managing graphical objects
   CChartObjectsControl *obj=GetChartObjectCtrlObj(chart_id);
//--- If failed to get the pointer, exit the method
   if(obj==NULL)
      return;
//--- Update the list of graphical objects on a specified chart
   obj.Refresh();
  }
//+------------------------------------------------------------------+

以下は、ターミナルで開いているすべてのチャートのすべてのグラフィカルオブジェクトのリストを更新するメソッドです。

//+------------------------------------------------------------------+
//| Update the list of all graphical objects                         |
//+------------------------------------------------------------------+
void CGraphElementsCollection::Refresh(void)
  {
//--- Declare variables to search for charts
   long chart_id=0;
   int i=0;
//--- In the loop by all open charts in the terminal (no more than 100)
   while(i<CHARTS_MAX)
     {
      //--- Get the chart ID
      chart_id=::ChartNext(chart_id);
      if(chart_id<0)
         break;
      //--- Update the list of graphical objects by chart ID
      this.RefreshByChartID(chart_id);
      //--- Increase the loop index
      i++;
     }
  }
//+------------------------------------------------------------------+

提供されている各メソッドのロジックは、適切なコードコメントで詳細に説明されています。ご質問がある場合は、コメント欄でお気軽にお問い合わせください。

次に、新しく作成したグラフィカルオブジェクトのコレクションをCEngineライブラリのメインオブジェクトに含めて、プログラムからコレクション機能にアクセスできるようにする必要があります。

\MQL5\Include\DoEasy\Engine.mqhのクラスのprivateセクションで、グラフィカルオブジェクトコレクションクラスのインスタンスおよびグラフィカルオブジェクトのリストでのイベントフラグ変数 グラフィカルオブジェクトイベントを管理するメソッドを宣言します。

//+------------------------------------------------------------------+
//| Library basis class                                              |
//+------------------------------------------------------------------+
class CEngine
  {
private:
   CHistoryCollection   m_history;                       // Collection of historical orders and deals
   CMarketCollection    m_market;                        // Collection of market orders and deals
   CEventsCollection    m_events;                        // Event collection
   CAccountsCollection  m_accounts;                      // Account collection
   CSymbolsCollection   m_symbols;                       // Symbol collection
   CTimeSeriesCollection m_time_series;                  // Timeseries collection
   CBuffersCollection   m_buffers;                       // Collection of indicator buffers
   CIndicatorsCollection m_indicators;                   // Indicator collection
   CTickSeriesCollection m_tick_series;                  // Collection of tick series
   CMBookSeriesCollection m_book_series;                 // Collection of DOM series
   CMQLSignalsCollection m_signals_mql5;                 // Collection of MQL5.com Signals service signals
   CChartObjCollection  m_charts;                        // Chart collection
   CGraphElementsCollection m_graph_objects;             // Collection of graphical objects
   CResourceCollection  m_resource;                      // Resource list
   CTradingControl      m_trading;                       // Trading management object
   CPause               m_pause;                         // Pause object
   CArrayObj            m_list_counters;                 // List of timer counters
   int                  m_global_error;                  // Global error code
   bool                 m_first_start;                   // First launch flag
   bool                 m_is_hedge;                      // Hedge account flag
   bool                 m_is_tester;                     // Flag of working in the tester
   bool                 m_is_market_trade_event;         // Account trading event flag
   bool                 m_is_history_trade_event;        // Account history trading event flag
   bool                 m_is_account_event;              // Account change event flag
   bool                 m_is_symbol_event;               // Symbol change event flag
   bool                 m_is_graph_obj_event;            // Event flag in the list of graphical objects
   ENUM_TRADE_EVENT     m_last_trade_event;              // Last account trading event
   int                  m_last_account_event;            // Last event in the account properties
   int                  m_last_symbol_event;             // Last event in the symbol properties
   ENUM_PROGRAM_TYPE    m_program;                       // Program type
   string               m_name;                          // Program name
//--- Return the counter index by id
   int                  CounterIndex(const int id) const;
//--- Return the first launch flag
   bool                 IsFirstStart(void);
//--- Handling events of (1) orders, deals and positions, (2) accounts and (3) graphical objects
   void                 TradeEventsControl(void);
   void                 AccountEventsControl(void);
   void                 GraphObjEventsControl(void);
//--- (1) Working with a symbol collection and (2) symbol list events in the market watch window
   void                 SymbolEventsControl(void);
   void                 MarketWatchEventsControl(void);
//--- Return the last (1) market pending order, (2) market order, (3) last position, (4) position by ticket
   COrder              *GetLastMarketPending(void);
   COrder              *GetLastMarketOrder(void);
   COrder              *GetLastPosition(void);
   COrder              *GetPosition(const ulong ticket);
//--- Return the last (1) removed pending order, (2) historical market order, (3) historical order (market or pending one) by its ticket
   COrder              *GetLastHistoryPending(void);
   COrder              *GetLastHistoryOrder(void);
   COrder              *GetHistoryOrder(const ulong ticket);
//--- Return the (1) first and the (2) last historical market orders from the list of all position orders, (3) the last deal
   COrder              *GetFirstOrderPosition(const ulong position_id);
   COrder              *GetLastOrderPosition(const ulong position_id);
   COrder              *GetLastDeal(void);
//--- Retrieve a necessary 'ushort' number from the packed 'long' value
   ushort               LongToUshortFromByte(const long source_value,const uchar index) const;
   
public:

クラスコンストラクタで、グラフィカルオブジェクトコレクションのカウンタを作成します。

//+------------------------------------------------------------------+
//| CEngine constructor                                              |
//+------------------------------------------------------------------+
CEngine::CEngine() : m_first_start(true),
                     m_last_trade_event(TRADE_EVENT_NO_EVENT),
                     m_last_account_event(WRONG_VALUE),
                     m_last_symbol_event(WRONG_VALUE),
                     m_global_error(ERR_SUCCESS)
  {
   this.m_is_hedge=#ifdef __MQL4__ true #else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif;
   this.m_is_tester=::MQLInfoInteger(MQL_TESTER);
   this.m_program=(ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE);
   this.m_name=::MQLInfoString(MQL_PROGRAM_NAME);
   
   this.m_list_counters.Sort();
   this.m_list_counters.Clear();
   this.CreateCounter(COLLECTION_ORD_COUNTER_ID,COLLECTION_ORD_COUNTER_STEP,COLLECTION_ORD_PAUSE);
   this.CreateCounter(COLLECTION_ACC_COUNTER_ID,COLLECTION_ACC_COUNTER_STEP,COLLECTION_ACC_PAUSE);
   this.CreateCounter(COLLECTION_SYM_COUNTER_ID1,COLLECTION_SYM_COUNTER_STEP1,COLLECTION_SYM_PAUSE1);
   this.CreateCounter(COLLECTION_SYM_COUNTER_ID2,COLLECTION_SYM_COUNTER_STEP2,COLLECTION_SYM_PAUSE2);
   this.CreateCounter(COLLECTION_REQ_COUNTER_ID,COLLECTION_REQ_COUNTER_STEP,COLLECTION_REQ_PAUSE);
   this.CreateCounter(COLLECTION_TS_COUNTER_ID,COLLECTION_TS_COUNTER_STEP,COLLECTION_TS_PAUSE);
   this.CreateCounter(COLLECTION_IND_TS_COUNTER_ID,COLLECTION_IND_TS_COUNTER_STEP,COLLECTION_IND_TS_PAUSE);
   this.CreateCounter(COLLECTION_TICKS_COUNTER_ID,COLLECTION_TICKS_COUNTER_STEP,COLLECTION_TICKS_PAUSE);
   this.CreateCounter(COLLECTION_CHARTS_COUNTER_ID,COLLECTION_CHARTS_COUNTER_STEP,COLLECTION_CHARTS_PAUSE);
   this.CreateCounter(COLLECTION_GRAPH_OBJ_COUNTER_ID,COLLECTION_GRAPH_OBJ_COUNTER_STEP,COLLECTION_GRAPH_OBJ_PAUSE);
   
   ::ResetLastError();
   #ifdef __MQL5__
      if(!::EventSetMillisecondTimer(TIMER_FREQUENCY))
        {
         ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_TIMER),(string)::GetLastError());
         this.m_global_error=::GetLastError();
        }
   //---__MQL4__
   #else 
      if(!this.IsTester() && !::EventSetMillisecondTimer(TIMER_FREQUENCY))
        {
         ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_TIMER),(string)::GetLastError());
         this.m_global_error=::GetLastError();
        }
   #endif 
   //---
  }
//+------------------------------------------------------------------+

クラスタイマーで、グラフィカルオブジェクトコレクションのタイマーの処理を追加します

//+------------------------------------------------------------------+
//| CEngine timer                                                    |
//+------------------------------------------------------------------+
void CEngine::OnTimer(SDataCalculate &data_calculate)
  {
//--- If this is not a tester, work with collection events by timer
   if(!this.IsTester())
     {
   //--- Timer of the collections of historical orders and deals, as well as of market orders and positions
      int index=this.CounterIndex(COLLECTION_ORD_COUNTER_ID);
      CTimerCounter* cnt1=this.m_list_counters.At(index);
      if(cnt1!=NULL)
        {
         //--- If unpaused, work with the order, deal and position collections events
         if(cnt1.IsTimeDone())
            this.TradeEventsControl();
        }
   //--- Account collection timer
      index=this.CounterIndex(COLLECTION_ACC_COUNTER_ID);
      CTimerCounter* cnt2=this.m_list_counters.At(index);
      if(cnt2!=NULL)
        {
         //--- If unpaused, work with the account collection events
         if(cnt2.IsTimeDone())
            this.AccountEventsControl();
        }
   //--- Timer 1 of the symbol collection (updating symbol quote data in the collection)
      index=this.CounterIndex(COLLECTION_SYM_COUNTER_ID1);
      CTimerCounter* cnt3=this.m_list_counters.At(index);
      if(cnt3!=NULL)
        {
         //--- If the pause is over, update quote data of all symbols in the collection
         if(cnt3.IsTimeDone())
            this.m_symbols.RefreshRates();
        }
   //--- Timer 2 of the symbol collection (updating all data of all symbols in the collection and tracking symbl and symbol search events in the market watch window)
      index=this.CounterIndex(COLLECTION_SYM_COUNTER_ID2);
      CTimerCounter* cnt4=this.m_list_counters.At(index);
      if(cnt4!=NULL)
        {
         //--- If the pause is over
         if(cnt4.IsTimeDone())
           {
            //--- update data and work with events of all symbols in the collection
            this.SymbolEventsControl();
            //--- When working with the market watch list, check the market watch window events
            if(this.m_symbols.ModeSymbolsList()==SYMBOLS_MODE_MARKET_WATCH)
               this.MarketWatchEventsControl();
           }
        }
   //--- Trading class timer
      index=this.CounterIndex(COLLECTION_REQ_COUNTER_ID);
      CTimerCounter* cnt5=this.m_list_counters.At(index);
      if(cnt5!=NULL)
        {
         //--- If unpaused, work with the list of pending requests
         if(cnt5.IsTimeDone())
            this.m_trading.OnTimer();
        }
   //--- Timeseries collection timer
      index=this.CounterIndex(COLLECTION_TS_COUNTER_ID);
      CTimerCounter* cnt6=this.m_list_counters.At(index);
      if(cnt6!=NULL)
        {
         //--- If the pause is over, work with the timeseries list (update all except the current one)
         if(cnt6.IsTimeDone())
            this.SeriesRefreshAllExceptCurrent(data_calculate);
        }
        
   //--- Timer of timeseries collection of indicator buffer data
      index=this.CounterIndex(COLLECTION_IND_TS_COUNTER_ID);
      CTimerCounter* cnt7=this.m_list_counters.At(index);
      if(cnt7!=NULL)
        {
         //--- If the pause is over, work with the timeseries list of indicator data (update all except for the current one)
         if(cnt7.IsTimeDone()) 
            this.IndicatorSeriesRefreshAll();
        }
   //--- Tick series collection timer
      index=this.CounterIndex(COLLECTION_TICKS_COUNTER_ID);
      CTimerCounter* cnt8=this.m_list_counters.At(index);
      if(cnt8!=NULL)
        {
         //--- If the pause is over, work with the tick series list (update all except the current one)
         if(cnt8.IsTimeDone())
            this.TickSeriesRefreshAllExceptCurrent();
        }
   //--- Chart collection timer
      index=this.CounterIndex(COLLECTION_CHARTS_COUNTER_ID);
      CTimerCounter* cnt9=this.m_list_counters.At(index);
      if(cnt9!=NULL)
        {
         //--- If unpaused, work with the chart list
         if(cnt9.IsTimeDone())
            this.ChartsRefreshAll();
        }
        
   //--- Graphical objects collection timer
      index=this.CounterIndex(COLLECTION_GRAPH_OBJ_COUNTER_ID);
      CTimerCounter* cnt10=this.m_list_counters.At(index);
      if(cnt10!=NULL)
        {
         //--- If unpaused, work with the list of graphical objects
         if(cnt10.IsTimeDone())
            this.GraphObjEventsControl();
        }
        
     }
//--- If this is a tester, work with collection events by tick
   else
     {
      //--- work with events of collections of orders, deals and positions by tick
      this.TradeEventsControl();
      //--- work with events of collections of accounts by tick
      this.AccountEventsControl();
      //--- update quote data of all collection symbols by tick
      this.m_symbols.RefreshRates();
      //--- work with events of all symbols in the collection by tick
      this.SymbolEventsControl();
      //--- work with the list of pending orders by tick
      this.m_trading.OnTimer();
      //--- work with the timeseries list by tick
      this.SeriesRefresh(data_calculate);
      //--- work with the timeseries list of indicator buffers by tick
      this.IndicatorSeriesRefreshAll();
      //--- work with the list of tick series by tick
      this.TickSeriesRefreshAll();
      //--- work with the list of graphical objects by tick
      this.GraphObjEventsControl();
     }
  }
//+------------------------------------------------------------------+

クラス本体の外で、グラフィカルオブジェクトイベントを確認するメソッドを実装します。

//+------------------------------------------------------------------+
//| Check the events of graphical objects                            |
//+------------------------------------------------------------------+
void CEngine::GraphObjEventsControl(void)
  {
//--- Check the changes in the list of graphical objects and set the flag of their events
   this.m_graph_objects.Refresh();
   this.m_is_graph_obj_event=this.m_graph_objects.IsEvent();
//--- If there are changes in the list of graphical objects
   if(this.m_is_graph_obj_event)
     {
      Print(DFUN,"Graph obj is event. NewObjects: ",m_graph_objects.NewObjects());
      //--- Get the last event of the graphical object property change
      // ...
     }
  }
//+------------------------------------------------------------------+

ここでは、開いているすべてのターミナルチャートを更新するメソッドを呼び出すだけです

強調表示された文字列以降のすべてのメソッド文字列はまだ処理されていません。適切な機能は、今後の記事で実装されます。その間、グラフィカルオブジェクトコレクションクラスのRefresh()メソッドは、上記で検討したグラフィカルオブジェクト管理オブジェクトの適切なRefresh()メソッドを呼び出すことにより、すべてのチャートイベントを検索するメソッドを交互に呼び出します。このメソッド(開いているチャートごとに一意のメソッド)は、操作ログエントリを介して適切なチャート上のグラフィカルオブジェクトの数を変更することを通知します。この動作をテストしてみましょう。


検証

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

ここで、変更を少しだけ加える必要があります。

テスターの外部で作業が実行される場合にライブラリタイマーを呼び出すOnTimer()ハンドラを追加します

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- Launch the library timer (only not in the tester)
   if(!MQLInfoInteger(MQL_TESTER))
      engine.OnTimer(rates_data);
  }
//+------------------------------------------------------------------+

OnChartEvent()ハンドラで、Ctrlキーが押された場合にマウスの右ボタンを使用してコンテキストメニューを呼び出すことを禁止します。この場合、 バータイプの説明を含むバーオブジェクト(これは前の記事で行いました)と作成したオブジェクトの幅をわずかに広くして、長いバーの説明(「実体がゼロのローソク足」)に合うようにします。

//+------------------------------------------------------------------+
//| 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();
           }
         //--- Redraw the chart
         ChartRedraw();
        }
     }
  }
//+------------------------------------------------------------------+

EAの改善はこれですべてです。

銘柄チャート(複数の開いているチャートがあるはずです)で起動し、各チャートにグラフィカルオブジェクトを追加すると、操作ログに適切なメッセージが表示されます。次に、各チャートで[削除]をクリックして、強調表示されているすべてのグラフィカルオブジェクトを削除します。適切なメッセージが操作ログに再度表示されます。



次の段階

次の記事では、グラフィカルオブジェクトコレクションの改良を続けます。

すべてのグラフィカルオブジェクトの準備ができているわけではありません。これにより、オブジェクトへのポインタをコレクションリストに格納してさらに開発する必要があるため、グラフィカルオブジェクトコレクションの作成がさらに合理的になります。コレクションを処理した直後にポインタを実装します。

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

目次に戻る

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

DoEasyライブラリのグラフィックス(第73部): グラフィック要素のフォームオブジェクト
DoEasyライブラリのグラフィックス(第74部): CCanvasクラスを使用した基本的グラフィック要素
DoEasyライブラリのグラフィックス(第75部): 基本的なグラフィック要素でプリミティブとテキストを処理するメソッド
DoEasyライブラリのグラフィックス(第76部): フォームオブジェクトと事前定義されたカラースキーム
DoEasyライブラリのグラフィックス(第77部): 影オブジェクトクラス
DoEasyライブラリのグラフィックス(第78部): ライブラリのアニメーションの原則イメージスライス
DoEasyライブラリのグラフィックス(第79部): 「アニメーションフレーム」オブジェクトクラスとその子孫オブジェクト
DoEasyライブラリのグラフィックス(第80部): 「幾何学的アニメーションフレーム」オブジェクトクラス
DoEasyライブラリのグラフィックス(第81部): ライブラリオブジェクトへのグラフィックの統合

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/9850

添付されたファイル |
MQL5.zip (4047.49 KB)
より優れたプログラマー(第04部): より速い開発者になる方法 より優れたプログラマー(第04部): より速い開発者になる方法
すべての開発者は、コードをより速く書くことを望んでいます。より速く効果的にコードを書けることは、少数の人々だけが生まれつき持っているような特別な能力ではありません。これは、コーディングの経験年数に関係なく、すべてのコーダーが習得できるスキルです。
より優れたプログラマー(第03部): MQL5プログラマーとして成功するためにあきらめなければいけない5つのこと より優れたプログラマー(第03部): MQL5プログラマーとして成功するためにあきらめなければいけない5つのこと
この記事は、プログラミングのキャリアを向上させたい人にとって必読です。本連載は、どんなに経験が豊富な読者でも最高のプログラマーになれることを目的としています。議論されたアイデアは、MQL5プログラミングの初心者だけでなくプロにも役立ちます。
DoEasyライブラリのグラフィックス(第83部): 抽象標準グラフィカルオブジェクトのクラス DoEasyライブラリのグラフィックス(第83部): 抽象標準グラフィカルオブジェクトのクラス
本稿では、抽象グラフィカルオブジェクトのクラスを作成します。このオブジェクトは、標準のグラフィカルオブジェクトのクラスを作成するための基礎として機能します。グラフィカルオブジェクトには複数のプロパティがあるため、抽象グラフィカルオブジェクトクラスを実際に作成する前に、多くの準備作業が必要です。この作業には、ライブラリ列挙型のプロパティの設定が含まれます。
DoEasyライブラリのグラフィックス(第81部): ライブラリオブジェクトへのグラフィックの統合 DoEasyライブラリのグラフィックス(第81部): ライブラリオブジェクトへのグラフィックの統合
すでに作成されたオブジェクトを以前に作成されたライブラリオブジェクトに統合する時が来ました。最終的には各ライブラリオブジェクトに独自のグラフィカルオブジェクトが付与されるようになり、ユーザーはプログラムを操作できるようになります。