English Русский 中文 Español Deutsch Português
preview
DoEasy - コントロール(第7部):テキストラベルコントロール

DoEasy - コントロール(第7部):テキストラベルコントロール

MetaTrader 5 | 31 8月 2022, 10:10
230 0
Artyom Trishkin
Artyom Trishkin

内容


概念

プログラムは皆、画面に情報を表示します。MS Visual Studioでは、他の要素に加えてテキストラベルコントロールを使用します。MetaTrader 5は、「テキストラベル」 グラフィカルオブジェクトも備えています。さらに、ターミナルでプログラムGUIを作成するためのすべてのグラフィック要素にはキャンバスにテキストを表示する機能がありますが、これが不便な場合もあります。そのため、今回の記事では、独立した「テキストラベル」コントロールを作成します。

このようなオブジェクトはコンテナをどこにでも配置できますが、独自の機能はMS Visual Studioテキストラベルの機能を繰り返します。表示されるテキストのフォントパラメータは設定できます。テキストは、「テキストラベル」オブジェクトの境界内に配置されます。次に、オブジェクトのサイズは、指定された幅と高さに設定するか、ラベルに使用されるフォントのサイズに自動的に調整することができます。さらに、オブジェクトフレーム(「テキストラベル」オブジェクト全体をその境界に沿って囲む長方形)も使用できるようになります。オブジェクトフレームは、平面または3次元のいずれかです。プログラムのGUI要素内に適切なデザインでテキストを表示する十分な機会が与えられます。

すべての新しいオブジェクトパラメータをどこかに表示するため、または目的のパラメータでオブジェクトを選択できるようにするために、「テキストラベル」オブジェクトで使用されるすべてのプロパティをライブラリのグラフィック要素のプロパティの整数、実数、文字列の列挙に追加します。ライブラリオブジェクトの迅速な検索、選択、および並べ替えのために提供される機能を十分な柔軟性をもって使用できるため、すべてのライブラリオブジェクトでこの概念に従うようにしています。


ライブラリクラスの改善

まず、新しいテキストメッセージをライブラリに追加します。

\MQL5\Include\DoEasy\Data.mqhに、ライブラリの新しいメッセージインデックスを追加します

   MSG_GRAPH_ELEMENT_TYPE_WF_PANEL,                   // Panel control
   MSG_GRAPH_ELEMENT_TYPE_WF_LABEL,                   // Label control
   MSG_GRAPH_OBJ_BELONG_PROGRAM,                      // Graphical object belongs to a program

...

//--- CPanel
   MSG_PANEL_OBJECT_ERR_FAILED_CREATE_UNDERLAY_OBJ,   // Failed to create the underlay object
   MSG_PANEL_OBJECT_ERR_OBJ_MUST_BE_WFBASE,           // Error. The created object should be of WinForms Base type or be derived from it

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

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

   {"Элемент управления \"Panel\"","Control element \"Panel\""},
   {"Элемент управления \"Label\"","Control element \"Label\""},
   {"Графический объект принадлежит программе","The graphic object belongs to the program"},

...

//--- CPanel
   {"Не удалось создать объект-подложку","Failed to create underlay object"},
   {"Ошибка. Создаваемый объект должен иметь тип WinForms Base или быть его наследником","Error. The object being created must be of type WinForms Base or be derived from it"},
   
  };
//+---------------------------------------------------------------------+


「テキストラベル」コントロールのテキストの色に加えて、その不透明度も使用します。これにより、たとえば、プログラムのGUI要素でテキストをスムーズに表示/非表示させる効果を作成できます。さらに、テキストラベルオブジェクトによって表示されるテキストと、グラフィック要素のプロパティに追加していないWinFormsオブジェクトを構築するために必要なその他のパラメータを設定する必要があります。ただし、それらは既に作成されています。

\MQL5\Include\DoEasy\Defines.mqhのキャンバスパラメータのブロックで、コントロールのデフォルトのテキスト不透明度を指定する新しいマクロ置換を追加 します

//--- Canvas parameters
#define PAUSE_FOR_CANV_UPDATE          (16)                       // Canvas update frequency
#define CLR_CANV_NULL                  (0x00FFFFFF)               // Zero for the canvas with the alpha channel
#define CLR_DEF_FORE_COLOR             (C'0x2D,0x43,0x48')        // Default color for texts of objects on canvas
#define CLR_DEF_FORE_COLOR_OPACITY     (255)                      // Default color non-transparency for canvas object texts
#define CLR_DEF_OPACITY                (200)                      // Default color non-transparency for canvas objects
#define CLR_DEF_SHADOW_COLOR           (C'0x6B,0x6B,0x6B')        // Default color for canvas object shadows
#define CLR_DEF_SHADOW_OPACITY         (127)                      // Default color non-transparency for canvas objects
#define DEF_SHADOW_BLUR                (4)                        // Default blur for canvas object shadows
#define DEF_FONT                       ("Calibri")                // Default font
#define DEF_FONT_SIZE                  (8)                        // Default font size
#define OUTER_AREA_SIZE                (16)                       // Size of one side of the outer area around the form workspace
#define DEF_FRAME_WIDTH_SIZE           (3)                        // Default form/panel/window frame width
//--- Graphical object parameters


ライブラリオブジェクトタイプのリストにテキストラベルタイプを追加します

//+------------------------------------------------------------------+
//| 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_GFORM_CONTROL,                                  // "Form for managing pivot points of graphical object" object type
   OBJECT_DE_TYPE_GSHADOW,                                        // Shadow object type
   //--- WinForms
   OBJECT_DE_TYPE_GWF_BASE,                                       // WinForms Base object type (base abstract WinForms object)
   OBJECT_DE_TYPE_GWF_PANEL,                                      // WinForms Panel object type
   OBJECT_DE_TYPE_GWF_LABEL,                                      // WinForms Label object type
//--- Animation


グラフィック要素タイプのリストにテキストラベル要素を追加します

//+------------------------------------------------------------------+
//| The list of graphical element types                              |
//+------------------------------------------------------------------+
enum ENUM_GRAPH_ELEMENT_TYPE
  {
   GRAPH_ELEMENT_TYPE_STANDARD,                       // Standard graphical object
   GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED,              // Extended standard graphical object
   GRAPH_ELEMENT_TYPE_SHADOW_OBJ,                     // Shadow object
   GRAPH_ELEMENT_TYPE_ELEMENT,                        // Element
   GRAPH_ELEMENT_TYPE_FORM,                           // Form
   GRAPH_ELEMENT_TYPE_WINDOW,                         // Window
   //--- WinForms
   GRAPH_ELEMENT_TYPE_WF_UNDERLAY,                    // Panel object underlay
   GRAPH_ELEMENT_TYPE_WF_BASE,                        // Windows Forms Base
   GRAPH_ELEMENT_TYPE_WF_PANEL,                       // Windows Forms Panel
   GRAPH_ELEMENT_TYPE_WF_LABEL,                       // Windows Forms Label
  };
//+------------------------------------------------------------------+


キャンバス上のグラフィカル要素の整数プロパティのリストに、すべての新しい定数(以前にWimFormsオブジェクトに追加されたが列挙には配置されなかったもの新しいもの の両方)を追加します。

//+------------------------------------------------------------------+
//| Integer properties of the graphical element on the canvas        |
//+------------------------------------------------------------------+
enum ENUM_CANV_ELEMENT_PROP_INTEGER
  {
   //--- ...
   
   CANV_ELEMENT_PROP_FORE_COLOR,                      // Default text color for all control objects
   CANV_ELEMENT_PROP_FORE_COLOR_OPACITY,              // Default text color opacity for all control objects
   CANV_ELEMENT_PROP_BOLD_TYPE,                       // Font width type
   CANV_ELEMENT_PROP_BORDER_STYLE,                    // Control frame style
   CANV_ELEMENT_PROP_AUTOSIZE,                        // Flag of the element auto resizing depending on the content
   CANV_ELEMENT_PROP_AUTOSIZE_MODE,                   // Mode of the element auto resizing depending on the content
   CANV_ELEMENT_PROP_AUTOSCROLL,                      // Auto scrollbar flag
   CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_W,             // Width of the field inside the element during auto scrolling
   CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_H,             // Height of the field inside the element during auto scrolling
   CANV_ELEMENT_PROP_DOCK_MODE,                       // Mode of binding control borders to the container
   CANV_ELEMENT_PROP_MARGIN_TOP,                      // Top margin between the fields of this and another control
   
   //--- ...

   CANV_ELEMENT_PROP_PADDING_RIGHT,                   // Right margin inside the control
   CANV_ELEMENT_PROP_TEXT_ALIGN,                      // Text position within text label boundaries
  };
#define CANV_ELEMENT_PROP_INTEGER_TOTAL (44)          // Total number of integer properties
#define CANV_ELEMENT_PROP_INTEGER_SKIP  (0)           // Number of integer properties not used in sorting
//+------------------------------------------------------------------+

整数プロパティの総数を38から44に増やします


キャンバスに基づいたグラフィカル要素の文字列プロパティのリストに新しい「グラフィカル要素テキスト」プロパティを追加し、文字列プロパティの総数を2から3に増やします

//+------------------------------------------------------------------+
//| String properties of the graphical element on the canvas         |
//+------------------------------------------------------------------+
enum ENUM_CANV_ELEMENT_PROP_STRING
  {
   CANV_ELEMENT_PROP_NAME_OBJ = (CANV_ELEMENT_PROP_INTEGER_TOTAL+CANV_ELEMENT_PROP_DOUBLE_TOTAL), // Graphical element object name
   CANV_ELEMENT_PROP_NAME_RES,                        // Graphical resource name
   CANV_ELEMENT_PROP_TEXT,                            // Graphical element text
  };
#define CANV_ELEMENT_PROP_STRING_TOTAL  (3)           // Total number of string properties
//+------------------------------------------------------------------+


キャンバス上のグラフィック要素を並べ替えるための基準の列挙に新しいプロパティによる並べ替えを追加します

//+------------------------------------------------------------------+
//| 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_FORE_COLOR,                   // Sort by default text color for all control objects
   SORT_BY_CANV_ELEMENT_FORE_COLOR_OPACITY,           // Sort by default text color opacity for all control objects
   SORT_BY_CANV_ELEMENT_BOLD_TYPE,                    // Sort by font width type
   SORT_BY_CANV_ELEMENT_BORDER_STYLE,                 // Sort by control frame style
   SORT_BY_CANV_ELEMENT_AUTOSIZE,                     // Sort by the flag of the control auto resizing depending on the content
   SORT_BY_CANV_ELEMENT_AUTOSIZE_MODE,                // Sort by the mode of the control auto resizing depending on the content
   SORT_BY_CANV_ELEMENT_AUTOSCROLL,                   // Sort by auto scrollbar flag
   SORT_BY_CANV_ELEMENT_AUTOSCROLL_MARGIN_W,          // Sort by width of the field inside the element during auto scrolling
   SORT_BY_CANV_ELEMENT_AUTOSCROLL_MARGIN_H,          // Sort by height of the field inside the element during auto scrolling
   SORT_BY_CANV_ELEMENT_DOCK_MODE,                    // Sort by mode of binding control borders to the container
   
   //--- ...

   SORT_BY_CANV_ELEMENT_PADDING_RIGHT,                // Sort by right margin inside the control
   SORT_BY_CANV_ELEMENT_TEXT_ALIGN,                   // Sort by text position within text label boundaries
//--- 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
   SORT_BY_CANV_ELEMENT_TEXT,                         // Sort by graphical element text
  };
//+------------------------------------------------------------------+

これで、すべてのグラフィック要素を新しいプロパティで選択して並べ替えることができるようになります。


CWinFormBaseクラスは、ライブラリのすべてのWinFormsオブジェクトの基本クラスとして機能します。このクラスは、マウス操作を特徴とするフォームオブジェクトから派生しています。継承されたクラスでそのprivate変数のいくつかが必要になります。private変数とメソッドは、それらが宣言されているクラスでのみで可視性があるため、継承されたクラスで使用できるように、それらをprivateセクションからprotectedセクションに移動する必要があります。

\MQL5\Include\DoEasy\Objects\Graph\Form.mqhフォームオブジェクトファイルでprivateセクションから変数を

//+------------------------------------------------------------------+
//| Form object class                                                |
//+------------------------------------------------------------------+
class CForm : public CGCnvElement
  {
private:
   CArrayObj         m_list_elements;                          // List of attached elements
   CAnimations      *m_animations;                             // Pointer to the animation object
   CShadowObj       *m_shadow_obj;                             // Pointer to the shadow object
   CMouseState       m_mouse;                                  // "Mouse status" class object
   ENUM_MOUSE_FORM_STATE m_mouse_form_state;                   // Mouse status relative to the form
   ushort            m_mouse_state_flags;                      // Mouse status flags
   color             m_color_frame;                            // Form frame color
   int               m_offset_x;                               // Offset of the X coordinate relative to the cursor
   int               m_offset_y;                               // Offset of the Y coordinate relative to the cursor
   int               m_init_x;                                 // Newly created form X coordinate
   int               m_init_y;                                 // Newly created form Y coordinate
   int               m_init_w;                                 // Newly created form width
   int               m_init_h;                                 // Newly created form height

//--- Reset the array size of (1) text, (2) rectangular and (3) geometric animation frames

protectedセクションに移動し、継承されたクラスで再定義できるようにいくつかのメソッドを仮想化します

protected:
   CArrayObj         m_list_elements;                          // List of attached elements
   CAnimations      *m_animations;                             // Pointer to the animation object
   CShadowObj       *m_shadow_obj;                             // Pointer to the shadow object
   CMouseState       m_mouse;                                  // "Mouse status" class object
   ENUM_MOUSE_FORM_STATE m_mouse_form_state;                   // Mouse status relative to the form
   ushort            m_mouse_state_flags;                      // Mouse status flags
   color             m_color_frame;                            // Form frame color
   int               m_offset_x;                               // Offset of the X coordinate relative to the cursor
   int               m_offset_y;                               // Offset of the Y coordinate relative to the cursor
   CArrayObj         m_list_tmp;                               // List for storing the pointers
   int               m_frame_width_left;                       // Form frame width to the left
   int               m_frame_width_right;                      // Form frame width to the right
   int               m_frame_width_top;                        // Form frame width at the top
   int               m_frame_width_bottom;                     // Form frame width at the bottom
   int               m_init_x;                                 // Newly created form X coordinate
   int               m_init_y;                                 // Newly created form Y coordinate
   int               m_init_w;                                 // Newly created form width
   int               m_init_h;                                 // Newly created form height
//--- Initialize the variables
   virtual void      Initialize(void);
   void              Deinitialize(void);
//--- Create a shadow object
   void              CreateShadowObj(const color colour,const uchar opacity);
//--- Return the name of the dependent object
   string            CreateNameDependentObject(const string base_name)  const
                       { return ::StringSubstr(this.NameObj(),::StringLen(::MQLInfoString(MQL_PROGRAM_NAME))+1)+"_"+base_name;   }
//--- Update coordinates of bound objects
   virtual bool      MoveDependentObj(const int x,const int y,const bool redraw=false);
//--- Create a new bound element and add it to the list of bound objects
   virtual CGCnvElement *CreateAndAddNewElement(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                                                CGCnvElement *main,
                                                const int x,
                                                const int y,
                                                const int w,
                                                const int h,
                                                const color colour,
                                                const uchar opacity,
                                                const bool activity);
   
public:


WinFormsオブジェクトのライブラリオブジェクトを構築する一般的な概念を使用してWinFormsオブジェクトパラメータをグラフィカル要素のプロパティに追加するため、オブジェクトプロパティを格納するためのCWinFormBase基本クラス変数を削除し、これらのプロパティを設定および取得するためのすべてのメソッドを書き直す必要があります。

\MQL5\Include\DoEasy\Objects\Graph\WForms\WinFormBase.mqh不要となった変数をprotectedセクションから削除します

//+------------------------------------------------------------------+
//| Form object class                                                |
//+------------------------------------------------------------------+
class CWinFormBase : public CForm
  {
protected:
   color             m_fore_color;                                   // Default text color for all control objects
   ENUM_FW_TYPE      m_bold_type;                                    // Font width type
   ENUM_FRAME_STYLE  m_border_style;                                 // Control frame style
   bool              m_autosize;                                     // Flag of the element auto resizing depending on the content
   ENUM_CANV_ELEMENT_DOCK_MODE m_dock_mode;                          // Mode of binding control borders to the container
   int               m_margin[4];                                    // Array of gaps of all sides between the fields of the current and adjacent controls
   int               m_padding[4];                                   // Array of gaps of all sides inside controls

private:


クラスのpublicセクションでプロパティを受け取るメソッドとプロパティをオブジェクトプロパティ列挙に設定するメソッドを書き換え、 「テキストラベル」オブジェクトテキストを処理するための新しいメソッドWinFormsオブジェクトの一般的なプロパティを設定および取得するための新しいメソッドを追加します。

public:
//--- ...
   
//--- ...

//--- Constructors
                     CWinFormBase(const long chart_id,
                                  const int subwindow,
                                  const string name,
                                  const int x,
                                  const int y,
                                  const int w,
                                  const int h);
                     CWinFormBase(const string name) : CForm(::ChartID(),0,name,0,0,0,0)
                       {
                        this.m_type=OBJECT_DE_TYPE_GWF_BASE; 
                       }
                       
//--- (1) Set and (2) return the default text color of all panel objects
   void              SetForeColor(const color clr)                   { this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR,clr);                               }
   color             ForeColor(void)                           const { return (color)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR);                     }
//--- (1) Set and (2) return the default text color opacity of all panel objects
   void              SetForeColorOpacity(const uchar value)          { this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_OPACITY,value);                     }
   uchar             ForeColorOpacity(void)                    const { return (uchar)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR_OPACITY);             }
//--- (1) Set and (2) return the element text
   virtual void      SetText(const string text)                      { this.SetProperty(CANV_ELEMENT_PROP_TEXT,text);                                    }
   string            Text(void)                                const { return this.GetProperty(CANV_ELEMENT_PROP_TEXT);                                  }
//--- (1) Set and (2) return the element text location angle (alignment type)
   void              SetTextAlign(const ENUM_ANCHOR_POINT anchor)    { this.SetProperty(CANV_ELEMENT_PROP_TEXT_ALIGN,anchor);                            }
   ENUM_ANCHOR_POINT TextAlign(void)                           const { return (ENUM_ANCHOR_POINT)this.GetProperty(CANV_ELEMENT_PROP_TEXT_ALIGN);         }
//--- (1) Set and (2) return the Bold font flag
   void              SetBold(const bool flag);
   bool              Bold(void);
//--- (1) Set and (2) return the Italic font flag
   void              SetItalic(const bool flag);
   bool              Italic(void);
//--- (1) Set and (2) return the Strikeout font flag
   void              SetStrikeout(const bool flag);
   bool              Strikeout(void);
//--- (1) Set and (2) return the Underline font flag
   void              SetUnderline(const bool flag);
   bool              Underline(void);
//--- (1) Set and (2) return the font style
   void              SetFontDrawStyle(ENUM_FONT_STYLE style);
   ENUM_FONT_STYLE   FontDrawStyle(void);
//--- (1) Set and (2) return the font width type
   void              SetFontBoldType(ENUM_FW_TYPE type);
   ENUM_FW_TYPE      FontBoldType(void)                        const { return (ENUM_FW_TYPE)this.GetProperty(CANV_ELEMENT_PROP_BOLD_TYPE);               }
//--- (1) Set and (2) return the frame style
   void              SetBorderStyle(const ENUM_FRAME_STYLE style)    { this.SetProperty(CANV_ELEMENT_PROP_BORDER_STYLE,style);                           }
   ENUM_FRAME_STYLE  BorderStyle(void)                         const { return (ENUM_FRAME_STYLE)this.GetProperty(CANV_ELEMENT_PROP_BORDER_STYLE);        }

//--- (1) Set and (2) return the flag of the element auto resizing depending on the content
   virtual void      SetAutoSize(const bool flag,const bool redraw)  { this.SetProperty(CANV_ELEMENT_PROP_AUTOSIZE,flag);                                }
   bool              AutoSize(void)                                  { return (bool)this.GetProperty(CANV_ELEMENT_PROP_AUTOSIZE);                        }
//--- (1) Set and (2) return the auto scrollbar flag
   virtual void      SetAutoScroll(const bool flag,const bool redraw){ this.SetProperty(CANV_ELEMENT_PROP_AUTOSCROLL,flag);                              }
   bool              AutoScroll(void)                                { return (bool)this.GetProperty(CANV_ELEMENT_PROP_AUTOSCROLL);                      }
   
//--- (1) Set and (2) return the mode of binding element borders to the container
   virtual void      SetDockMode(const ENUM_CANV_ELEMENT_DOCK_MODE mode,const bool redraw)
                       {
                        this.SetProperty(CANV_ELEMENT_PROP_DOCK_MODE,mode);
                       }
   ENUM_CANV_ELEMENT_DOCK_MODE DockMode(void)                  const { return (ENUM_CANV_ELEMENT_DOCK_MODE)this.GetProperty(CANV_ELEMENT_PROP_DOCK_MODE);}
   
//--- Set the gap (1) to the left, (2) at the top, (3) to the right, (4) at the bottom and (5) on all sides between the fields of this and another control
   void              SetMarginLeft(const int value)                  { this.SetProperty(CANV_ELEMENT_PROP_MARGIN_LEFT,value);                            }
   void              SetMarginTop(const int value)                   { this.SetProperty(CANV_ELEMENT_PROP_MARGIN_TOP,value);                             }
   void              SetMarginRight(const int value)                 { this.SetProperty(CANV_ELEMENT_PROP_MARGIN_RIGHT,value);                           }
   void              SetMarginBottom(const int value)                { this.SetProperty(CANV_ELEMENT_PROP_MARGIN_BOTTOM,value);                          }
   void              SetMarginAll(const int value)
                       {
                        this.SetMarginLeft(value); this.SetMarginTop(value); this.SetMarginRight(value); this.SetMarginBottom(value);
                       }
   void              SetMargin(const int left,const int top,const int right,const int bottom)
                       {
                        this.SetMarginLeft(left); this.SetMarginTop(top); this.SetMarginRight(right); this.SetMarginBottom(bottom);
                       }
//--- Return the gap (1) to the left, (2) at the top, (3) to the right and (4) at the bottom between the fields of this and another control
   int               MarginLeft(void)                          const { return (int)this.GetProperty(CANV_ELEMENT_PROP_MARGIN_LEFT);                      }
   int               MarginTop(void)                           const { return (int)this.GetProperty(CANV_ELEMENT_PROP_MARGIN_TOP);                       }
   int               MarginRight(void)                         const { return (int)this.GetProperty(CANV_ELEMENT_PROP_MARGIN_RIGHT);                     }
   int               MarginBottom(void)                        const { return (int)this.GetProperty(CANV_ELEMENT_PROP_MARGIN_BOTTOM);                    }

//--- Set the gap (1) to the left, (2) at the top, (3) to the right, (4) at the bottom and (5) on all sides inside the control
   virtual void      SetPaddingLeft(const uint value)
                       {
                        int padding=((int)value<this.m_frame_width_left ? this.m_frame_width_left : (int)value);
                        this.SetProperty(CANV_ELEMENT_PROP_PADDING_LEFT,padding);
                       }
   virtual void      SetPaddingTop(const uint value)
                       {
                        int padding=((int)value<this.m_frame_width_top ? this.m_frame_width_top : (int)value);
                        this.SetProperty(CANV_ELEMENT_PROP_PADDING_TOP,padding);
                       }
   virtual void      SetPaddingRight(const uint value)
                       {
                        int padding=((int)value<this.m_frame_width_right ? this.m_frame_width_right : (int)value);
                        this.SetProperty(CANV_ELEMENT_PROP_PADDING_RIGHT,padding);
                       }
   virtual void      SetPaddingBottom(const uint value)
                       {
                        int padding=((int)value<this.m_frame_width_bottom ? this.m_frame_width_bottom : (int)value);
                        this.SetProperty(CANV_ELEMENT_PROP_PADDING_BOTTOM,padding);
                       }
   virtual void      SetPaddingAll(const uint value)
                       {
                        this.SetPaddingLeft(value); this.SetPaddingTop(value); this.SetPaddingRight(value); this.SetPaddingBottom(value);
                       }
   virtual void      SetPadding(const int left,const int top,const int right,const int bottom)
                       {
                        this.SetPaddingLeft(left); this.SetPaddingTop(top); this.SetPaddingRight(right); this.SetPaddingBottom(bottom);
                       }
   
//--- Set the width of the element frame (1) to the left, (2) at the top, (3) to the right and (4) at the bottom
   virtual void      SetFrameWidthLeft(const uint value)             { this.m_frame_width_left=(int)value;                                               }
   virtual void      SetFrameWidthTop(const uint value)              { this.m_frame_width_top=(int)value;                                                }
   virtual void      SetFrameWidthRight(const uint value)            { this.m_frame_width_right=(int)value;                                              }
   virtual void      SetFrameWidthBottom(const uint value)           { this.m_frame_width_bottom=(int)value;                                             }
   virtual void      SetFrameWidthAll(const uint value)
                       {
                        this.SetFrameWidthLeft(value); this.SetFrameWidthTop(value); this.SetFrameWidthRight(value); this.SetFrameWidthBottom(value);
                       }
   virtual void      SetFrameWidth(const uint left,const uint top,const uint right,const uint bottom)
                       {
                        this.SetFrameWidthLeft(left); this.SetFrameWidthTop(top); this.SetFrameWidthRight(right); this.SetFrameWidthBottom(bottom);
                       }
   
//--- Return the width of the element frame (1) to the left, (2) at the top, (3) to the right and (4) at the bottom
   int               FrameWidthLeft(void)                      const { return this.m_frame_width_left;                                                   }
   int               FrameWidthTop(void)                       const { return this.m_frame_width_top;                                                    }
   int               FrameWidthRight(void)                     const { return this.m_frame_width_right;                                                  }
   int               FrameWidthBottom(void)                    const { return this.m_frame_width_bottom;                                                 }
   
//--- Return the gap (1) to the left, (2) at the top, (3) to the right and (4) at the bottom between the fields inside the control
   int               PaddingLeft(void)                         const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PADDING_LEFT);                     }
   int               PaddingTop(void)                          const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PADDING_TOP);                      }
   int               PaddingRight(void)                        const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PADDING_RIGHT);                    }
   int               PaddingBottom(void)                       const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PADDING_BOTTOM);                   }
   
  };
//+------------------------------------------------------------------+

すべての書き直されたメソッドでは、最初の記事のライブラリオブジェクトの構築の概念で最初に説明したように、変数ではなくSetProperty()メソッドとGetProperty()メソッドを使用してオブジェクトプロパティの列挙で値を書き込んで取得するようになりました。

クラスコンストラクタで、作成されたオブジェクトのテキストを「空の文字列」として設定 し、Defines.mqhで設定されているテキストの色不透明度のデフォルト値を設定します。

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CWinFormBase::CWinFormBase(const long chart_id,
                           const int subwindow,
                           const string name,
                           const int x,
                           const int y,
                           const int w,
                           const int h) : CForm(chart_id,subwindow,name,x,y,w,h)
  {
//--- Set the graphical element and library object types as a base WinForms object
   CGBaseObj::SetTypeElement(GRAPH_ELEMENT_TYPE_WF_BASE);
   CGCnvElement::SetProperty(CANV_ELEMENT_PROP_TYPE,GRAPH_ELEMENT_TYPE_WF_BASE);
   this.m_type=OBJECT_DE_TYPE_GWF_BASE; 
//--- Initialize all variables
   this.SetText("");
   this.SetForeColor(CLR_DEF_FORE_COLOR);
   this.SetForeColorOpacity(CLR_DEF_FORE_COLOR_OPACITY);
   this.SetFontBoldType(FW_TYPE_NORMAL);
   this.SetMarginAll(0);
   this.SetPaddingAll(0);
   this.SetDockMode(CANV_ELEMENT_DOCK_MODE_NONE,false);
   this.SetBorderStyle(FRAME_STYLE_NONE);
   this.SetAutoSize(false,false);
   CForm::SetCoordXInit(x);
   CForm::SetCoordYInit(y);
   CForm::SetWidthInit(w);
   CForm::SetHeightInit(h);
   this.m_shadow=false;
   this.m_frame_width_right=0;
   this.m_frame_width_left=0;
   this.m_frame_width_top=0;
   this.m_frame_width_bottom=0;
   this.m_gradient_v=true;
   this.m_gradient_c=false;
  }
//+------------------------------------------------------------------+


Boldフォントフラグを設定するメソッドとフォント幅タイプを設定するメソッドでは、変数に値を設定する代わりにオブジェクトプロパティに値を設定します

//+------------------------------------------------------------------+
//| Set the Bold font flag                                           |
//+------------------------------------------------------------------+
void CWinFormBase::SetBold(const bool flag)
  {
   uint flags=this.GetFontFlags();
   if(flag)
     {
      this.SetFontBoldType(FW_TYPE_BOLD);
      CGCnvElement::SetFontFlags(flags | FW_BOLD);
     }
   else
      this.SetFontBoldType(FW_TYPE_NORMAL);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Set the font width type                                          |
//+------------------------------------------------------------------+
void CWinFormBase::SetFontBoldType(ENUM_FW_TYPE type)
  {
   this.SetProperty(CANV_ELEMENT_PROP_BOLD_TYPE,type);
   uint flags=this.GetFontFlags();
   switch(type)
     {
      case FW_TYPE_DONTCARE   : CGCnvElement::SetFontFlags(flags | FW_DONTCARE);    break;
      case FW_TYPE_THIN       : CGCnvElement::SetFontFlags(flags | FW_THIN);        break;
      case FW_TYPE_EXTRALIGHT : CGCnvElement::SetFontFlags(flags | FW_EXTRALIGHT);  break;
      case FW_TYPE_ULTRALIGHT : CGCnvElement::SetFontFlags(flags | FW_ULTRALIGHT);  break;
      case FW_TYPE_LIGHT      : CGCnvElement::SetFontFlags(flags | FW_LIGHT);       break;
      case FW_TYPE_REGULAR    : CGCnvElement::SetFontFlags(flags | FW_REGULAR);     break;
      case FW_TYPE_MEDIUM     : CGCnvElement::SetFontFlags(flags | FW_MEDIUM);      break;
      case FW_TYPE_SEMIBOLD   : CGCnvElement::SetFontFlags(flags | FW_SEMIBOLD);    break;
      case FW_TYPE_DEMIBOLD   : CGCnvElement::SetFontFlags(flags | FW_DEMIBOLD);    break;
      case FW_TYPE_BOLD       : CGCnvElement::SetFontFlags(flags | FW_BOLD);        break;
      case FW_TYPE_EXTRABOLD  : CGCnvElement::SetFontFlags(flags | FW_EXTRABOLD);   break;
      case FW_TYPE_ULTRABOLD  : CGCnvElement::SetFontFlags(flags | FW_ULTRABOLD);   break;
      case FW_TYPE_HEAVY      : CGCnvElement::SetFontFlags(flags | FW_HEAVY);       break;
      case FW_TYPE_BLACK      : CGCnvElement::SetFontFlags(flags | FW_BLACK);       break;
      default                 : CGCnvElement::SetFontFlags(flags | FW_NORMAL);      break;
     }
  }
//+------------------------------------------------------------------+


「テキストラベル」コントロールクラス

\MQL5\Include\DoEasy\Objects\Graph\WForms\Common Controls\で、CLabelクラスの新しいファイル(Label.mqh)を作成します。CWinFormBaseクラスは基本クラスでそのファイルは新しく作成されたクラスのファイルにインクルードされます

//+------------------------------------------------------------------+
//|                                                        Label.mqh |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "..\..\WForms\WinFormBase.mqh"
//+------------------------------------------------------------------+
//| Label object class of WForms controls                            |
//+------------------------------------------------------------------+
class CLabel : public CWinFormBase
  {
  }

クラスのprivate、protect、public各セクションで、クラスメソッドの宣言を追加します。

//+------------------------------------------------------------------+
//| Label object class of WForms controls                            |
//+------------------------------------------------------------------+
class CLabel : public CWinFormBase
  {
private:
//--- Set the element width and height automatically
   void              AutoSetWH(void);
protected:
//--- Initialize the variables
   virtual void      Initialize(void);
   
public:
//--- Clear the element filling it with color and opacity
   virtual void      Erase(const color colour,const uchar opacity,const bool redraw=false);
//--- Clear the element with a gradient fill
   virtual void      Erase(color &colors[],const uchar opacity,const bool vgradient,const bool cycle,const bool redraw=false);
//--- Clear the element completely
   virtual void      Erase(const bool redraw=false);
//--- Redraw the object
   virtual void      Redraw(bool redraw);
//--- Set the element text
   virtual void      SetText(const string text)
                       {
                        CWinFormBase::SetText(text);
                        if(this.AutoSize())
                           this.AutoSetWH();
                       }

//--- Constructors
                     CLabel(const long chart_id,
                            const int subwindow,
                            const string name,
                            const int x,
                            const int y,
                            const int w,
                            const int h);
  };
//+------------------------------------------------------------------+

ご覧のとおり、protectedセクションとpublicセクションでCWinFormBase基本クラスの仮想メソッドを宣言しました。これらのメソッドは、基本メソッドとは少し異なるロジックを持ち、それらはこのクラスで再定義されます。

たとえば、要素テキストを設定するメソッドでは、基本クラスのメソッドが最初に呼び出されます。メソッドに渡された新しい値は、オブジェクトプロパティに設定されます。次に、オブジェクトの自動サイズ変更フラグが設定されている場合、新しいサイズを設定するためのprivateメソッドが呼び出されます。サイズは、以下で検討するオブジェクトキャンバスに表示されるテキストのサイズに対応する必要があります。

//--- Set the element text
   virtual void      SetText(const string text)
                       {
                        CWinFormBase::SetText(text);
                        if(this.AutoSize())
                           this.AutoSetWH();
                       }


クラスにはパラメトリック コンストラクタがあり、既定のコンストラクタとデストラクタは自動的に作成されます。

パラメトリック コンストラクタには、オブジェクトが構築されるチャートIDとそのサブウィンドウ、オブジェクトの名前、座標とサイズが渡されます。

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CLabel::CLabel(const long chart_id,
               const int subwindow,
               const string name,
               const int x,
               const int y,
               const int w,
               const int h) : CWinFormBase(chart_id,subwindow,name,x,y,w,h)
  {
   CGBaseObj::SetTypeElement(GRAPH_ELEMENT_TYPE_WF_LABEL);
   CGCnvElement::SetProperty(CANV_ELEMENT_PROP_TYPE,GRAPH_ELEMENT_TYPE_WF_LABEL);
   this.m_type=OBJECT_DE_TYPE_GWF_LABEL;
   this.SetCoordX(x);
   this.SetCoordY(y);
   this.SetWidth(w);
   this.SetHeight(h);
   this.Initialize();
   if(this.AutoSize())
      this.AutoSetWH();
   this.SetWidthInit(this.Width());
   this.SetHeightInit(this.Height());
   this.SetCoordXInit(x);
   this.SetCoordYInit(y);
   this.Redraw(false);
  }
//+------------------------------------------------------------------+

まず、グラフィカル要素のタイプがすべての親クラスに設定され、オブジェクトのWinFormsラベルライブラリオブジェクトタイプが設定されます
次に、オブジェクトと座標を設定し、ライブラリグラフィック要素の主なパラメータを設定するための仮想メソッドを呼び出します。このメソッドは、同じ基本オブジェクトメソッドとは少し異なるため、クラスで再定義されます。これはあとで考慮します。
オブジェクトの自動サイズ変更フラグがテキストに合わせて設定されている場合は、オブジェクトのサイズを変更するための適切なメソッドを呼び出します(フラグはここでは常に無効になっていますが、後で変更できます)。
サイズ変更後(フラグが設定されている)、オブジェクトの初期サイズと初期座標を設定します
最後にオブジェクト全体を再描画します

以下は、変数を初期化する仮想メソッドです。

//+------------------------------------------------------------------+
//| Initialize the variables                                         |
//+------------------------------------------------------------------+
void CLabel::Initialize(void)
  {
//--- Clear all object lists and set sorted list flags for them
   this.m_list_elements.Clear();
   this.m_list_elements.Sort();
   this.m_list_tmp.Clear();
   this.m_list_tmp.Sort();
//--- Text label has no shadow object
   this.m_shadow_obj=NULL;
   this.m_shadow=false;
//--- The width of the object frame on each side is 1 pixel by default
   this.m_frame_width_right=1;
   this.m_frame_width_left=1;
   this.m_frame_width_top=1;
   this.m_frame_width_bottom=1;
//--- The object does not have a gradient filling (neither vertical, nor horizontal)
   this.m_gradient_v=false;
   this.m_gradient_c=false;
//--- Reset all "working" flags and variables
   this.m_mouse_state_flags=0;
   this.m_offset_x=0;
   this.m_offset_y=0;
   CGCnvElement::SetInteraction(false);
//--- Create an animation object and add it to the list for storing such objects
   this.m_animations=new CAnimations(CGCnvElement::GetObject());
   this.m_list_tmp.Add(this.m_animations);
//--- Set the transparent color for the object background
   this.SetColorBackground(CLR_CANV_NULL);
   this.SetOpacity(0);
//--- Set the default color and text opacity, as well as the absence of the object frame
   this.SetForeColor(CLR_DEF_FORE_COLOR);
   this.SetForeColorOpacity(CLR_DEF_FORE_COLOR_OPACITY);
   this.SetBorderStyle(FRAME_STYLE_NONE);
//--- Set the default text parameters
   this.SetFont(DEF_FONT,DEF_FONT_SIZE);
   this.SetText("");
   this.SetTextAnchor(FRAME_ANCHOR_LEFT_TOP);
   this.SetTextAlign(ANCHOR_LEFT_UPPER);
//--- Set the default object parameters
   this.SetAutoSize(false,false);
   this.SetMargin(3,0,3,0);
   this.SetPaddingAll(0);
   this.SetEnabled(true);
   this.SetVisible(true,false);
  }
//+------------------------------------------------------------------+

仮想メソッドは基本オブジェクトメソッドを再定義します。他のデフォルト値はここで設定されます。さらに、Labelオブジェクトに固有のプロパティ値の初期化があります。


基本オブジェクトメソッドを再定義する仮想 Eraseメソッド完全に不透明なオブジェクトフレームを描画します

//+------------------------------------------------------------------+
//| Clear the element filling it with color and opacity              |
//+------------------------------------------------------------------+
void CLabel::Erase(const color colour,const uchar opacity,const bool redraw=false)
  {
//--- Fill the element having the specified color and the redrawing flag
   CGCnvElement::Erase(colour,opacity,redraw);
//--- If the object has a frame, draw it
   if(this.BorderStyle()!=FRAME_STYLE_NONE && redraw)
      this.DrawFormFrame(this.FrameWidthTop(),this.FrameWidthBottom(),this.FrameWidthLeft(),this.FrameWidthRight(),this.ColorFrame(),255,this.BorderStyle());
//--- Update the element having the specified redrawing flag
   this.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Clear the element with a gradient fill                           |
//+------------------------------------------------------------------+
void CLabel::Erase(color &colors[],const uchar opacity,const bool vgradient,const bool cycle,const bool redraw=false)
  {
//--- Fill the element having the specified color array and the redrawing flag
   CGCnvElement::Erase(colors,opacity,vgradient,cycle,redraw);
//--- If the object has a frame, draw it
   if(this.BorderStyle()!=FRAME_STYLE_NONE && redraw)
      this.DrawFormFrame(this.FrameWidthTop(),this.FrameWidthBottom(),this.FrameWidthLeft(),this.FrameWidthRight(),this.ColorFrame(),255,this.BorderStyle());
//--- Update the element having the specified redrawing flag
   this.Update(redraw);
  }
//+------------------------------------------------------------------+
//| Clear the element completely                                     |
//+------------------------------------------------------------------+
void CLabel::Erase(const bool redraw=false)
  {
//--- Fully clear the element with the redrawing flag
   CGCnvElement::Erase(redraw);
  }
//+------------------------------------------------------------------+


以下は、オブジェクトを再描画する仮想メソッドです。

//+------------------------------------------------------------------+
//| Redraw the object                                                |
//+------------------------------------------------------------------+
void CLabel::Redraw(bool redraw)
  {
//--- Fill the object with the background color having full transparency
   this.Erase(this.ColorBackground(),0,true);
   int x=0;
   int y=0;
//--- Depending on the element text alignment type
   switch(this.TextAlign())
     {
      //--- The text is displayed in the upper left corner of the object
      case ANCHOR_LEFT_UPPER : 
        //--- Set the text binding point coordinate
        x=this.FrameWidthLeft();
        y=this.FrameWidthTop();
        //--- Set the text binding point at the top left
        this.SetTextAnchor(FRAME_ANCHOR_LEFT_TOP);
        break;
      //--- The text is drawn vertically from the left side of the object in the center
      case ANCHOR_LEFT : 
        //--- Set the text binding point coordinate
        x=this.FrameWidthLeft();
        y=this.Height()/2;
        //--- Set the text binding point at the center left
        this.SetTextAnchor(FRAME_ANCHOR_LEFT_CENTER);
        break;
      //--- The text is displayed in the lower left corner of the object
      case ANCHOR_LEFT_LOWER : 
        //--- Set the text binding point coordinate
        x=this.FrameWidthLeft();
        y=this.Height()-this.FrameWidthBottom();
        //--- Set the text binding point at the bottom left
        this.SetTextAnchor(FRAME_ANCHOR_LEFT_BOTTOM);
        break;
      //--- The text is drawn at the center of the bottom edge of the object
      case ANCHOR_LOWER : 
        //--- Set the text binding point coordinate
        x=this.Width()/2;
        y=this.Height()-this.FrameWidthBottom();
        //--- Set the text anchor point at the bottom center
        this.SetTextAnchor(FRAME_ANCHOR_CENTER_BOTTOM);
        break;
      //--- The text is displayed in the lower right corner of the object
      case ANCHOR_RIGHT_LOWER : 
        //--- Set the text binding point coordinate
        x=this.Width()-this.FrameWidthRight();
        y=this.Height()-this.FrameWidthBottom();
        //--- Set the text binding point at the bottom right
        this.SetTextAnchor(FRAME_ANCHOR_RIGHT_BOTTOM);
        break;
      //--- The text is drawn vertically from the right side of the object in the center
      case ANCHOR_RIGHT : 
        //--- Set the text binding point coordinate
        x=this.Width()-this.FrameWidthRight();
        y=this.Height()/2;
        //--- Set the text binding point at the center right
        this.SetTextAnchor(FRAME_ANCHOR_RIGHT_CENTER);
        break;
      //--- The text is displayed in the upper right corner of the object
      case ANCHOR_RIGHT_UPPER : 
        //--- Set the text binding point coordinate
        x=this.Width()-this.FrameWidthRight();
        y=this.FrameWidthTop();
        //--- Set the text binding point at the top right
        this.SetTextAnchor(FRAME_ANCHOR_RIGHT_TOP);
        break;
      //--- The text is drawn at the center of the upper edge of the object
      case ANCHOR_UPPER : 
        //--- Set the text binding point coordinate
        x=this.Width()/2;
        y=this.FrameWidthTop();
        //--- Set the text binding point at the center top
        this.SetTextAnchor(FRAME_ANCHOR_CENTER_TOP);
        break;
      //--- The text is drawn at the object center
      //---ANCHOR_CENTER
      default:
        //--- Set the text binding point coordinate
        x=this.Width()/2;
        y=this.Height()/2;
        //--- Set the text binding point at the center
        this.SetTextAnchor(FRAME_ANCHOR_CENTER);
        break;
     }
//--- Draw the text within the set coordinates of the object and the binding point of the text, and update the object 
   this.Text(x,y,this.Text(),this.ForeColor(),this.ForeColorOpacity(),this.TextAnchor());
   this.Update(redraw);
  }
//+------------------------------------------------------------------+

このメソッドは基本クラスのメソッドを再定義します。オブジェクトの背景はここで最初に削除されます(完全に透明な背景色で塗りつぶされます)。次に、要素内のテキストに応じて、テキストの結合点が定義されます。テキスト結合点の座標(ラベル座標の原点)を算出し、算出した座標内にテキストを表示し、オブジェクトを更新します。

テキストの結合点は視覚的にマークされ、TextOut() 関数のヘルプで説明されています。



以下は、要素の幅と高さを自動的に設定するメソッドです。

//+------------------------------------------------------------------+
//| Set the element width and height automatically                   |
//+------------------------------------------------------------------+
void CLabel::AutoSetWH(void)
  {
//--- Define the variables for receiving the label width and height
   int w=0, h=0;
//--- Get the width and height depending on the object text
   CGCnvElement::TextSize(this.Text()!="" && this.Text()!=NULL ? this.Text() : " ",w,h);
//--- Add the Margin values of the object on the left and right to the resulting width
   w+=(this.MarginLeft()+this.MarginRight());
//--- If failed to get the width, set it to three pixels
   if(w==0)
      w=3;
//--- Add the Margin values of the object on the top and bottom to the resulting height
   h+=(this.MarginTop()+this.MarginBottom());
//--- If failed to get the height, set it as "font size" * ratio
   if(h==0)
      h=(int)ceil(FontSize()*1.625);
//--- Set the object width and height from the received values
   this.SetWidth(w);
   this.SetHeight(h);
  }
//+------------------------------------------------------------------+

メソッドのロジックは、コードのコメントで説明されています。まず、オブジェクトに設定されたテキストとフォントのパラメータに応じてテキストのサイズを取得します。ラベルが「空」の場合、測定にはスペース (" ") が使用されます。次に、オブジェクトの左右のマージン値を結果の幅に追加し、上下のマージン値を高さの値に追加します。テキストの高さを取得できなかった場合は、オブジェクトに設定されているフォントサイズに経験的に選択した比率を乗算して、おおよそのサイズを計算します。MS Visual Studioのフォントサイズに応じてオブジェクトサイズの値を比較し、さまざまなサイズのいくつかの測定値から平均値を取得して、1.625の比率を得ました。これ以上正確な方法はわかりません。フォントサイズに応じたオブジェクトサイズを計算するより良い方法が後で見つかるかもしれません。すべての計算が完了したら、取得した幅と高さの値がオブジェクトに設定されます。

これで、「テキストラベル」オブジェクトの作成は完了です。

WinForms Panelオブジェクトは、他の同じタイプのオブジェクトを結合するためのコンテナであるため、作成された同じタイプのすべてのオブジェクトが表示される必要があります。これを実現するには、作成された各WinFormsオブジェクトのファイルをパネルオブジェクトファイルに含めます。

パネルオブジェクトファイル(\MQL5\Include\DoEasy\Objects\Graph\WForms\Containers\Panel.mqh)を開き、新しく作成されたテキストラベルオブジェクトのファイルをインクルードします

//+------------------------------------------------------------------+
//|                                                        Panel.mqh |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "..\..\WForms\WinFormBase.mqh"
#include "..\..\WForms\Common Controls\Label.mqh"
//+------------------------------------------------------------------+


クラスのprivateセクションから不要な変数を削除 します。基本的なWinFormsオブジェクトプロパティに設定されているためです。

//+------------------------------------------------------------------+
//| Panel object class of WForms controls                            |
//+------------------------------------------------------------------+
class CPanel : public CWinFormBase
  {
private:
   CGCnvElement     *m_obj_top;                                      // Pointer to the object whose coordinates the current upper object is bound to
   CGCnvElement     *m_obj_bottom;                                   // Pointer to the object whose coordinates the current bottom object is bound to
   CGCnvElement     *m_obj_left;                                     // Pointer to the object whose coordinates the current left object is bound to
   CGCnvElement     *m_obj_right;                                    // Pointer to the object whose coordinates the current right object is bound to
   CGCnvElement     *m_underlay;                                     // Underlay for placing elements
   bool              m_autoscroll;                                   // Auto scrollbar flag
   int               m_autoscroll_margin[2];                         // Array of fields around the control during an auto scroll
   ENUM_CANV_ELEMENT_AUTO_SIZE_MODE m_autosize_mode;                 // Mode of the element auto resizing depending on the content
//--- Create a new graphical object


クラスのpublicセクションで、指定されたタイプのバインドされた WinFormsオブジェクトのリストを受け取るメソッドと指定された WinFormsオブジェクトへのポインタをこのタイプのオブジェクトリスト内のインデックスによって取得する メソッドの2 つの新しいメソッドを宣言します。

public:
//--- Return the underlay
   CGCnvElement     *GetUnderlay(void)                               { return this.m_underlay;              }
//--- Return the list of bound objects with (1) any and (2) specified basic WinForms type and higher
   CArrayObj        *GetListWinFormsObj(void);
   CArrayObj        *GetListWinFormsObjByType(const ENUM_GRAPH_ELEMENT_TYPE type);
//--- Return the pointer to the specified WinForms object with the specified type by index
   CWinFormBase     *GetWinFormsObj(const ENUM_GRAPH_ELEMENT_TYPE type,const int index);
   
//--- Update the coordinates (shift the canvas)


クラスからSetAutoScroll()およびAutoScroll()メソッドを削除します。これらはCWinFormBase親クラスのメンバーであり、クラス変数ではなくオブジェクトプロパティを処理するように調整されているためです。

//--- Place bound objects in the order of their Dock binding
   bool              ArrangeObjects(const bool redraw);
   
//--- (1) Set and (2) return the auto scrollbar flag
   void              SetAutoScroll(const bool flag)                  { this.m_autoscroll=flag;              }
   bool              AutoScroll(void)                                { return this.m_autoscroll;            }
//--- Set the (1) field width, (2) height, (3) the height of all fields around the control during auto scrolling


同様の方法でオブジェクトプロパティを処理するクラスメソッドを書き換え、幅と高さによってAutoScrollMarginを同時に設定するメソッドを追加します

//--- Set the (1) field width, (2) height, (3) the height of all fields around the control during auto scrolling
   void              SetAutoScrollMarginWidth(const int value)       { this.SetProperty(CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_W,value);  }
   void              SetAutoScrollMarginHeight(const int value)      { this.SetProperty(CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_H,value);  }
   void              SetAutoScrollMarginAll(const int value)
                       {
                        this.SetAutoScrollMarginWidth(value); this.SetAutoScrollMarginHeight(value);
                       }
   void              SetAutoScrollMargin(const int width,const int height)
                       {
                        this.SetAutoScrollMarginWidth(width); this.SetAutoScrollMarginHeight(height);
                       }
//--- Return the (1) field width and (2) height around the control during auto scrolling
   int               AutoScrollMarginWidth(void)               const { return (int)this.GetProperty(CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_W); }
   int               AutoScrollMarginHeight(void)              const { return (int)this.GetProperty(CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_H); }
  
//--- (1) Set the flag of the element auto resizing depending on the content
   virtual void      SetAutoSize(const bool flag,const bool redraw)
                       {
                        bool prev=this.AutoSize();
                        if(prev==flag)
                           return;
                        CWinFormBase::SetAutoSize(flag,redraw);
                        if(prev!=this.AutoSize() && this.ElementsTotal()>0)
                           this.AutoSizeProcess(redraw);
                       }
//--- (1) Set and (2) return the mode of the element auto resizing depending on the content
   void              SetAutoSizeMode(const ENUM_CANV_ELEMENT_AUTO_SIZE_MODE mode,const bool redraw)
                       {
                        ENUM_CANV_ELEMENT_AUTO_SIZE_MODE prev=this.AutoSizeMode();
                        if(prev==mode)
                           return;
                        this.SetProperty(CANV_ELEMENT_PROP_AUTOSIZE_MODE,mode);
                        if(prev!=this.AutoSizeMode() && this.ElementsTotal()>0)
                           this.AutoSizeProcess(redraw);
                       }
   ENUM_CANV_ELEMENT_AUTO_SIZE_MODE AutoSizeMode(void)   const { return (ENUM_CANV_ELEMENT_AUTO_SIZE_MODE)this.GetProperty(CANV_ELEMENT_PROP_AUTOSIZE_MODE); }
   
//--- (1) Set and (2) return the mode of binding element borders to the container


新しいグラフィカルオブジェクトを作成するメソッドで、テキストラベルオブジェクトを作成するためのコードブロックを追加します

//+------------------------------------------------------------------+
//| Create a new graphical object                                    |
//+------------------------------------------------------------------+
CGCnvElement *CPanel::CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type,
                                       const int obj_num,
                                       const string obj_name,
                                       const int x,
                                       const int y,
                                       const int w,
                                       const int h,
                                       const color colour,
                                       const uchar opacity,
                                       const bool movable,
                                       const bool activity)
  {
   string name=this.CreateNameDependentObject(obj_name);
   CGCnvElement *element=NULL;
   switch(type)
     {
      case GRAPH_ELEMENT_TYPE_ELEMENT :
         element=new CGCnvElement(type,this.ID(),obj_num,this.ChartID(),this.SubWindow(),name,x,y,w,h,colour,opacity,movable,activity);
        break;
      case GRAPH_ELEMENT_TYPE_FORM :
         element=new CForm(this.ChartID(),this.SubWindow(),name,x,y,w,h);
        break;
      case GRAPH_ELEMENT_TYPE_WF_PANEL :
         element=new CPanel(this.ChartID(),this.SubWindow(),name,x,y,w,h);
        break;
      case GRAPH_ELEMENT_TYPE_WF_LABEL :
         element=new CLabel(this.ChartID(),this.SubWindow(),name,x,y,w,h);
        break;
      default:
        break;
     }
   if(element==NULL)
      ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),": ",name);
   return element;
  }
//+------------------------------------------------------------------+

ここではすべてが明確であり、コメントは必要ありません。


新しくバインドされた要素を作成するメソッドを書き直してみましょう。

//+------------------------------------------------------------------+
//| Create a new attached element                                    |
//+------------------------------------------------------------------+
bool CPanel::CreateNewElement(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                              CGCnvElement *main,
                              const int x,
                              const int y,
                              const int w,
                              const int h,
                              const color colour,
                              const uchar opacity,
                              const bool activity,
                              const bool redraw)
  {
//--- If the object type is less than the base WinForms object
   if(element_type<GRAPH_ELEMENT_TYPE_WF_BASE)
     {
      //--- report the error and return 'false'
      CMessage::ToLog(DFUN,MSG_PANEL_OBJECT_ERR_OBJ_MUST_BE_WFBASE);
      return false;
     }
//--- If failed to create a new graphical element, return 'false'
   CWinFormBase *obj=CForm::CreateAndAddNewElement(element_type,main,x,y,w,h,colour,opacity,activity);
   if(obj==NULL)
      return false;
//--- Set the text color of the created object as that of the base panel
   obj.SetForeColor(this.ForeColor());
//--- If the object type is a panel
   if(obj.TypeGraphElement()==GRAPH_ELEMENT_TYPE_WF_PANEL)
     {
      //--- set the frame color equal to the background color 
      obj.SetColorFrame(obj.ColorBackground());
     }
//--- If the object type is a text label,
   if(obj.TypeGraphElement()==GRAPH_ELEMENT_TYPE_WF_LABEL)
     {
      //--- set the object text color depending on the one passed to the method
      //--- or the panel text color or the one passed to the method and the frame color equal to the text color 
      obj.SetForeColor(colour==clrNONE ? this.ForeColor() : colour);
      obj.SetColorFrame(main!=NULL ? main.ColorBackground() : obj.ForeColor());
     }
//--- If the panel has auto resize enabled and features bound objects, call the resize method
   if(this.AutoSize() && this.ElementsTotal()>0)
      this.AutoSizeProcess(redraw);
//--- Redraw the panel and all added objects, and return 'true'
   this.Redraw(redraw);
   return true;
  }
//+------------------------------------------------------------------+

メソッドのロジックは、コードのコメントで説明されています。メソッド自体での小規模なロジックの改善とは別に、テキストラベルオブジェクトの作成を処理するコードブロックを追加しました。ここでのすべてが明確であり、説明が必要ないことを願っています。質問がある場合は、下のコメント欄でお気軽にお問い合わせください。


以下は、タイプが指定されたWinFormsオブジェクトで接続されたオブジェクトのリストを返すメソッドです。

//+------------------------------------------------------------------+
//| Return the list of bound objects                                 |
//| with the specified WinForms object type                          |
//+------------------------------------------------------------------+
CArrayObj *CPanel::GetListWinFormsObjByType(const ENUM_GRAPH_ELEMENT_TYPE type)
  {
   return CSelect::ByGraphCanvElementProperty(this.GetListElements(),CANV_ELEMENT_PROP_TYPE,type,EQUAL);
  }
//+------------------------------------------------------------------+

ここでは、指定されたWinFormsオブジェクトタイプのCSelectクラスで受け取ったリストを返すだけです。リストの取得に失敗した場合、または指定されたタイプのオブジェクトがない場合、メソッドはNULLを返します。


以下は、インデックスで指定されたタイプのバインドされたWinFormsオブジェクトへのポインタを返すメソッドです。

//+------------------------------------------------------------------+
//| Return the pointer to the specified WinForms object              |
//| with the specified type by index                                 |
//+------------------------------------------------------------------+
CWinFormBase *CPanel::GetWinFormsObj(const ENUM_GRAPH_ELEMENT_TYPE type,const int index)
  {
   CArrayObj *list=this.GetListWinFormsObjByType(type);
   return(list!=NULL ? list.At(index) : NULL);
  }
//+------------------------------------------------------------------+

ここでは、指定されたタイプのオブジェクトのリストを取得し、指定されたインデックスによってリストからオブジェクトへのポインタを返します
リストの取得に失敗した場合、または存在しないインデックスが指定された場合、メソッドはNULLを返します。

すべてをテストする準備ができました。


検証

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

すべてのグラフィカルオブジェクトの名前にはプログラム名が含まれているため、CCanvasクラスのCreate()メソッドでチャート ID + プログラムの起動以降に経過したプロセッサティック数 + 疑似乱数を使用してグラフィカルオブジェクトリソースを作成します

//+------------------------------------------------------------------+
//| Create dynamic resource                                          |
//+------------------------------------------------------------------+
bool CCanvas::Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt)
  {
   Destroy();
//--- prepare data array
   if(width>0 && height>0 && ArrayResize(m_pixels,width*height)>0)
     {
      //--- generate resource name
      m_rcname="::"+name+(string)ChartID()+(string)(GetTickCount()+MathRand());
      //--- initialize data with zeros
      ArrayInitialize(m_pixels,0);
      //--- create dynamic resource
      if(ResourceCreate(m_rcname,m_pixels,width,height,0,0,0,clrfmt))
        {
         //--- successfully created
         //--- complete initialization
         m_width =width;
         m_height=height;
         m_format=clrfmt;
         //--- succeed
         return(true);
        }
     }
//--- error - destroy object
   Destroy();
   return(false);
  }
//+------------------------------------------------------------------+

... グラフィックオブジェクトの名前が63文字を超えると、リソース作成エラーが発生します。したがって、当面はプログラム名の長さを短くする必要があります。後で、グラフィカルオブジェクト名の作成の問題を解決する必要があります。これは、バインドされた各オブジェクトがバインド先のオブジェクトの名前を継承し、階層内の新しい要素を示す末尾が追加されているためです。互いに接続されたオブジェクトの階層内でネストされたオブジェクトが多いほど、オブジェクト名は長くなります。この概念は間違っており、最終的に、グラフィカルオブジェクトの作成時に名前の長さの超過によるエラーが発生します。ただし、今のところは、プログラム名自体の長さを短くしましょう。

メインパネルに6つのパネルオブジェクトが作成されます。各パネルに1つのテキストラベルオブジェクトを作成します。オブジェクトサイズは、パネルサイズから各辺の2ポイントを減算した値になります。EA設定で、テキストラベルオブジェクトのフレームタイプと、テキストラベルオブジェクト内のテキスト配置値を表示します。これにより、テキストがオブジェクト内のどこにどのように表示されるかを明確に確認できます。

グローバル領域で、プログラムの英語版とライブラリユーザの言語版の両方でコンパイルするオブジェクトフレームタイプを記述する列挙を作成し、新しいプログラム入力を追加します

//+------------------------------------------------------------------+
//|                                                     TstDE107.mq5 |
//|                                  Copyright 2022, MetaQuotes Ltd. |
//|                             https://mql5.com/en/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, MetaQuotes Ltd."
#property link      "https://mql5.com/en/users/artmedia70"
#property version   "1.00"
//--- includes
#include <DoEasy\Engine.mqh>
//--- defines
#define  FORMS_TOTAL (3)   // Number of created forms
#define  START_X     (4)   // Initial X coordinate of the shape
#define  START_Y     (4)   // Initial Y coordinate of the shape
#define  KEY_LEFT    (65)  // (A) Left
#define  KEY_RIGHT   (68)  // (D) Right
#define  KEY_UP      (87)  // (W) Up
#define  KEY_DOWN    (88)  // (X) Down
#define  KEY_FILL    (83)  // (S) Filling
#define  KEY_ORIGIN  (90)  // (Z) Default
#define  KEY_INDEX   (81)  // (Q) By index

//--- enumerations by compilation language
#ifdef COMPILE_EN
enum ENUM_AUTO_SIZE_MODE
  {
   AUTO_SIZE_MODE_GROW=CANV_ELEMENT_AUTO_SIZE_MODE_GROW,                // Grow
   AUTO_SIZE_MODE_GROW_SHRINK=CANV_ELEMENT_AUTO_SIZE_MODE_GROW_SHRINK   // Grow and Shrink
  };
enum ENUM_BORDER_STYLE
  {
   BORDER_STYLE_NONE=FRAME_STYLE_NONE,                                  // None
   BORDER_STYLE_SIMPLE=FRAME_STYLE_SIMPLE,                              // Simple
   BORDER_STYLE_FLAT=FRAME_STYLE_FLAT,                                  // Flat
   BORDER_STYLE_BEVEL=FRAME_STYLE_BEVEL,                                // Embossed (bevel)
   BORDER_STYLE_STAMP=FRAME_STYLE_STAMP,                                // Embossed (stamp)
  };
#else 
enum ENUM_AUTO_SIZE_MODE
  {
   AUTO_SIZE_MODE_GROW=CANV_ELEMENT_AUTO_SIZE_MODE_GROW,                // Increase only
   AUTO_SIZE_MODE_GROW_SHRINK=CANV_ELEMENT_AUTO_SIZE_MODE_GROW_SHRINK   // Increase and decrease
  };
enum ENUM_BORDER_STYLE
  {
   BORDER_STYLE_NONE=FRAME_STYLE_NONE,                                  // No frame
   BORDER_STYLE_SIMPLE=FRAME_STYLE_SIMPLE,                              // Simple frame
   BORDER_STYLE_FLAT=FRAME_STYLE_FLAT,                                  // Flat frame
   BORDER_STYLE_BEVEL=FRAME_STYLE_BEVEL,                                // Embossed (convex)
   BORDER_STYLE_STAMP=FRAME_STYLE_STAMP,                                // Embossed (concave)
  };
#endif 
//--- input parameters
sinput   bool                 InpMovable        =  true;                // Movable forms flag
sinput   ENUM_INPUT_YES_NO    InpAutoSize       =  INPUT_YES;           // Autosize
sinput   ENUM_AUTO_SIZE_MODE  InpAutoSizeMode   =  AUTO_SIZE_MODE_GROW; // Autosize mode
sinput   ENUM_BORDER_STYLE    InpFrameStyle     =  BORDER_STYLE_NONE;   // Label border style
sinput   ENUM_ANCHOR_POINT    InpTextAlign      =  ANCHOR_LEFT_UPPER;   // Label text align
//--- global variables
CEngine        engine;
color          array_clr[];
//+------------------------------------------------------------------+


OnInit()ハンドラで、テキストラベルオブジェクトを作成するためのコードブロックを追加します

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Set EA global variables
   ArrayResize(array_clr,2);        // Array of gradient filling colors
   array_clr[0]=C'26,100,128';      // Original ≈Dark-azure color
   array_clr[1]=C'35,133,169';      // Lightened original color
//--- Create the array with the current symbol and set it to be used in the library
   string array[1]={Symbol()};
   engine.SetUsedSymbols(array);
   //--- Create the timeseries object for the current symbol and period, and show its description in the journal
   engine.SeriesCreate(Symbol(),Period());
   engine.GetTimeSeriesCollection().PrintShort(false); // Short descriptions
//--- Create WinForms Panel object
   CPanel *pnl=NULL;
   pnl=engine.CreateWFPanel("WFPanel",50,50,230,150,array_clr,200,true,true,false,-1,FRAME_STYLE_BEVEL,true,false);
   if(pnl!=NULL)
     {
      //--- Set Padding to 4
      pnl.SetPaddingAll(4);
      //--- Set the flags of relocation, auto resizing and auto changing mode from the inputs
      pnl.SetMovable(InpMovable);
      pnl.SetAutoSize(InpAutoSize,false);
      pnl.SetAutoSizeMode((ENUM_CANV_ELEMENT_AUTO_SIZE_MODE)InpAutoSizeMode,false);
      //--- In the loop, create 6 bound panel objects
      for(int i=0;i<6;i++)
        {
         //--- create the panel object with coordinates along the X axis in the center and 10 along the Y axis, the width of 80 and the height of 50
         CPanel *prev=pnl.GetElement(i-1);
         int xb=0, yb=0;
         int x=(i<3 ? (prev==NULL ? xb : prev.CoordXRelative()) : xb+prev.Width()+20);
         int y=(i<3 ? (prev==NULL ? yb : prev.BottomEdgeRelative()+16) : (i==3 ? yb : prev.BottomEdgeRelative()+16));
         if(pnl.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_PANEL,pnl,x,y,90,40,C'0xCD,0xDA,0xD7',200,true,false))
           {
            CPanel *obj=pnl.GetElement(i);
            if(obj==NULL)
               continue;
            obj.SetFrameWidthAll(3);
            obj.SetBorderStyle(FRAME_STYLE_BEVEL);
            obj.SetColorBackground(obj.ChangeColorLightness(obj.ColorBackground(),4*i));
            obj.SetForeColor(clrRed);
            //--- Calculate the width and height of the future text label object
            int w=obj.Width()-obj.FrameWidthLeft()-obj.FrameWidthRight()-4;
            int h=obj.Height()-obj.FrameWidthTop()-obj.FrameWidthBottom()-4;
            //--- Create a text label object
            obj.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_LABEL,pnl,2,2,w,h,clrNONE,255,false,false);
            //--- Get the pointer to a newly created object
            CLabel *lbl=obj.GetElement(0);
            if(lbl!=NULL)
              {
               //--- If the object has an even or zero index in the list, set the default text color for it
               if(i % 2==0)
                  lbl.SetForeColor(CLR_DEF_FORE_COLOR);
               //--- If the object index in the list is odd, set the object opacity to 127
               else
                  lbl.SetForeColorOpacity(127);
               //--- Set the font Black width type and
               //--- specify the text alignment from the EA settings
               lbl.SetFontBoldType(FW_TYPE_BLACK);
               lbl.SetTextAlign(InpTextAlign);
               //--- For an object with an even or zero index, specify the Bid price for the text, otherwise - the Ask price of the symbol 
               lbl.SetText(GetPrice(i % 2==0 ? SYMBOL_BID : SYMBOL_ASK));
               //--- Set the frame width and type for a text label and update the modified object
               lbl.SetFrameWidthAll(1);
               lbl.SetBorderStyle((ENUM_FRAME_STYLE)InpFrameStyle);
               lbl.Update(true);
              }
           }
        }
      //--- Redraw all objects according to their hierarchy
      pnl.Redraw(true);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+

ロジック全体は、コード内で詳細にコメントされています。テキストラベルオブジェクトを作成する前に、ラベルがバインドされているパネルのテキスト背景色を設定します。この色は、テキストラベルオブジェクトによって継承される必要があります。これがここで確認しているものです。その後、必要に応じてテキストオブジェクト自体の色を変更します。

OnTick()ハンドラで、各テキストラベルに売り値と買い値を入力します。リスト内のインデックスが偶数のオブジェクトの場合は買い呼び値を入力し奇数のオブジェクトの場合は売り呼び値を入力します

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //--- Get the pointer to the panel object by name
   CPanel *pnl=engine.GetWFPanel("WFPanel");
   if(pnl!=NULL)
     {
      //--- Get the list of all bound panel objects
      CArrayObj *list=pnl.GetListWinFormsObjByType(GRAPH_ELEMENT_TYPE_WF_PANEL);
      //--- In the loop by bound panel objects,
      for(int i=0;i<list.Total();i++)
        {
         //--- get the pointer to the next panel object
         CPanel *obj=pnl.GetWinFormsObj(GRAPH_ELEMENT_TYPE_WF_PANEL,i);
         if(obj!=NULL)
           {
            //--- take the pointer to the first (and only) text label object from the received object
            CLabel *lbl=obj.GetWinFormsObj(GRAPH_ELEMENT_TYPE_WF_LABEL,0);
            if(lbl!=NULL)
              {
               //--- set the new text for the object and redraw it
               lbl.SetText(GetPrice(i % 2==0 ? SYMBOL_BID : SYMBOL_ASK));
               lbl.Redraw(false);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+

EAリストの最後に、買い呼び値または売り呼び値の文字列値を返す関数を追加します。

//+------------------------------------------------------------------+
//| Return Bid/Ask string value                                      |
//+------------------------------------------------------------------+
string GetPrice(const ENUM_SYMBOL_INFO_DOUBLE price)
  {
   return((price==SYMBOL_ASK ? "Ask: " : "Bid: ")+DoubleToString(SymbolInfoDouble(Symbol(),price),Digits()));
  }
//+------------------------------------------------------------------+

関数に渡される値に応じて、価格値の前に何を書き込むか (「Ask」または「Bid」)を選択し、指定されたタイプの文字列の価格値をテキストに追加します。

EAをコンパイルし、チャート上で起動します。


ご覧のとおり、テキストはオブジェクト内の正しい位置に表示され、そのサイズはフレームの存在を指定することで確認できます。オブジェクト内の価格を含むテキストは、チャート上の対応する価格の更新に従って更新されます。

パネルとそのオブジェクトを作成すると、明らかに視覚的に不快な効果が見られます。これらは、チャート上のオブジェクトが構築、移動、再構築されたときにそれらを操作しながらビジュアル表示を最適化するときに取り除くつもりです。


次の段階

次回の記事では、WinFormsオブジェクトの開発を続けます。

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

目次に戻る

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

DoEasyコントロール(第1部):最初のステップ
DoEasyコントロール(第2部):CPanelクラスでの作業
DoEasyコントロール(第3部):バインドされたコントロールの作成
DoEasyコントロール(第4部):パネルコントロール、Padding、Dockパラメータ
DoEasyコントロール(第5部):WinForms基本オブジェクト、Panelコントロール、AutoSizeパラメータ
DoEasyコントロール(第6部):パネルコントロール、内部コンテンツに合わせたコンテナサイズの自動変更



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

添付されたファイル |
MQL5.zip (4357.39 KB)
一からの取引エキスパートアドバイザーの開発(第18部):新規受注システム(I) 一からの取引エキスパートアドバイザーの開発(第18部):新規受注システム(I)
今回は新規受注システムの第一弾です。本連載で紹介し始めてから、このEAは、同じチャート上注文システムモデルを維持しながら様々な変更と改良を受けてきました。
ビデオ:MetaTrader5とMQL5での簡単な自動売買の設定方法 ビデオ:MetaTrader5とMQL5での簡単な自動売買の設定方法
このビデオコースでは、MetaTrader 5をダウンロード、インストールして自動売買のために設定する方法を学びます。また、チャートの設定や自動売買のオプションの調整方法についても学びます。最初のバックテストをおこないます。このコースの終わりには、画面の前に座らなくても、24時間365日自動的に取引できるエキスパートアドバイザー(EA)をインポートする方法が分かります。
データサイエンスと機械学習(第04回):現在の株式市場の暴落を予測する データサイエンスと機械学習(第04回):現在の株式市場の暴落を予測する
今回は、米国経済のファンダメンタルズに基づいて、私たちのロジスティックモデルを使って株式市場の暴落の予測を試みます。NETFLIXとAPPLEが私たちが注目する銘柄です、2019年と2020年の過去の市場の暴落を使って、モデルが現在の破滅と暗雲でどのように機能するか見てみましょう。
AD(蓄積/分散、Accumulation/Distribution)による取引システムの設計方法を学ぶ AD(蓄積/分散、Accumulation/Distribution)による取引システムの設計方法を学ぶ
最も人気のあるテクニカル指標に基づいて取引システムを設計する方法を学ぶための連載の新しい記事へようこそ。今回は、AD(蓄積/分散、Accumulation/Distribution)という新しいテクニカル指標について学び、シンプルなAD取引戦略に基づいてMQL5取引システムを設計する方法を学びます。