English Русский 中文 Español Deutsch Português
preview
DoEasy - コントロール(第28部):ProgressBarコントロールのバースタイル

DoEasy - コントロール(第28部):ProgressBarコントロールのバースタイル

MetaTrader 5 | 31 1月 2023, 09:03
169 0
Artyom Trishkin
Artyom Trishkin

内容


概念

現在、ライブラリ用に作成されたProgressBarコントロールのプログレスバー表示スタイルは、連続線(Continuous)の一種類ですが、このようなコントロールの表示スタイルには後2つあります。分割ブロック(Blocks)とオブジェクト内のブロックの連続スクロール(Marquee)です。Blocksスタイルは非常に明確です(連続線が、別々に配置されたブロックに置き換えられます)。ProgressBarコントロールを使用して視覚的に表示する必要のある反復の回数が事前にわからない場合、Marqueeスタイルを使用することができます。この場合、プログレスバーの幅の半分に相当する1つのブロックが常にスクロールすることになります。 

これら2つのスタイルを新たに作成するとともに、プログレスバーの内部に表示するテキストを追加してみます。テキスト自体は、ライブラリのCLabelクラスの通常のオブジェクトで表現され、プログレスバーオブジェクトではなく、ProgressBarコントロールのベースであるアンダーレイオブジェクトに結合されます。テキストは、プログレスバーの幅と高さに合わせた大きさの、完全に透明なテキストラベルオブジェクトの中に描画されます。このオブジェクトは、常にProgressBarコントロールのすべてのオブジェクトの前面に表示されます。

デフォルトでは、テキストはプログレスバーに表示されませんが、ライブラリベースのプログラムの実行中にいつでも追加することができます。出力テキストとその属性(フォント、サイズ、フォントフラグ、色、不透明度など)を指定するだけです。


ライブラリクラスの改善

ProgressBarコントロールの新しいスタイルの開発を始める前に、基本的なグラフィック要素のコンストラクタを簡素化してみましょう。オブジェクトを作成した後、protectedコンストラクタとパラメトリックコンストラクタでプロパティの値を設定します。どちらのコンストラクタにも、新しいオブジェクトが作成されるときに常に追加される、100種類以上のライブラリのグラフィック要素パラメータの長いリストがあります。そのため、オブジェクトのプロパティの設定を、CGCnvElementクラスのprotectedコンストラクタとパラメトリックコンストラクタで、常に2回記述する必要があります。これらのプロパティの設定は、別の初期化メソッドに移すのが論理的でしょう。同時に、いくつかのプロパティを異なるコンストラクタで異なるように設定する場合、それらは単に新しいメソッドの仮パラメータで渡されて示されることになります。

\MQL5\Include\DoEasy\Objects\Graph\GCnvElement.mqhで、オブジェクト構造体に新しいプロパティを追加します

   struct SData
     {
      //--- Object integer properties
      int            id;                                       // Element ID
      int            type;                                     // Graphical element type
      
      //---...
      //---...

      //---
      int            group;                                    // Group the graphical element belongs to
      int            tab_size_mode;                            // Tab size setting mode
      int            tab_page_number;                          // Tab index number
      int            tab_page_row;                             // Tab row index
      int            tab_page_column;                          // Tab column index
      int            progress_bar_minimum;                     // The lower bound of the range ProgressBar operates in
      int            progress_bar_maximum;                     // The upper bound of the range ProgressBar operates in
      int            progress_bar_step;                        // ProgressBar increment needed to redraw it
      int            progress_bar_style;                       // ProgressBar style
      int            progress_bar_value;                       // Current ProgressBar value from Min to Max
      int            progress_bar_marquee_speed;               // Progress bar animation speed in case of Marquee style
      //---
      ulong          tooltip_initial_delay;                    // Tooltip display delay
      ulong          tooltip_auto_pop_delay;                   // Tooltip display duration
      ulong          tooltip_reshow_delay;                     // One element new tooltip display delay
      bool           tooltip_show_always;                      // Display a tooltip in inactive window
      int            tooltip_icon;                             // Icon displayed in a tooltip
      bool           tooltip_is_balloon;                       // Tooltip in the form of a "cloud"
      bool           tooltip_use_fading;                       // Fade when showing/hiding a tooltip
      //--- Object real properties

      //--- Object string properties
      uchar          name_obj[64];                             // Graphical element object name
      uchar          name_res[64];                             // Graphical resource name
      uchar          text[256];                                // Graphical element text
      uchar          descript[256];                            // Graphical element description
      uchar          tooltip_title[256];                       // Element tooltip title
      uchar          tooltip_text[256];                        // Element tooltip text
     };
   SData             m_struct_obj;                             // Object structure

グラフィカルオブジェクトの構造体は、オブジェクトのプロパティをファイルに正しく書き込み、復元時にファイルから読み取るために必要です。この構造体に書き込まれるようになったプロパティは、オブジェクトにはすでに追加されていますが、構造体にはまだ追加されていません。構造体のフィールドとオブジェクトの特性が一致しなくても、この段階では心配ありません。今のところ、オブジェクトをファイルに保存し、そのファイルからプロパティを読み出すという実装はしていません。その後、もちろんグラフィカルオブジェクトのプロパティをファイルに保存し、そこから読み込むことになります。このとき、構造体のフィールドとオブジェクトのプロパティを完全に一致させる必要があります。

クラスのprivateセクションで、グラフィカル要素のプロパティを初期化するための新しいメソッドを宣言します

//--- Save the colors to the background color array
   void              SaveColorsBG(color &colors[])                         { this.CopyArraysColors(this.m_array_colors_bg,colors,DFUN);      }
   void              SaveColorsBGMouseDown(color &colors[])                { this.CopyArraysColors(this.m_array_colors_bg_dwn,colors,DFUN);  }
   void              SaveColorsBGMouseOver(color &colors[])                { this.CopyArraysColors(this.m_array_colors_bg_ovr,colors,DFUN);  }
   void              SaveColorsBGInit(color &colors[])                     { this.CopyArraysColors(this.m_array_colors_bg_init,colors,DFUN); }

//--- Initialize property values
   void              Initialize(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                                const int element_id,const int element_num,
                                const int x,const int y,const int w,const int h,
                                const string descript,const bool movable,const bool activity);

public:

作成されたオブジェクトのプロパティは、メソッドに渡されます。プロパティはコンストラクタごとに異なる値を持つか、コンストラクタの仮パラメータに直接指定される、つまり外部から渡されます。このようなプロパティはすべて、パラメータを介してメソッドに渡すことにします。


各コンストラクタでオブジェクトのプロパティを設定する長いリストを削除し、初期化メソッドの呼び出しに置き換えます

//+---------------------------------------------+
//| Parametric constructor                      |
//+---------------------------------------------+
CGCnvElement::CGCnvElement(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                           CGCnvElement *main_obj,CGCnvElement *base_obj,
                           const int      element_id,
                           const int      element_num,
                           const long     chart_id,
                           const int      wnd_num,
                           const string   descript,
                           const int      x,
                           const int      y,
                           const int      w,
                           const int      h,
                           const color    colour,
                           const uchar    opacity,
                           const bool     movable=true,
                           const bool     activity=true,
                           const bool     redraw=false) : m_shadow(false)
  {
   this.SetTypeElement(element_type);
   this.m_type=OBJECT_DE_TYPE_GELEMENT; 
   this.m_element_main=main_obj;
   this.m_element_base=base_obj;
   this.m_chart_color_bg=(color)::ChartGetInteger((chart_id==NULL ? ::ChartID() : chart_id),CHART_COLOR_BACKGROUND);
   this.m_name=this.CreateNameGraphElement(element_type);
   this.m_chart_id=(chart_id==NULL || chart_id==0 ? ::ChartID() : chart_id);
   this.m_subwindow=wnd_num;
   this.SetFont(DEF_FONT,DEF_FONT_SIZE);
   this.m_text_anchor=0;
   this.m_text_x=0;
   this.m_text_y=0;
   this.SetBackgroundColor(colour,true);
   this.SetOpacity(opacity);
   this.m_shift_coord_x=0;
   this.m_shift_coord_y=0;
   if(::ArrayResize(this.m_array_colors_bg,1)==1)
      this.m_array_colors_bg[0]=this.BackgroundColor();
   if(::ArrayResize(this.m_array_colors_bg_dwn,1)==1)
      this.m_array_colors_bg_dwn[0]=this.BackgroundColor();
   if(::ArrayResize(this.m_array_colors_bg_ovr,1)==1)
      this.m_array_colors_bg_ovr[0]=this.BackgroundColor();
   if(this.Create(chart_id,wnd_num,x,y,w,h,redraw))
     {
      this.Initialize(element_type,element_id,element_num,x,y,w,h,descript,movable,activity);
      this.SetVisibleFlag(false,false);
     }
   else
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),"\"",this.TypeElementDescription(element_type),"\" ",this.NameObj());
     }
  }
//+---------------------------------------------+
//| Protected constructor                       |
//+---------------------------------------------+
CGCnvElement::CGCnvElement(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                           CGCnvElement *main_obj,CGCnvElement *base_obj,
                           const long    chart_id,
                           const int     wnd_num,
                           const string  descript,
                           const int     x,
                           const int     y,
                           const int     w,
                           const int     h) : m_shadow(false)
  {
   this.m_type=OBJECT_DE_TYPE_GELEMENT; 
   this.m_element_main=main_obj;
   this.m_element_base=base_obj;
   this.m_chart_color_bg=(color)::ChartGetInteger((chart_id==NULL ? ::ChartID() : chart_id),CHART_COLOR_BACKGROUND);
   this.m_name=this.CreateNameGraphElement(element_type);
   this.m_chart_id=(chart_id==NULL || chart_id==0 ? ::ChartID() : chart_id);
   this.m_subwindow=wnd_num;
   this.m_type_element=element_type;
   this.SetFont(DEF_FONT,DEF_FONT_SIZE);
   this.m_text_anchor=0;
   this.m_text_x=0;
   this.m_text_y=0;
   this.SetBackgroundColor(CLR_CANV_NULL,true);
   this.SetOpacity(0);
   this.m_shift_coord_x=0;
   this.m_shift_coord_y=0;
   if(::ArrayResize(this.m_array_colors_bg,1)==1)
      this.m_array_colors_bg[0]=this.BackgroundColor();
   if(::ArrayResize(this.m_array_colors_bg_dwn,1)==1)
      this.m_array_colors_bg_dwn[0]=this.BackgroundColor();
   if(::ArrayResize(this.m_array_colors_bg_ovr,1)==1)
      this.m_array_colors_bg_ovr[0]=this.BackgroundColor();
   if(this.Create(chart_id,wnd_num,x,y,w,h,false))
     {
      this.Initialize(element_type,0,0,x,y,w,h,descript,false,false);
      this.SetVisibleFlag(false,false);
     }
   else
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),"\"",this.TypeElementDescription(element_type),"\" ",this.NameObj());
     }
  }
//+------------------------------------------------------------------+

ご覧の通り、それぞれの固有のコンストラクタに固有の値が、両方のコンストラクタの初期化メソッドに渡されます。


新しい初期化メソッドでは、クラスのコンストラクタからプロパティ設定を削除します。

//+---------------------------------------------+
//| Initialize the properties                   |
//+---------------------------------------------+
void CGCnvElement::Initialize(const ENUM_GRAPH_ELEMENT_TYPE element_type,
                              const int element_id,const int element_num,
                              const int x,const int y,const int w,const int h,
                              const string descript,const bool movable,const bool activity)
  {
   this.SetProperty(CANV_ELEMENT_PROP_NAME_RES,this.m_canvas.ResourceName()); // Graphical resource name
   this.SetProperty(CANV_ELEMENT_PROP_CHART_ID,CGBaseObj::ChartID());         // Chart ID
   this.SetProperty(CANV_ELEMENT_PROP_WND_NUM,CGBaseObj::SubWindow());        // Chart subwindow index
   this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,CGBaseObj::Name());            // Element object name
   this.SetProperty(CANV_ELEMENT_PROP_TYPE,element_type);                     // Graphical element type
   this.SetProperty(CANV_ELEMENT_PROP_ID,element_id);                         // Element ID
   this.SetProperty(CANV_ELEMENT_PROP_NUM,element_num);                       // Element index in the list
   this.SetProperty(CANV_ELEMENT_PROP_COORD_X,x);                             // Element's X coordinate on the chart
   this.SetProperty(CANV_ELEMENT_PROP_COORD_Y,y);                             // Element's Y coordinate on the chart
   this.SetProperty(CANV_ELEMENT_PROP_WIDTH,w);                               // Element width
   this.SetProperty(CANV_ELEMENT_PROP_HEIGHT,h);                              // Element height
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,0);                      // Active area offset from the left edge of the element
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP,0);                       // Active area offset from the upper edge of the element
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,0);                     // Active area offset from the right edge of the element
   this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,0);                    // Active area offset from the bottom edge of the element
   this.SetProperty(CANV_ELEMENT_PROP_MOVABLE,movable);                       // Element moveability flag
   this.SetProperty(CANV_ELEMENT_PROP_ACTIVE,activity);                       // Element activity flag
   this.SetProperty(CANV_ELEMENT_PROP_INTERACTION,false);                     // Flag of interaction with the outside environment
   this.SetProperty(CANV_ELEMENT_PROP_ENABLED,true);                          // Element availability flag
   this.SetProperty(CANV_ELEMENT_PROP_RIGHT,this.RightEdge());                // Element right border
   this.SetProperty(CANV_ELEMENT_PROP_BOTTOM,this.BottomEdge());              // Element bottom border
   this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_X,this.ActiveAreaLeft());     // X coordinate of the element active area
   this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y,this.ActiveAreaTop());      // Y coordinate of the element active area
   this.SetProperty(CANV_ELEMENT_PROP_ACT_RIGHT,this.ActiveAreaRight());      // Right border of the element active area
   this.SetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM,this.ActiveAreaBottom());    // Bottom border of the element active area
   this.SetProperty(CANV_ELEMENT_PROP_VISIBLE_AREA_X,0);                      // Visibility scope X coordinate
   this.SetProperty(CANV_ELEMENT_PROP_VISIBLE_AREA_Y,0);                      // Visibility scope Y coordinate
   this.SetProperty(CANV_ELEMENT_PROP_VISIBLE_AREA_WIDTH,w);                  // Visibility scope width
   this.SetProperty(CANV_ELEMENT_PROP_VISIBLE_AREA_HEIGHT,h);                 // Visibility scope height
   this.SetProperty(CANV_ELEMENT_PROP_DISPLAYED,true);                        // Non-hidden control display flag
   this.SetProperty(CANV_ELEMENT_PROP_DISPLAY_STATE,CANV_ELEMENT_DISPLAY_STATE_NORMAL);// Control display state
   this.SetProperty(CANV_ELEMENT_PROP_DISPLAY_DURATION,DEF_CONTROL_PROCESS_DURATION);  // Control display duration
   this.SetProperty(CANV_ELEMENT_PROP_CONTROL_AREA_X,0);                      // Control area X coordinate
   this.SetProperty(CANV_ELEMENT_PROP_CONTROL_AREA_Y,0);                      // Control area Y coordinate
   this.SetProperty(CANV_ELEMENT_PROP_CONTROL_AREA_WIDTH,0);                  // Control area width
   this.SetProperty(CANV_ELEMENT_PROP_CONTROL_AREA_HEIGHT,0);                 // Control area height
   this.SetProperty(CANV_ELEMENT_PROP_SCROLL_AREA_X_RIGHT,0);                 // Right scroll area X coordinate
   this.SetProperty(CANV_ELEMENT_PROP_SCROLL_AREA_Y_RIGHT,0);                 // Right scroll area Y coordinate
   this.SetProperty(CANV_ELEMENT_PROP_SCROLL_AREA_WIDTH_RIGHT,0);             // Right scroll area width
   this.SetProperty(CANV_ELEMENT_PROP_SCROLL_AREA_HEIGHT_RIGHT,0);            // Right scroll area height
   this.SetProperty(CANV_ELEMENT_PROP_SCROLL_AREA_X_BOTTOM,0);                // Bottom scroll area X coordinate
   this.SetProperty(CANV_ELEMENT_PROP_SCROLL_AREA_Y_BOTTOM,0);                // Bottom scroll area Y coordinate
   this.SetProperty(CANV_ELEMENT_PROP_SCROLL_AREA_WIDTH_BOTTOM,0);            // Bottom scroll area width
   this.SetProperty(CANV_ELEMENT_PROP_SCROLL_AREA_HEIGHT_BOTTOM,0);           // Bottom scroll area height
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_LEFT_AREA_WIDTH,0);              // Left edge area width
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_BOTTOM_AREA_WIDTH,0);            // Bottom edge area width
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_RIGHT_AREA_WIDTH,0);             // Right edge area width
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_TOP_AREA_WIDTH,0);               // Top edge area width
   //---
   this.SetProperty(CANV_ELEMENT_PROP_BELONG,ENUM_GRAPH_OBJ_BELONG::GRAPH_OBJ_BELONG_PROGRAM);  // Graphical element affiliation
   this.SetProperty(CANV_ELEMENT_PROP_ZORDER,0);                              // Priority of a graphical object for receiving the event of clicking on a chart
   this.SetProperty(CANV_ELEMENT_PROP_BOLD_TYPE,FW_NORMAL);                   // Font width type
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_STYLE,FRAME_STYLE_NONE);         // Control frame style
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_TOP,0);                     // Control frame top size
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_BOTTOM,0);                  // Control frame bottom size
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_LEFT,0);                    // Control frame left size
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_RIGHT,0);                   // Control frame right size
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_COLOR,this.BackgroundColor());   // Control frame color
   this.SetProperty(CANV_ELEMENT_PROP_AUTOSIZE,false);                        // Flag of the element auto resizing depending on the content
   this.SetProperty(CANV_ELEMENT_PROP_AUTOSIZE_MODE,CANV_ELEMENT_AUTO_SIZE_MODE_GROW); // Mode of the element auto resizing depending on the content
   this.SetProperty(CANV_ELEMENT_PROP_AUTOSCROLL,false);                      // Auto scrollbar flag
   this.SetProperty(CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_W,0);                 // Width of the field inside the element during auto scrolling
   this.SetProperty(CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_H,0);                 // Height of the field inside the element during auto scrolling
   this.SetProperty(CANV_ELEMENT_PROP_DOCK_MODE,CANV_ELEMENT_DOCK_MODE_NONE); // Mode of binding control borders to the container
   this.SetProperty(CANV_ELEMENT_PROP_MARGIN_TOP,0);                          // Top margin between the fields of this and another control
   this.SetProperty(CANV_ELEMENT_PROP_MARGIN_BOTTOM,0);                       // Bottom margin between the fields of this and another control
   this.SetProperty(CANV_ELEMENT_PROP_MARGIN_LEFT,0);                         // Left margin between the fields of this and another control
   this.SetProperty(CANV_ELEMENT_PROP_MARGIN_RIGHT,0);                        // Right margin between the fields of this and another control
   this.SetProperty(CANV_ELEMENT_PROP_PADDING_TOP,0);                         // Top margin inside the control
   this.SetProperty(CANV_ELEMENT_PROP_PADDING_BOTTOM,0);                      // Bottom margin inside the control
   this.SetProperty(CANV_ELEMENT_PROP_PADDING_LEFT,0);                        // Left margin inside the control
   this.SetProperty(CANV_ELEMENT_PROP_PADDING_RIGHT,0);                       // Right margin inside the control
   this.SetProperty(CANV_ELEMENT_PROP_TEXT_ALIGN,ANCHOR_LEFT_UPPER);          // Text position within text label boundaries
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_ALIGN,ANCHOR_LEFT_UPPER);         // Position of the checkbox within control borders
   this.SetProperty(CANV_ELEMENT_PROP_CHECKED,false);                         // Control checkbox status
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_STATE,CANV_ELEMENT_CHEK_STATE_UNCHECKED);  // Status of a control having a checkbox
   this.SetProperty(CANV_ELEMENT_PROP_AUTOCHECK,true);                        // Auto change flag status when it is selected
   //---
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR,CLR_DEF_CHECK_BACK_COLOR);            // Color of control checkbox background
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_OPACITY,CLR_DEF_CHECK_BACK_OPACITY);  // Opacity of the control checkbox background color
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_DOWN,CLR_DEF_CHECK_BACK_MOUSE_DOWN);// Color of control checkbox background when clicking on the control
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_OVER,CLR_DEF_CHECK_BACK_MOUSE_OVER);// Color of control checkbox background when hovering the mouse over the control
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR,CLR_DEF_CHECK_BORDER_COLOR);                // Color of control checkbox frame
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_OPACITY,CLR_DEF_CHECK_BORDER_OPACITY);      // Opacity of the control checkbox frame color
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_DOWN,CLR_DEF_CHECK_BORDER_MOUSE_DOWN);// Color of control checkbox frame when clicking on the control
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_OVER,CLR_DEF_CHECK_BORDER_MOUSE_OVER);// Color of control checkbox frame when hovering the mouse over the control
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR,CLR_DEF_CHECK_FLAG_COLOR);                  // Control checkbox color
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_OPACITY,CLR_DEF_CHECK_FLAG_OPACITY);        // Control checkbox color opacity
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_DOWN,CLR_DEF_CHECK_FLAG_MOUSE_DOWN);  // Control checkbox color when clicking on the control
   this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER,CLR_DEF_CHECK_FLAG_MOUSE_OVER);  // Control checkbox color when hovering the mouse over the control
   this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR,CLR_DEF_FORE_COLOR);                              // Default text color for all control objects
   this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_OPACITY,CLR_DEF_FORE_COLOR_OPACITY);              // Opacity of the default text color for all control objects
   this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN,CLR_DEF_FORE_COLOR_MOUSE_DOWN);        // Default control text color when clicking on the control
   this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER,CLR_DEF_FORE_COLOR_MOUSE_OVER);        // Default control text color when hovering the mouse over the control
   this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_STATE_ON,CLR_DEF_FORE_COLOR);                     // Text color of the control which is on
   this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_STATE_ON_MOUSE_DOWN,CLR_DEF_FORE_COLOR_MOUSE_DOWN);// Default control text color when clicking on the control which is on
   this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_STATE_ON_MOUSE_OVER,CLR_DEF_FORE_COLOR_MOUSE_OVER);// Default control text color when hovering the mouse over the control which is on
   this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_DOWN,this.BackgroundColor());         // Control background color when clicking on the control
   this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_OVER,this.BackgroundColor());         // Control background color when hovering the mouse over the control
   this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_STATE_ON,CLR_DEF_CONTROL_STD_BACK_COLOR_ON);// Background color of the control which is on
   this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_STATE_ON_MOUSE_DOWN,CLR_DEF_CONTROL_STD_BACK_DOWN_ON);// Control background color when clicking on the control which is on
   this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_STATE_ON_MOUSE_OVER,CLR_DEF_CONTROL_STD_BACK_OVER_ON);// Control background color when clicking on the control which is on
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_COLOR_MOUSE_DOWN,CLR_DEF_BORDER_MOUSE_DOWN);          // Control frame color when clicking on the control
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_COLOR_MOUSE_OVER,CLR_DEF_BORDER_MOUSE_OVER);          // Control frame color when hovering the mouse over the control
   this.SetProperty(CANV_ELEMENT_PROP_BUTTON_TOGGLE,false);                                        // Toggle flag of the control featuring a button
   this.SetProperty(CANV_ELEMENT_PROP_BUTTON_STATE,false);                                         // Status of the Toggle control featuring a button
   this.SetProperty(CANV_ELEMENT_PROP_BUTTON_GROUP,false);                                         // Button group flag
   this.SetProperty(CANV_ELEMENT_PROP_LIST_BOX_MULTI_COLUMN,false);                                // Horizontal display of columns in the ListBox control
   this.SetProperty(CANV_ELEMENT_PROP_LIST_BOX_COLUMN_WIDTH,0);                                    // Width of each ListBox control column
   this.SetProperty(CANV_ELEMENT_PROP_TAB_MULTILINE,false);                                        // Several lines of tabs in TabControl
   this.SetProperty(CANV_ELEMENT_PROP_TAB_ALIGNMENT,CANV_ELEMENT_ALIGNMENT_TOP);                   // Location of tabs inside the control
   this.SetProperty(CANV_ELEMENT_PROP_ALIGNMENT,CANV_ELEMENT_ALIGNMENT_TOP);                       // Location of an object inside the control
   this.SetProperty(CANV_ELEMENT_PROP_TEXT,"");                                                    // Graphical element text
   this.SetProperty(CANV_ELEMENT_PROP_DESCRIPTION,descript);                                       // Graphical element description
   this.SetProperty(CANV_ELEMENT_PROP_SPLIT_CONTAINER_FIXED_PANEL,0);                              // Panel that retains its size when the container is resized
   this.SetProperty(CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_FIXED,true);                        // Separator moveability flag
   this.SetProperty(CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_DISTANCE,50);                       // Distance from edge to separator
   this.SetProperty(CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_WIDTH,4);                           // Separator width
   this.SetProperty(CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_ORIENTATION,0);                     // Separator location
   this.SetProperty(CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_COLLAPSED,false);                     // Flag for collapsed panel 1
   this.SetProperty(CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_MIN_SIZE,25);                         // Panel 1 minimum size
   this.SetProperty(CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_COLLAPSED,false);                     // Flag for collapsed panel 1
   this.SetProperty(CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_MIN_SIZE,25);                         // Panel 2 minimum size
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_INITIAL_DELAY,500);                                  // Tooltip display delay
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_AUTO_POP_DELAY,5000);                                // Tooltip display duration
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_RESHOW_DELAY,100);                                   // One element new tooltip display delay
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_SHOW_ALWAYS,false);                                  // Display a tooltip in inactive window
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_ICON,CANV_ELEMENT_TOOLTIP_ICON_NONE);                // Icon displayed in a tooltip
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_IS_BALLOON,false);                                   // Tooltip in the form of a "cloud"
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_USE_FADING,true);                                    // Fade when showing/hiding a tooltip
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_TITLE,"");                                           // Tooltip title for the element
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_TEXT,"");                                            // Tooltip text for the element
   this.SetProperty(CANV_ELEMENT_PROP_GROUP,0);                               // Group the graphical element belongs to
   this.SetProperty(CANV_ELEMENT_PROP_TAB_SIZE_MODE,CANV_ELEMENT_TAB_SIZE_MODE_NORMAL);// Tab size setting mode
   this.SetProperty(CANV_ELEMENT_PROP_TAB_PAGE_NUMBER,0);                     // Tab index number
   this.SetProperty(CANV_ELEMENT_PROP_TAB_PAGE_ROW,0);                        // Tab row index
   this.SetProperty(CANV_ELEMENT_PROP_TAB_PAGE_COLUMN,0);                     // Tab column index
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MAXIMUM,100);              // The upper bound of the range ProgressBar operates in
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MINIMUM,0);                // The lower bound of the range ProgressBar operates in
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STEP,10);                  // ProgressBar increment needed to redraw it
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STYLE,CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS); // ProgressBar style
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE,50);                 // Current ProgressBar value from Min to Max
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MARQUEE_ANIM_SPEED,10);    // Progress bar animation speed in case of Marquee style
  }
//+------------------------------------------------------------------+

ここでは、クラスのコンストラクタから削除された文字列を単純に移動しています。コンストラクタによって異なっていたプロパティ値が、メソッドの仮パラメータによってオブジェクトのプロパティに渡され、設定されるようになりました。


オブジェクト構造体を作成するメソッドで、新しい構造体フィールドに適切なグラフィック要素プロパティ値を設定するようにします

//+---------------------------------------------+
//| Create the object structure                 |
//+---------------------------------------------+
bool CGCnvElement::ObjectToStruct(void)
  {
//--- Save integer properties
   this.m_struct_obj.id=(int)this.GetProperty(CANV_ELEMENT_PROP_ID);                               // Element ID
   this.m_struct_obj.type=(int)this.GetProperty(CANV_ELEMENT_PROP_TYPE);                           // Graphical element type
   this.m_struct_obj.belong=(int)this.GetProperty(CANV_ELEMENT_PROP_BELONG);                       // Graphical element affiliation
   this.m_struct_obj.number=(int)this.GetProperty(CANV_ELEMENT_PROP_NUM);                          // Element ID in the list

   //---...
   //---...

   this.m_struct_obj.border_right_area_width=(int)this.GetProperty(CANV_ELEMENT_PROP_BORDER_RIGHT_AREA_WIDTH);    // Right edge area width
   this.m_struct_obj.border_top_area_width=(int)this.GetProperty(CANV_ELEMENT_PROP_BORDER_TOP_AREA_WIDTH);        // Top edge area width
   //---
   this.m_struct_obj.tooltip_initial_delay=this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_INITIAL_DELAY);    // Tooltip display delay
   this.m_struct_obj.tooltip_auto_pop_delay=this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_AUTO_POP_DELAY);  // Tooltip display duration
   this.m_struct_obj.tooltip_reshow_delay=this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_RESHOW_DELAY);      // One element new tooltip display delay
   this.m_struct_obj.tooltip_show_always=this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_SHOW_ALWAYS);        // Display a tooltip in inactive window
   this.m_struct_obj.tooltip_icon=(int)this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_ICON);                 // Icon displayed in the tooltip
   this.m_struct_obj.tooltip_is_balloon=(bool)this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_IS_BALLOON);    // Balloon tooltip
   this.m_struct_obj.tooltip_use_fading=(bool)this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_USE_FADING);    // Fade when showing and hiding the tooltip
      //---
   this.m_struct_obj.group=(int)this.GetProperty(CANV_ELEMENT_PROP_GROUP);                               // Group the graphical element belongs to
   this.m_struct_obj.tab_size_mode=(int)this.GetProperty(CANV_ELEMENT_PROP_TAB_SIZE_MODE);               // Tab size setting mode
   this.m_struct_obj.tab_page_number=(int)this.GetProperty(CANV_ELEMENT_PROP_TAB_PAGE_NUMBER);           // Tab index number
   this.m_struct_obj.tab_page_row=(int)this.GetProperty(CANV_ELEMENT_PROP_TAB_PAGE_ROW);                 // Tab row index
   this.m_struct_obj.tab_page_column=(int)this.GetProperty(CANV_ELEMENT_PROP_TAB_PAGE_COLUMN);           // Tab column index
   this.m_struct_obj.progress_bar_maximum=(int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MAXIMUM); // The upper bound of the range ProgressBar operates in
   this.m_struct_obj.progress_bar_minimum=(int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MINIMUM); // The lower bound of the range ProgressBar operates in
   this.m_struct_obj.progress_bar_step=(int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STEP);       // ProgressBar increment needed to redraw it
   this.m_struct_obj.progress_bar_style=(int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STYLE);     // ProgressBar style
   this.m_struct_obj.progress_bar_value=(int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE);     // Current ProgressBar value from Min to Max
   this.m_struct_obj.progress_bar_marquee_speed=(int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MARQUEE_ANIM_SPEED);// Progress bar animation speed in case of Marquee style
//--- Save real properties

//--- Save string properties
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_NAME_OBJ),this.m_struct_obj.name_obj);   // Graphical element object name
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_NAME_RES),this.m_struct_obj.name_res);   // Graphical resource name
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_TEXT),this.m_struct_obj.text);           // Graphical element text
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_DESCRIPTION),this.m_struct_obj.descript);// Graphical element description
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_TITLE),this.m_struct_obj.tooltip_title);// Tooltip title for the element
   ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_TEXT),this.m_struct_obj.tooltip_text);  // Tooltip text for the element
   //--- Save the structure to the uchar array
   ::ResetLastError();
   if(!::StructToCharArray(this.m_struct_obj,this.m_uchar_array))
     {
      CMessage::ToLog(DFUN,MSG_LIB_SYS_FAILED_SAVE_OBJ_STRUCT_TO_UARRAY,true);
      return false;
     }
   return true;
  }
//+------------------------------------------------------------------+


構造体からオブジェクトを生成するメソッドで、現在の記事で追加された対応する構造体フィールドからオブジェクトプロパティを設定するようにします

//+---------------------------------------------+
//| Create the object from the structure        |
//+---------------------------------------------+
void CGCnvElement::StructToObject(void)
  {
//--- Save integer properties
   this.SetProperty(CANV_ELEMENT_PROP_ID,this.m_struct_obj.id);                                    // Element ID
   this.SetProperty(CANV_ELEMENT_PROP_TYPE,this.m_struct_obj.type);                                // Graphical element type
   this.SetProperty(CANV_ELEMENT_PROP_BELONG,this.m_struct_obj.belong);                            // Graphical element affiliation
   this.SetProperty(CANV_ELEMENT_PROP_NUM,this.m_struct_obj.number);                               // Element index in the list

   //---...
   //---...

   this.SetProperty(CANV_ELEMENT_PROP_BORDER_RIGHT_AREA_WIDTH,this.m_struct_obj.border_right_area_width);      // Right edge area width
   this.SetProperty(CANV_ELEMENT_PROP_BORDER_TOP_AREA_WIDTH,this.m_struct_obj.border_top_area_width);          // Top edge area width
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_INITIAL_DELAY,this.m_struct_obj.tooltip_initial_delay);             // Tooltip display delay
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_AUTO_POP_DELAY,this.m_struct_obj.tooltip_auto_pop_delay);// Tooltip display duration
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_RESHOW_DELAY,this.m_struct_obj.tooltip_reshow_delay);// One element new tooltip display delay
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_SHOW_ALWAYS,this.m_struct_obj.tooltip_show_always);// Display a tooltip in inactive window
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_ICON,this.m_struct_obj.tooltip_icon);              // Icon displayed in a tooltip
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_IS_BALLOON,this.m_struct_obj.tooltip_is_balloon);  // Balloon tooltip
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_USE_FADING,this.m_struct_obj.tooltip_use_fading);  // Fade when showing/hiding a tooltip
   this.SetProperty(CANV_ELEMENT_PROP_GROUP,this.m_struct_obj.group);                            // Group the graphical element belongs to
   this.SetProperty(CANV_ELEMENT_PROP_TAB_SIZE_MODE,this.m_struct_obj.tab_size_mode);            // Tab size setting mode
   this.SetProperty(CANV_ELEMENT_PROP_TAB_PAGE_NUMBER,this.m_struct_obj.tab_page_number);        // Tab index number
   this.SetProperty(CANV_ELEMENT_PROP_TAB_PAGE_ROW,this.m_struct_obj.tab_page_row);              // Tab row index
   this.SetProperty(CANV_ELEMENT_PROP_TAB_PAGE_COLUMN,this.m_struct_obj.tab_page_column);        // Tab column index
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MAXIMUM,this.m_struct_obj.progress_bar_maximum);// The upper bound of the range ProgressBar operates in
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MINIMUM,this.m_struct_obj.progress_bar_minimum);// The lower bound of the range ProgressBar operates in
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STEP,this.m_struct_obj.progress_bar_step);    // ProgressBar increment needed to redraw it
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STYLE,this.m_struct_obj.progress_bar_style);  // ProgressBar style
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE,this.m_struct_obj.progress_bar_value);  // Current ProgressBar value from Min to Max
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MARQUEE_ANIM_SPEED,this.m_struct_obj.progress_bar_marquee_speed);  // Progress bar animation speed in case of Marquee style
//--- Save real properties

//--- Save string properties
   this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,::CharArrayToString(this.m_struct_obj.name_obj));   // Graphical element object name
   this.SetProperty(CANV_ELEMENT_PROP_NAME_RES,::CharArrayToString(this.m_struct_obj.name_res));   // Graphical resource name
   this.SetProperty(CANV_ELEMENT_PROP_TEXT,::CharArrayToString(this.m_struct_obj.text));           // Graphical element text
   this.SetProperty(CANV_ELEMENT_PROP_DESCRIPTION,::CharArrayToString(this.m_struct_obj.descript));// Graphical element description
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_TITLE,::CharArrayToString(this.m_struct_obj.tooltip_title));// Tooltip title for the element
   this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_TEXT,::CharArrayToString(this.m_struct_obj.tooltip_text));  // Tooltip text for the element
  }
//+------------------------------------------------------------------+

これで、グラフィック要素オブジェクトが正しくファイルに保存され、ファイルから復元されるようになりました。


プログレスバーに沿ったグレアは、平行六面体のような形状になることがあります。これは、上面の頂点が下面の頂点から6ピクセル分ずれた、傾いた四角形です。小さなオブジェクトの場合、このオフセットでオブジェクトがかなり傾いて見えるようになりますが、高さが増すと、6ピクセルに固定された傾きでは見分けがつかなくなります。この状況を改善するためには、傾きを相対的な値にする必要があります。つまり、高いオブジェクトほど傾きが強くなります。そこで、頂点のオフセットの大きさを設定するために、オブジェクトの高さを使用します。そうすると、視覚的には45度の傾きになります。

\MQL5\Include\DoEasy\Objects\Graph\WForms\GlareObj.mqhにある、オブジェクトのグレア形状を平行四辺形で描画するメソッドで、頂点座標のパラメータの初期化を修正しました。数値6の代わりに、グラフィカルオブジェクトの高さの値を代入します

//+------------------------------------------------------------------+
//| Draw the shape of the object glare as a parallelogram            |
//+------------------------------------------------------------------+
void CGlareObj::DrawFigureParallelogram(void)
  {
   int array_x[]={this.Height(),this.Width()-1,this.Width()-1-this.Height(),0};
   int array_y[]={0,0,this.Height()-1,this.Height()-1};
   CGCnvElement::DrawPolygonFill(array_x,array_y,this.m_color,this.OpacityDraw());
   CGCnvElement::Update();
  }
//+------------------------------------------------------------------+

これで、頂点はオブジェクトの高さの値だけオフセットされ、オブジェクトの高さに関係なく、常に約45度の傾きを持つようになります。


各ブロックを直接作成したり、単純に描画したりと、さまざまなオプションを使って「分割ブロック」式のプログレスバーを作成することができます。これは、次のようにおこなうつもりです。すでに完全に塗りつぶされたプログレスバーがあるので、ブロックがないところだけこのオブジェクトの背景を消せばいいのです。この場合、分割されたブロックからなるプログレスバーの外観を得ることができます。この方法の欠点は各ブロックの位置を計算する必要があることで、利点は実装が簡単であることです。

\MQL5\Include\DoEasy\Objects\Graph\WForms\Helpers\BarProgressBar.mqhのprivateセクションで、セグメントパラメータ格納用変数を追加してオブジェクト背景分割用メソッドを宣言します

//+------------------------------------------------------------------+
//| BarProgressBar object class of the ProgressBar control           |
//+------------------------------------------------------------------+
class CBarProgressBar : public CWinFormBase
  {
private:
   int               m_segment_s;                                 // Segment countdown start
   int               m_segment_x;                                 // Last segment X coordinate
   int               m_segment_w;                                 // Segment width
   int               m_segment_d;                                 // Distance between segments
//--- Segment the background
   void              Segmentation(void);
//--- (1) Set and (2) return a pause before displaying the effect
   void              SetShowDelay(const long delay)               { this.SetProperty(CANV_ELEMENT_PROP_TOOLTIP_RESHOW_DELAY,delay);             }
   ulong             ShowDelay(void)                              { return this.GetProperty(CANV_ELEMENT_PROP_TOOLTIP_RESHOW_DELAY);            }
//--- Initialize the properties
   void              Initialize(void);
protected:
//--- Protected constructor with object type, chart ID and subwindow
                     CBarProgressBar(const ENUM_GRAPH_ELEMENT_TYPE type,
                                     CGCnvElement *main_obj,CGCnvElement *base_obj,
                                     const long chart_id,
                                     const int subwindow,
                                     const string descript,
                                     const int x,
                                     const int y,
                                     const int w,
                                     const int h);
public:

宣言された変数には、セグメントの位置を計算するための初期パラメータが含まれます。セグメントの幅は常に高さの3/4となり、セグメント間の距離は結果として得られるセグメントの幅から計算されます。このデータは、オブジェクトの初期化時に記録され、その番号によって任意のセグメントの位置を計算することができるようになります。セグメントそのものを描くのではなく、セグメント間のスペースを描くので、開始点は0から数えても1から数えても最初のセグメントの幅となります。プログレスバーの高さが3ピクセル以上の場合は、オブジェクトの端の四方に1ピクセルの空白を描画する必要があります。これにより、セグメントとバーの外側の端が分離され、視覚的に独立した単位になります。この場合、最初のセグメントのインデントは、オブジェクトの端から最初のセグメントまでの1ピクセルの空白である1から開始する必要があります。プログレスバーの高さが3ピクセル以下であれば、空白を描く必要はなく、セグメントが描かれたオブジェクトの使用可能領域全体を占めることになります。この場合、最初のセグメントの開始点までのインデントは0でなければなりません。

クラスのpublicセクションに、プログレスバーのスタイルを返すメソッドと、セグメントの変数パラメータの値を返すメソッドを実装しますセグメントの幅とその間の距離を計算するメソッドを宣言してみましょうまた、オブジェクトの背景をクリアするための仮想メソッドも再定義する必要があります

public:
//--- Set the (1) animation speed in case of Marquee style, (2) display style, (3) increment value and (4) the current value of the ProgressBar control
   void              SetMarqueeAnimationSpeed(const int value)    { this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MARQUEE_ANIM_SPEED,value);  }
   void              SetStyle(const ENUM_CANV_ELEMENT_PROGRESS_BAR_STYLE style) { this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STYLE,style); }
   void              SetStep(const int value)                     { this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STEP,value);                }
   void              SetValue(const int value)                    { this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE,value);               }
   
//--- Return the display style
   ENUM_CANV_ELEMENT_PROGRESS_BAR_STYLE Style(void) const
                       { return (ENUM_CANV_ELEMENT_PROGRESS_BAR_STYLE)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_STYLE); }

//--- Return (1) the X coordinate of the last segment, (2) segment width, (3) distance between segments and (4) segment countdown start
   int               SegmentX(void)                         const { return this.m_segment_x; }
   int               SegmentWidth(void)                     const { return this.m_segment_w; }
   int               SegmentDistance(void)                  const { return this.m_segment_d; }
   int               SegmentStart(void)                     const { return this.m_segment_s; }
   
//--- Calculate (1) the segment width and (2) the distance between segments
   int               CalculateSegmentWidth(void);
   int               CalculateSegmentDistance(const int width);

//--- Supported object properties (1) integer, (2) real and (3) string ones
   virtual bool      SupportProperty(ENUM_CANV_ELEMENT_PROP_INTEGER property) { return true; }
   virtual bool      SupportProperty(ENUM_CANV_ELEMENT_PROP_DOUBLE property)  { return true; }
   virtual bool      SupportProperty(ENUM_CANV_ELEMENT_PROP_STRING property)  { return true; }

//--- 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);
   
//--- Constructor
                     CBarProgressBar(CGCnvElement *main_obj,CGCnvElement *base_obj,
                                     const long chart_id,
                                     const int subwindow,
                                     const string descript,
                                     const int x,
                                     const int y,
                                     const int w,
                                     const int h);
//--- Timer
   virtual void      OnTimer(void);
  };
//+------------------------------------------------------------------+

クリアメソッドでは、要素の背景がその背景色で塗りつぶされます。そのため、塗りつぶした後、セグメント間の隙間の背景を除去する必要があります。これらのメソッドでは、描画されたオブジェクトの背景を分割するために、privateセクションで宣言されたメソッドを呼び出すことになります。これらは仮想なので、オブジェクトがプログレスバーやそれから継承されたものであれば、クリーニングメソッドを呼び出す際に必ずこれらのメソッドが呼び出されることになります。

オブジェクトプロパティ初期化メソッドで、セグメンテーションパラメータを格納する変数のデフォルト値を入力します。最後のセグメントのx座標とカウントダウン開始はゼロに等しくセグメント幅とその間の距離は一度に計算されます

//+---------------------------------------------+
//| Initialize the properties                   |
//+---------------------------------------------+
void CBarProgressBar::Initialize(void)
  {
   this.SetPaddingAll(0);
   this.SetMarginAll(0);
   this.SetBorderSizeAll(0);
   this.SetBackgroundColor(CLR_DEF_CONTROL_PROGRESS_BAR_BAR_COLOR,true);
   this.SetBorderColor(CLR_DEF_CONTROL_PROGRESS_BAR_BAR_COLOR,true);
   this.SetForeColor(CLR_DEF_CONTROL_PROGRESS_BAR_FORE_COLOR,true);
   this.SetShowDelay(2000);
   this.m_segment_x=0;
   this.m_segment_s=0;
   this.m_segment_w=this.CalculateSegmentWidth();
   this.m_segment_d=this.CalculateSegmentDistance(this.m_segment_w);
  }
//+------------------------------------------------------------------+


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

以下は、色と不透明度を指定して要素をクリアするメソッドです。

//+------------------------------------------------------------------+
//| Clear the element filling it with color and opacity              |
//+------------------------------------------------------------------+
void CBarProgressBar::Erase(const color colour,const uchar opacity,const bool redraw=false)
  {
//--- Fill the element having the specified color and the redrawing flag
   CGCnvElement::EraseNoCrop(colour,opacity,false);
//--- Segment the background
   this.Segmentation();
//--- If the object has a frame, draw it
   if(this.BorderStyle()!=FRAME_STYLE_NONE)
      this.DrawFormFrame(this.BorderSizeTop(),this.BorderSizeBottom(),this.BorderSizeLeft(),this.BorderSizeRight(),this.BorderColor(),this.Opacity(),this.BorderStyle());
//--- Crop the excess and update the element with the specified redraw flag
   this.Crop();
   this.Update(redraw);
  }
//+------------------------------------------------------------------+

ここでは、まず要素の背景全体が塗りつぶされます。そして、セグメンテーションメソッドが呼び出され、オブジェクトの中でセグメントがない場所の背景を消去します。オブジェクトがフレームを持つ場合は、フレームが描画されます。オブジェクトの親コンテナからはみ出した部分が切り取られ、オブジェクトの背景がメソッドに渡されたチャート再描画フラグで更新されます。

以下は、グラデーションで塗りつぶされた要素をクリアするメソッドです。

//+---------------------------------------------+
//| Clear the element with a gradient fill      |
//+---------------------------------------------+
void CBarProgressBar::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::EraseNoCrop(colors,opacity,vgradient,cycle,false);
//--- Segment the background
   this.Segmentation();
//--- If the object has a frame, draw it
   if(this.BorderStyle()!=FRAME_STYLE_NONE)
      this.DrawFormFrame(this.BorderSizeTop(),this.BorderSizeBottom(),this.BorderSizeLeft(),this.BorderSizeRight(),this.BorderColor(),this.Opacity(),this.BorderStyle());
//--- Crop the excess and update the element with the specified redraw flag
   this.Crop();
   this.Update(redraw);
  }
//+------------------------------------------------------------------+

メソッドのロジックは上記のメソッドと同じですが、メソッドに渡されるのは単色ではなく、グラデーション塗りの色配列その方向フラグ(垂直/水平周期的)であることが異なります。


以下は、セグメントの幅を計算するメソッドです。

//+---------------------------------------------+
//| Calculate the segment width                 |
//+---------------------------------------------+
int CBarProgressBar::CalculateSegmentWidth(void)
  {
   int w=(int)::ceil((this.Height()-2)/1.75);
   return(w>3 ? w : 3);
  }
//+------------------------------------------------------------------+

セグメントの幅は高さの3分の2でなければなりません。このメソッドでは、プログレスバーオブジェクトの高さをもとにセグメントの幅を計算します。オブジェクトの高さから2ピクセルを引いた値をとってみましょう。より多くの場合、プログレスバーの高さは3ピクセル以上になるため、プログレスバーの周囲に沿って両側に1ピクセルずつの空き領域が描かれ、セグメントの可視部の高さが2ピクセル(上と下に1ピクセルずつ)減少することになります。出来上がった高さを1.75で割ると、アスペクト比が3/4になります。高さが小さすぎるセグメントは幅が1~2ピクセルになると見栄えが悪くなるので、結果の幅が3ピクセルに満たない場合は、幅を3ピクセルにします。


以下は、セグメント間の距離を計算するメソッドです。

//+---------------------------------------------+
//| Calculate the distance between segments     |
//+---------------------------------------------+
int CBarProgressBar::CalculateSegmentDistance(const int width)
  {
   int d=(int)::ceil(width/6);
   return(d<1 ? 1 : d);
  }
//+------------------------------------------------------------------+

簡単なことです。このメソッドは、インデントが計算されるべき幅を受け取ります。セグメント間の距離はブロックの幅の6分の1で、1ピクセル以上でなければなりません。


以下は、背景のセグメンテーションメソッドです。

//+---------------------------------------------+
//| Segment the background                      |
//+---------------------------------------------+
void CBarProgressBar::Segmentation(void)
  {
//--- If the drawing style is not "Segmented blocks", leave
   if(this.Style()!=CANV_ELEMENT_PROGRESS_BAR_STYLE_BLOCKS)
      return;
//--- Reset the X coordinate of the segment
   this.m_segment_x=0;
//--- Get the block width as 3/4 of its height
   int w=this.SegmentWidth();
//--- Get the distance between the segments (six times less than the block width)
   int d=this.SegmentDistance();
//--- Get the countdown start
   this.m_segment_s=w+(this.Height()>3 ? 1 : 0);
//--- In the loop from the beginning of the countdown to the width of the progress bar with a step in the block width + indent between segments
   for(int i=this.SegmentStart();i<this.Width();i+=w+d)
     {
      //--- draw an empty fully transparent rectangle (erasing the element background)
      this.DrawRectangleFill(i,0,i+d-1,this.Height()-1,CLR_CANV_NULL,0);
      //--- Store the X coordinate of the segment
      this.m_segment_x=i;
     }
//--- If the height of the progress line is more than three pixels, draw a completely transparent frame around the perimeter
   if(this.Height()>3)
      this.DrawRectangle(0,0,this.Width()-1,this.Height()-1,CLR_CANV_NULL,0);
  }
//+------------------------------------------------------------------+

メソッドのロジックはコードのコメントで完全に説明されています。プログレスバーのスタイルが「分割ブロック」の場合、ループでオブジェクトの背景全体を調べ、セグメントがない所の背景を消します。オブジェクトの高さが3ピクセル以上の場合は、さらに周囲に沿った背景を1ピクセル幅の境界線で消去し、セグメントをプログレスバーの端から分離させます。


ProgressBarオブジェクトに、プログレスバーに表示される説明を含める機能を追加します。デフォルトでは、説明は表示されませんが、説明を有効にするためにテキストを定義するだけで十分です。説明は、オブジェクトに恒久的に添付されたCLabelオブジェクトによって構築されます。もちろん、そのようなオブジェクトをいくつでも作り、適材適所に配置することが可能になりますが、プログレスバーの説明オブジェクトは、ProgressBarの作成時にデフォルトで作成され、特別なメソッドを使用してアクセスすることが容易になります。

MQL5\Include\DoEasy\Objects\Graph\WForms\Common Controls\ProgressBar.mqh CProgressBarクラスファイルで、不要になったスキップステップ数を格納する変数をprivateセクションから削除しました

//+------------------------------------------------------------------+
//| ArrowLeftRightBox object class of WForms controls                |
//+------------------------------------------------------------------+
class CProgressBar : public CContainer
  {
private:
   int               m_progress_bar_max;  // Maximum progress bar width
   int               m_value_by_max;      // Value relative to Maximum
   int               m_steps_skipped;     // Number of skipped steps of increasing the width of the progress bar

//--- Create a new graphical object


また、privateセクションで、プログレスバーの説明のあるテキストラベルのプロパティを格納するための変数を宣言します

//+------------------------------------------------------------------+
//| ArrowLeftRightBox object class of WForms controls                |
//+------------------------------------------------------------------+
class CProgressBar : public CContainer
  {
private:
   int               m_progress_bar_max;           // Maximum progress bar width
   int               m_value_by_max;               // Value relative to Maximum
   int               m_progress_bar_text_x;        // X coordinate of the text label with the description of the progress bar
   int               m_progress_bar_text_y;        // Y coordinate of the text label with the description of the progress bar
   color             m_progress_bar_text_color;    // Color of the text describing the progress bar
   uchar             m_progress_bar_text_opacity;  // Opacity of the text describing the progress bar
   string            m_progress_bar_text;          // Text describing the progress bar
   ENUM_FRAME_ANCHOR m_progress_bar_text_anchor;   // Method for binding the text with a progress bar description
//--- Create a new graphical object

この変数は、プログレスバーの説明として機能するテキストラベルオブジェクトのプロパティを設定したり、返したりするために必要です。


説明行に表示されるデータは、実行の各ステップを表示する実データと、すでに完了したステップの割合のいずれかを選択できます。

クラスのpublicセクションで、値をテキストとして返すメソッドと、数値テキスト形式の割合を返すメソッドを実装します。

//--- (1) Set and (2) return the current value of the progress bar in the range from Min to Max as a number and (3) as a text
   void              SetValue(const int value);
   int               Value(void)                         const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE);   }
   string            ValueDescription(void)              const { return (string)this.Value();                                          }
//--- Return the current progress bar value in the range from Min to Max as a percentage in the form of (1) a number and (2) a text
   double            ValuePercent(void) const;
   string            ValuePercentDescription(void)       const { return ::DoubleToString(this.ValuePercent(),2)+"%";                   }
   
//--- (1) Set and (2) return the upper bound of the ProgressBar operating range


グレアのオブジェクトへのアクセスを簡略化するため、クラスのpublicセクションに、グレアのプロパティを設定するメソッドと、作成した添付オブジェクトへのポインタを取得するメソッドを宣言し、プログレスバー説明オブジェクトを扱うメソッドを宣言します

//--- (1) Set and (2) return the lower bound of the ProgressBar operating range
   void              SetMinimum(const int value)               { this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MINIMUM,value);       }
   int               Minimum(void)                       const { return (int)this.GetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_MINIMUM); }
   
//--- Set (1) style, (2) opacity and (3) color for the glare object
   void              SetGlareStyle(const ENUM_CANV_ELEMENT_VISUAL_EFF_STYLE style);
   void              SetGlareOpacity(const uchar opacity);
   void              SetGlareColor(const color clr);

//--- Return the pointer to the (1) progress bar object, (2) glare object and (3) the text label object with the progress bar description
   CBarProgressBar  *GetProgressBar(void)                { return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR,0);     }
   CGlareObj        *GetGlareObj(void)                   { return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ,0);            }
   CLabel           *GetProgressDescriptionObj(void)     { return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_LABEL,0);                }

//--- Set the (1) text, (2) color
//--- (3) opacity, (4) X, (5) Y coordinates, (6) font, (7) size and (8) font flags to the progress bar text label
   void              SetBarDescriptionText(const string text,const bool redraw=false);
   void              SetBarDescriptionColor(const color clr,const bool redraw=false,const bool set_init_color=false);
   void              SetBarDescriptionOpacity(const uchar opacity,const bool redraw=false);
   void              SetBarDescriptionX(const int x,const bool redraw=false);
   void              SetBarDescriptionY(const int y,const bool redraw=false);
   void              SetBarDescriptionFontName(const string font,const bool redraw=false);
   void              SetBarDescriptionFontSize(const int size,const bool relative=false,const bool redraw=false);
   void              SetBarDescriptionFontFlags(const uint flags,const bool redraw=false);
   
//--- (1) hide and (2) display the progress bar text label
   void              HideBarDescription(void);
   void              ShowBarDescription(void);
     
//--- Resets the progress bar values to the set minimum


クラスコンストラクタで、すべての変数をデフォルト値で初期化します。

//+---------------------------------------------+
//| Initialize the element properties           |
//+---------------------------------------------+
void CProgressBar::Initialize(void)
  {
   this.SetBorderSizeAll(1);
   this.SetBorderStyle(FRAME_STYLE_SIMPLE);
   this.SetBackgroundColor(CLR_DEF_CONTROL_PROGRESS_BAR_BACK_COLOR,true);
   this.SetBorderColor(CLR_DEF_CONTROL_PROGRESS_BAR_BORDER_COLOR,true);
   this.SetForeColor(CLR_DEF_CONTROL_PROGRESS_BAR_FORE_COLOR,true);
   this.SetMarqueeAnimationSpeed(10);
   this.SetMaximum(100);
   this.SetMinimum(0);
   this.SetValue(50);
   this.SetStep(10);
   this.SetStyle(CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS);
   this.m_progress_bar_max=this.Width()-this.BorderSizeLeft()-this.BorderSizeRight();
   this.m_value_by_max=this.Value()*100/this.Maximum();
   this.m_progress_bar_text="";
   this.m_progress_bar_text_x=1;
   this.m_progress_bar_text_y=0;
   this.m_progress_bar_text_color=CLR_DEF_CONTROL_PROGRESS_BAR_FORE_COLOR;
   this.m_progress_bar_text_opacity=255;
   this.m_progress_bar_text_anchor=FRAME_ANCHOR_LEFT_TOP;
  }
//+------------------------------------------------------------------+


プログレスバーオブジェクトを作成するメソッドでは、グレアオブジェクトも作成します。また、プログレスバーの説明オブジェクトも追加して作成します

//+---------------------------------------------+
//| Create the progress bar object              |
//+---------------------------------------------+
void CProgressBar::CreateProgressBar(void)
  {
//--- Set the length of the progress bar equal to the object Value()
//--- The height of the progress bar is set equal to the height of the object minus the top and bottom border sizes
   int w=this.CalculateProgressBarWidth();
   int h=this.Height()-this.BorderSizeTop()-this.BorderSizeBottom();
   if(h<1)
      h=1;
//--- Create the progress bar object
   this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR,0,0,w,h,clrNONE,255,false,false);
//--- Create a description of the progress bar, get the text label object and set the default parameters
   this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_LABEL,1,0,this.Width()-2,this.Height()-2,clrNONE,0,false,false);
   CLabel *obj=this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_LABEL,0);
   if(obj!=NULL)
     {
      obj.SetText(this.m_progress_bar_text);
      obj.SetFontName(DEF_FONT);
      obj.SetFontSize(DEF_FONT_SIZE);
      obj.SetTextAnchor(FRAME_ANCHOR_LEFT_TOP);
      obj.SetTextAlign(ANCHOR_LEFT_UPPER);
      this.HideBarDescription();
     }
//--- Create the glare object
   this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ,0,0,w,h,CLR_CANV_NULL,0,true,false);
//--- Add the current CProgressBar object to the list of active elements of the collection
   this.AddObjToListActiveElements();
  }
//+------------------------------------------------------------------+

テキストラベルを作成した直後に、このオブジェクトへのポインタを取得し、テキスト、フォント名、フォントサイズ、アンカー方法、テキストアライメントなどのプロパティを設定し、作成したオブジェクトを非表示にします。オブジェクトの残りのパラメータは、後でGetProgressDescriptionObj()メソッドでこのオブジェクトへのポインタを取得し、既に受信しているオブジェクトに必要なプロパティを設定することで取得できます。
オブジェクトをゼロサイズで作成することができないため、高さが1ピクセル未満のプログレスバーオブジェクトを作成しようとしてもうまくいきません。そこで、ゼロサイズに対するチェックを導入し、チェックが肯定的な場合に調整することにします


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

//+---------------------------------------------+
//| Create a new graphical object               |
//+---------------------------------------------+
CGCnvElement *CProgressBar::CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type,
                                             const int obj_num,
                                             const string descript,
                                             const int x,
                                             const int y,
                                             const int w,
                                             const int h,
                                             const color colour,
                                             const uchar opacity,
                                             const bool movable,
                                             const bool activity)
  {
   CGCnvElement *element=NULL;
   switch(type)
     {
      case GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR  :
         element=new CBarProgressBar(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h);
        break;
      case GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ         :
         element=new CGlareObj(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h);
        break;
      case GRAPH_ELEMENT_TYPE_WF_LABEL             :
         element=new CLabel(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h);
        break;
      default:
        break;
     }
   if(element==NULL)
      ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.TypeElementDescription(type));
   return element;
  }
//+------------------------------------------------------------------+

これで、ProgressBarオブジェクトは、ProgressBar、Glare、結合されたテキストラベル型のオブジェクトを作成できるようになりました。


ProgressBarオブジェクトは、タイマーの中で扱われるアクティブコントロールです。今のところ、タイマーはプログレスバーに沿って流れるグレアに対応しています。Marqueeスタイルで表示されるプログレスバーもタイマーで処理することになります。このモードでは、プログレスバーはオブジェクト全体の半分の幅で固定され、ProgressBarオブジェクトの内部で常にスクロールし、繰り返し回数が事前にわからない処理の進行状況を表示します。

オブジェクトタイマーハンドラに、以下のようなプログレスバーの処理を追加してみましょう。

//+---------------------------------------------+
//| Timer                                       |
//+---------------------------------------------+
void CProgressBar::OnTimer(void)
  {
   CBarProgressBar *bar=this.GetProgressBar();
   if(bar!=NULL)
     {
      if(bar.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_MARQUEE)
        {
         int x=bar.CoordX()+8;
         if(x>this.RightEdge())
            x=this.CoordX()-bar.Width();
         bar.Move(x,bar.CoordY());
         bar.Redraw(true);
        }
      else
         bar.OnTimer();
     }
  }
//+------------------------------------------------------------------+

ここでは、プログレスバーの表示スタイルが「連続スクロール」の場合、オブジェクトを移動させる必要があるX座標を取得します。現時点では、現在のX座標に8ピクセルのオフセットを加え、プログレスバーを新しい座標に水平方向に移動させます。この場合、オブジェクトのX座標を設定して、オブジェクトがコンテナの左端を越えて左側の幅の値になるようにします。Redraw()メソッドでは、オブジェクトを再描画するだけでなく、もう1つの機能として、コンテナの端からはみ出したオブジェクトの部分を切り落とします。コンテナの中でプログレスバーを動かすと同時に、端からはみ出した部分が切り落とされるという、完全なサイクルを作り出しました。
オブジェクトのレンダリングスタイルが異なる場合は、プログレスバーオブジェクトのタイマーを呼び出して、グレアオブジェクトを表示します。


プログレスバーの描画スタイルが「分割ブロック」になったので、プログレスバーの値を設定するメソッドを改良する必要があります。現在、このメソッドは、値を設定した後、直ちに新しい値に従ってオブジェクトのサイズを変更します。しかし、分割されたブロックはピクセル単位ではなく、ブロック単位で描画する必要があるため、設定されたプログレスバーの幅に何個のブロックが収まるかを把握する必要があります。もし、新しいセグメントを描くのに十分な幅があれば、オブジェクトはそのプロパティにすでに設定されている幅を変更します。幅が足りない場合(現在の描画セグメントが不完全で切り取られる)、オブジェクトの設定幅から1セグメントの幅を引き、ちょうどこの幅をプログレスバーに設定する必要があります。その場合、前のセグメントをすべて含む最後のセグメントのみが描画されます。したがって、オブジェクトの幅は、すべてのセグメントが切り取られずに完全に描画できる場合にのみ常に変化し、プログレスバーの可視幅がブロックごとに変化することになります。この場合、値は常にオブジェクトに渡されたものとなります。つまり、視覚的に離散的に幅を変えるだけで、中の値は常にそのオブジェクトに設定されているものになります。

プログレスバーの現在値を設定するメソッドに、上記のような改善点を実装する予定です

//+---------------------------------------------+
//| Set the current value of the progress bar   |
//+---------------------------------------------+
void CProgressBar::SetValue(const int value)
  {
//--- Correct the value passed to the method and set it to the object property
   int v=(value<this.Minimum() ? this.Minimum() : value>this.Maximum() ? this.Maximum() : value);
   this.SetProperty(CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE,v);
//--- Get the progress bar object
   CBarProgressBar *bar=this.GetProgressBar();
   if(bar!=NULL)
     {
      //--- Set 'value' for the progress bar
      bar.SetValue(v);
      //--- Calculate the width of the progress bar object
      int w=this.CalculateProgressBarWidth();
      //--- If the calculated width is greater than the maximum possible value, set the maximum width
      if(w>this.m_progress_bar_max)
         w=this.m_progress_bar_max;
      //--- If the width is less than 1, then
      if(w<1)
        {
         //--- hide the progress bar and redraw the chart to display changes immediately
         bar.Hide();
         ::ChartRedraw(bar.ChartID());
        }
      //--- If the width value is not less than 1
      else
        {
         //--- If the progress bar is hidden, display it and
         if(!bar.IsVisible())
            bar.Show();
         //--- If the style of the progress bar is "Continuous line", change the width of the object to the calculated value
         if(this.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS)
            bar.Resize(w,bar.Height(),true);
         //--- Otherwise, if the progress bar style is "Segmented blocks"
         else if(this.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_BLOCKS)
           {
            //--- Segment width including indent
            int wd=bar.SegmentWidth()+bar.SegmentDistance();
            //--- The number of segments that fit the width of the progress bar
            int num=w/(wd>0 ? wd : 1);
            //--- The X coordinate of the last segment calculated from the beginning of the segment count
            int wx=bar.SegmentStart()+num*wd;
            //--- If the calculated width of the progress bar is less than the coordinate of the last segment, and this is not the last segment,
            //--- set the width of the progress bar equal to the penultimate segment coordinate
            if(w<wx-bar.SegmentDistance() && w<this.m_progress_bar_max)
               w=wx-wd+bar.SegmentDistance();
            //--- If the calculated width of the progress bar is less than the coordinate of the last segment, or it is not the last segment,
            if(w<wx-bar.SegmentDistance() || w==this.m_progress_bar_max)
               //--- change the size of the progress bar in accordance with the received and adjusted width
               bar.Resize(w,bar.Height(),true);
           }
        }
      //--- If the progress bar description text is set,
      if(this.m_progress_bar_text!="")
        {
         //--- get the object description of the progress bar and bring it to the foreground
         CLabel *obj=this.GetProgressDescriptionObj();
         if(obj!=NULL)
            obj.BringToTop();
        }
     }
  }
//+------------------------------------------------------------------+

メソッドのロジックは、コードのコメントで説明されています。プログレスバーの値を変更するたびに、説明も変更する必要がある場合があります。したがって、このオブジェクトにテキストが設定されている場合は、常に前景に表示されます


プログレスバーの幅を計算するメソッドは、プログレスバーのスタイルが「連続スクロール」に設定されている場合にProgressBarコントロールのサイズの半分を返すように改良する必要があります。

//+---------------------------------------------+
//| Calculate the width of the progress bar     |
//+---------------------------------------------+
int CProgressBar::CalculateProgressBarWidth(void)   

  {
   this.m_value_by_max=this.Value()*100/this.Maximum();
   return(this.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_MARQUEE ? this.m_progress_bar_max/2 : this.m_progress_bar_max*this.m_value_by_max/100);
  }
//+------------------------------------------------------------------+

これで、このメソッドは、どの表示スタイルでも正しいスクロールバーのサイズを返すようになりました。


新しい幅を設定するメソッドでは、プログレスバーの説明を表示するためのテキストラベルオブジェクトにも、オブジェクトに設定された幅を割り当てる必要があります。

//+---------------------------------------------+
//| Set a new width                             |
//+---------------------------------------------+
bool CProgressBar::SetWidth(const int width)
  {
   if(!CGCnvElement::SetWidth(width))
      return false;
   this.m_progress_bar_max=this.Width()-this.BorderSizeLeft()-this.BorderSizeRight();
   CBarProgressBar *bar=this.GetProgressBar();
   if(bar==NULL)
      return false;
   int w=this.CalculateProgressBarWidth();
   bar.SetWidth(w);
   CLabel *lbl=this.GetProgressDescriptionObj();
   if(lbl!=NULL)
      lbl.SetWidth(w);
   return true;
  }
//+------------------------------------------------------------------+

テキストラベルオブジェクトのサイズをプログレスバーのサイズに合わせないと、プログレスバーの見かけ上のサイズに合わせて書いたテキストが、見た目より小さい幅のオブジェクトに収まらない場合があります。これにより、テキストが単に切り取られることになります。そのため、テキストラベルとプログレスバーは同じ寸法であることが必要です。

ProgressBarコントロールに結合されているオブジェクトのプロパティへのアクセスを容易にする補助メソッドについて見てみましょう。

以下は、グレアオブジェクトにスタイルを設定するメソッドです。

//+---------------------------------------------+
//| Set the glare object style                  |
//+---------------------------------------------+
void CProgressBar::SetGlareStyle(const ENUM_CANV_ELEMENT_VISUAL_EFF_STYLE style)
  {
   CGlareObj *obj=this.GetGlareObj();
   if(obj==NULL)
      return;
   obj.SetVisualEffectStyle(style);
  }
//+------------------------------------------------------------------+

ここでは、グレアオブジェクトへのポインタを取得し、その結果のオブジェクトにスタイルを設定しています。


以下は、グレアオブジェクトの不透明度を設定するメソッドです。

//+---------------------------------------------+
//| Set the opacity of the highlight object     |
//+---------------------------------------------+
void CProgressBar::SetGlareOpacity(const uchar opacity)
  {
   CGlareObj *obj=this.GetGlareObj();
   if(obj==NULL)
      return;
   obj.SetOpacity(opacity);
  }
//+------------------------------------------------------------------+

グレアオブジェクトへのポインタを取得し、結果のオブジェクトに不透明度を設定します。


以下は、グレアオブジェクトに色を設定するメソッドです。

//+---------------------------------------------+
//| Set the color for the glare object          |
//+---------------------------------------------+
void CProgressBar::SetGlareColor(const color clr)
  {
   CGlareObj *obj=this.GetGlareObj();
   if(obj==NULL)
      return;
   obj.SetColor(clr);
  }
//+------------------------------------------------------------------+

グレアオブジェクトへのポインタを取得し、メソッドに渡されたカラー値を結果のオブジェクトに設定します。


以下は、プログレスバーのテキストラベルにテキストを設定するメソッドです。

//+------------------------------------------------------------------+
//| Set a text to the text label of the progress bar                 |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionText(const string text,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text=text;
   obj.SetText(text);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+

ここでは、テキストラベルオブジェクトへのポインタを取得しています。このメソッドに渡されたテキストをm_progress_bar_text変数に設定します。そして、そのテキストをオブジェクトに設定します。テキストはすぐにオブジェクトに表示されるので、テキストが他のテキストと重ならないように、背景とその上に描かれたものはすべて消去する必要があります。次に、テキストを表示し、要素を更新します


以下は、プログレスバーのテキスト色をテキストラベルに設定するメソッドです。

//+------------------------------------------------------------------+
//| Set the text color of the progress bar to the text label         |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionColor(const color clr,const bool redraw=false,const bool set_init_color=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text_color=clr;
   obj.SetForeColor(clr,false);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+

テキストラベルオブジェクトへのポインタを取得します。変数m_progress_bar_text_colorに、このメソッドに渡された色を設定します。次に、そのオブジェクトの色を文字色として設定します。テキストはすぐに表示されるため、テキストが他のテキストと重ならないように、テキストラベルの背景は消去されます。さらに、テキストが表示され、要素が更新されます


以下は、プログレスバーのテキストラベルに不透明度を設定するメソッドです。

//+---------------------------------------------+
//| Set opacity to the progress bar text label  |
//+---------------------------------------------+
void CProgressBar::SetBarDescriptionOpacity(const uchar opacity,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text_opacity=opacity;
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+

メソッドのロジックは上記と同じですが、不透明度の値を対応する変数とオブジェクトに設定しています。


以下は、プログレスバーのテキストラベルにX座標を設定するメソッドです。

//+------------------------------------------------------------------+
//| Set the X coordinate to the text label of the progress bar       |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionX(const int x,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text_x=x;
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+


以下は、プログレスバーのテキストラベルにY座標を設定するメソッドです。

//+------------------------------------------------------------------+
//| Set the Y coordinate to the text label of the progress bar       |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionY(const int y,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   this.m_progress_bar_text_y=y;
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+


以下は、プログレスバーのテキストラベルにフォントを設定するメソッドです。

//+------------------------------------------------------------------+
//| Set the font in the text label of the progress bar               |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionFontName(const string font,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetFontName(font);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+


以下は、プログレスバーのテキストラベルにフォントサイズを設定するメソッドです。

//+------------------------------------------------------------------+
//| Set the font size to the progress bar text label                 |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionFontSize(const int size,const bool relative=false,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetFontSize(size,relative);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+


以下は、プログレスバーのテキストラベルにフォントフラグを設定するメソッドです。

//+------------------------------------------------------------------+
//| Set the font flags in the text label of the progress bar         |
//+------------------------------------------------------------------+
void CProgressBar::SetBarDescriptionFontFlags(const uint flags,const bool redraw=false)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetFontFlags(flags);
   obj.Erase(false);
   obj.Text(this.m_progress_bar_text_x,this.m_progress_bar_text_y,this.m_progress_bar_text,this.m_progress_bar_text_color,this.m_progress_bar_text_opacity,this.m_progress_bar_text_anchor);
   obj.Update(redraw);
  }
//+------------------------------------------------------------------+

上に示したメソッドはすべて同じロジックで、プログレスバーの記述に(テキストラベルに)希望のテキストとフォントのパラメータを素早く設定することができます。変更内容はすぐに画面に表示されます。


プログレスバーの記述を隠す必要がある場合、常に前景に出されることで表示されてしまうため、隠すだけでなく、オブジェクトに非表示フラグを設定する必要があるのです。オブジェクトを非表示にした後、そのオブジェクトに非表示フラグを設定すると、再び表示フラグを受け取るまで、オブジェクトは再描画されません。

以下は、プログレスバーのテキストラベルを非表示にするメソッドです。

//+---------------------------------------------+
//| Hide the progress bar text label            |
//+---------------------------------------------+
void CProgressBar::HideBarDescription(void)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetDisplayed(false);
   obj.Hide();
  }
//+------------------------------------------------------------------+

ここでは、プログレスバーの説明を記述したテキストラベルオブジェクトを取得し、それに非表示フラグを設定し、オブジェクトを非表示にしています。


以下は、プログレスバーのテキストラベルを表示するメソッドです。

//+---------------------------------------------+
//| Display a text label for the progress bar   |
//+---------------------------------------------+
void CProgressBar::ShowBarDescription(void)
  {
   CLabel *obj=this.GetProgressDescriptionObj();
   if(obj==NULL)
      return;
   obj.SetDisplayed(true);
   obj.Show();
  }
//+------------------------------------------------------------------+

ここでは、プログレスバーの説明を記述したテキストラベルオブジェクトを取得し、その表示フラグを設定し、オブジェクトを表示しています。


以下は、MinからMaxまでの範囲の現在のプログレスバーの値を割合で返すメソッドです。

//+---------------------------------------------+
//| Return the current value of the progress bar|
//| in the range from Min to Max as a percentage|
//+---------------------------------------------+
double CProgressBar::ValuePercent(void) const
  {
   double range=this.Maximum()-this.Minimum();
   return(this.Value()*100.0/(range>0 ? range : 1));
  }
//+------------------------------------------------------------------+

プログレスバーの値をMinからMaxまでの範囲の割合で取得する必要がある場合、このメソッドは指定した範囲の何割合がすでに処理されているかを計算し、その値を返します。100%は、ProgressBarオブジェクトに設定された最大値と最小値の差です。

結果を確認してみましょう。


検証

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

英語版とユーザー言語版コンパイルのプログレスバー形式の列挙を作成します。

//--- 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)
  };
enum ENUM_CHEK_STATE
  {
   CHEK_STATE_UNCHECKED=CANV_ELEMENT_CHEK_STATE_UNCHECKED,                             // Unchecked
   CHEK_STATE_CHECKED=CANV_ELEMENT_CHEK_STATE_CHECKED,                                 // Checked
   CHEK_STATE_INDETERMINATE=CANV_ELEMENT_CHEK_STATE_INDETERMINATE,                     // Indeterminate
  };
enum ENUM_ELEMENT_ALIGNMENT
  {
   ELEMENT_ALIGNMENT_TOP=CANV_ELEMENT_ALIGNMENT_TOP,                                   // Top
   ELEMENT_ALIGNMENT_BOTTOM=CANV_ELEMENT_ALIGNMENT_BOTTOM,                             // Bottom
   ELEMENT_ALIGNMENT_LEFT=CANV_ELEMENT_ALIGNMENT_LEFT,                                 // Left
   ELEMENT_ALIGNMENT_RIGHT=CANV_ELEMENT_ALIGNMENT_RIGHT,                               // Right
  };
enum ENUM_ELEMENT_TAB_SIZE_MODE
  {
   ELEMENT_TAB_SIZE_MODE_NORMAL=CANV_ELEMENT_TAB_SIZE_MODE_NORMAL,                     // Fit to tab title text width
   ELEMENT_TAB_SIZE_MODE_FIXED=CANV_ELEMENT_TAB_SIZE_MODE_FIXED,                       // Fixed size
   ELEMENT_TAB_SIZE_MODE_FILL=CANV_ELEMENT_TAB_SIZE_MODE_FILL,                         // Fit TabControl Size
  };
enum ENUM_ELEMENT_PROGRESS_BAR_STYLE
  {
   ELEMENT_PROGRESS_BAR_STYLE_BLOCKS=CANV_ELEMENT_PROGRESS_BAR_STYLE_BLOCKS,           // Blocks
   ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS=CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS,   // Continuous
   ELEMENT_PROGRESS_BAR_STYLE_MARQUEE=CANV_ELEMENT_PROGRESS_BAR_STYLE_MARQUEE,         // Marquee
  };  
#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)
  };
enum ENUM_CHEK_STATE
  {
   CHEK_STATE_UNCHECKED=CANV_ELEMENT_CHEK_STATE_UNCHECKED,                             // Unchecked
   CHEK_STATE_CHECKED=CANV_ELEMENT_CHEK_STATE_CHECKED,                                 // Checked
   CHEK_STATE_INDETERMINATE=CANV_ELEMENT_CHEK_STATE_INDETERMINATE,                     // Undefined
  };
enum ENUM_ELEMENT_ALIGNMENT
  {
   ELEMENT_ALIGNMENT_TOP=CANV_ELEMENT_ALIGNMENT_TOP,                                   // Top
   ELEMENT_ALIGNMENT_BOTTOM=CANV_ELEMENT_ALIGNMENT_BOTTOM,                             // Bottom
   ELEMENT_ALIGNMENT_LEFT=CANV_ELEMENT_ALIGNMENT_LEFT,                                 // Left
   ELEMENT_ALIGNMENT_RIGHT=CANV_ELEMENT_ALIGNMENT_RIGHT,                               // Right
  };
enum ENUM_ELEMENT_TAB_SIZE_MODE
  {
   ELEMENT_TAB_SIZE_MODE_NORMAL=CANV_ELEMENT_TAB_SIZE_MODE_NORMAL,                     // By tab title width
   ELEMENT_TAB_SIZE_MODE_FIXED=CANV_ELEMENT_TAB_SIZE_MODE_FIXED,                       // Fixed size
   ELEMENT_TAB_SIZE_MODE_FILL=CANV_ELEMENT_TAB_SIZE_MODE_FILL,                         // By TabControl size
  };
enum ENUM_ELEMENT_PROGRESS_BAR_STYLE
  {
   ELEMENT_PROGRESS_BAR_STYLE_BLOCKS=CANV_ELEMENT_PROGRESS_BAR_STYLE_BLOCKS,           // Segmented blocks
   ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS=CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS,   // Continuous bar
   ELEMENT_PROGRESS_BAR_STYLE_MARQUEE=CANV_ELEMENT_PROGRESS_BAR_STYLE_MARQUEE,         // Continuous scrolling
  };  
#endif 
//--- input parameters


プログレスバーのスタイルプログレスバーの値を割合で表示するフラグの2つの新しいパラメータを入力に追加しましょう。

//--- input parameters
sinput   bool                          InpMovable           =  true;                   // Panel Movable flag
sinput   ENUM_INPUT_YES_NO             InpAutoSize          =  INPUT_YES;              // Panel Autosize
sinput   ENUM_AUTO_SIZE_MODE           InpAutoSizeMode      =  AUTO_SIZE_MODE_GROW;    // Panel Autosize mode
sinput   ENUM_BORDER_STYLE             InpFrameStyle        =  BORDER_STYLE_SIMPLE;    // Label border style
sinput   ENUM_ANCHOR_POINT             InpTextAlign         =  ANCHOR_CENTER;          // Label text align
sinput   ENUM_INPUT_YES_NO             InpTextAutoSize      =  INPUT_NO;               // Label autosize
sinput   ENUM_ANCHOR_POINT             InpCheckAlign        =  ANCHOR_LEFT;            // Check flag align
sinput   ENUM_ANCHOR_POINT             InpCheckTextAlign    =  ANCHOR_LEFT;            // Check label text align
sinput   ENUM_CHEK_STATE               InpCheckState        =  CHEK_STATE_UNCHECKED;   // Check flag state
sinput   ENUM_INPUT_YES_NO             InpCheckAutoSize     =  INPUT_YES;              // CheckBox autosize
sinput   ENUM_BORDER_STYLE             InpCheckFrameStyle   =  BORDER_STYLE_NONE;      // CheckBox border style
sinput   ENUM_ANCHOR_POINT             InpButtonTextAlign   =  ANCHOR_CENTER;          // Button text align
sinput   ENUM_INPUT_YES_NO             InpButtonAutoSize    =  INPUT_YES;              // Button autosize
sinput   ENUM_AUTO_SIZE_MODE           InpButtonAutoSizeMode=  AUTO_SIZE_MODE_GROW;    // Button Autosize mode
sinput   ENUM_BORDER_STYLE             InpButtonFrameStyle  =  BORDER_STYLE_NONE;      // Button border style
sinput   bool                          InpButtonToggle      =  true ;                  // Button toggle flag
sinput   bool                          InpButtListMSelect   =  false;                  // ButtonListBox Button MultiSelect flag
sinput   bool                          InpListBoxMColumn    =  true;                   // ListBox MultiColumn flag
sinput   bool                          InpTabCtrlMultiline  =  false;                   // Tab Control Multiline flag
sinput   ENUM_ELEMENT_ALIGNMENT        InpHeaderAlignment   =  ELEMENT_ALIGNMENT_TOP;  // TabHeader Alignment
sinput   ENUM_ELEMENT_TAB_SIZE_MODE    InpTabPageSizeMode   =  ELEMENT_TAB_SIZE_MODE_FILL; // TabHeader Size Mode
sinput   int                           InpTabControlX       =  10;                     // TabControl X coord
sinput   int                           InpTabControlY       =  20;                     // TabControl Y coord
sinput   ENUM_CANV_ELEMENT_TOOLTIP_ICON InpTooltipIcon      =  CANV_ELEMENT_TOOLTIP_ICON_NONE;  // Tooltip Icon
sinput   string                        InpTooltipTitle      =  "";                     // Tooltip Title
sinput   ENUM_ELEMENT_PROGRESS_BAR_STYLE InpProgressBarStyle=  ELEMENT_PROGRESS_BAR_STYLE_BLOCKS;  // Progress Bar Style
sinput   bool                          InpProgressBarPercent=  false;                  // Show progress bar values as a percentage
//--- global variables


EAのOnInit()ハンドラでProgressBarコントロールを作成する際に、設定の変数からスタイルをプログレスバーに設定し、プログレスバーを記述するパラメータを設定します

                     //--- If this is the first tab and the second panel
                     if(n==0 && j==1)
                       {
                        //--- Create the ProgressBar control on it
                        if(split_container.CreateNewElement(j,GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR,4,4,100,12,clrNONE,255,false,false))
                          {
                           CProgressBar *progress_bar=split_container.GetPanelElementByType(j,GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR,0);
                           if(progress_bar!=NULL)
                             {
                              //--- Set the style of the progress bar specified in the EA settings
                              progress_bar.SetStyle((ENUM_CANV_ELEMENT_PROGRESS_BAR_STYLE)InpProgressBarStyle);
                              //--- Set the parameters for describing the progress bar
                              progress_bar.SetBarDescriptionText("Progress Bar ");
                              progress_bar.SetBarDescriptionColor(panel.BackgroundColor());
                              progress_bar.SetBarDescriptionOpacity(255);
                              progress_bar.SetBarDescriptionY(-2);
                             }
                          }
                       }


すべてのパネルを表示し再描画するループで、プログレスバーのスタイルが「連続線」の時に説明を表示します。プログレスバーの値を増加させるループの繰り返しごとに、設定に応じて値を割合または完了ステップで説明に表示します。ループ完了時に、プログレスバーの記述に、インクリメントループ完了のメッセージをフォントを太字に変えて記述します
グレアオブジェクトのパラメータを設定するために、オブジェクトのクイックアクセスメソッドを使用することにします

//--- Display and redraw all created panels
   for(int i=0;i<FORMS_TOTAL;i++)
     {
      //--- Get the panel object
      pnl=engine.GetWFPanel("WinForms Panel"+(string)i);
      if(pnl!=NULL)
        {
         //--- display and redraw the panel
         pnl.Show();
         pnl.Redraw(true);
         //--- Get the TabControl object from the panel
         CTabControl *tc=pnl.GetElementByType(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,0);
         //--- Get the SplitContainer object from the first tab of the TabControl object
         CSplitContainer *sc=tc.GetTabElementByType(0,GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER,0);
         //--- Get the second panel from the SplitContainer object
         CSplitContainerPanel *scp=sc.GetPanel(1);
         //--- Get the ProgressBar object from the received panel
         CProgressBar *pb=scp.GetElementByType(GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR,0);
         //--- Wait for 1/10 of a second
         Sleep(100);
         //--- Get the width of the ProgressBar object
         int w=pb.Width();
         //--- In the loop, increase the width of the ProgressBar by 180 pixels with a delay of 1/50
         for(int n=0;n<180;n++)
           {
            Sleep(20);
            pb.Resize(w+n,pb.Height(),true);
           }
         //--- Set the values for PerformStep of the ProgressBar object
         pb.SetValuesForProcessing(0,350,1,0);
         //--- Reset ProgressBar to minimum
         pb.ResetProgressBar();
         //--- If the style of the progress bar is "Continuous line", display the progress bar description
         if(pb.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS)
            pb.ShowBarDescription();
         //--- Wait for 1/5 second
         Sleep(200);
         //--- If the style of the progress bar is not "Continuous scrolling"
         if(pb.Style()!=CANV_ELEMENT_PROGRESS_BAR_STYLE_MARQUEE)
           {
            //--- In the loop from the minimum to the maximum value of ProgressBar
            for(int n=0;n<=pb.Maximum();n++)
              {
               //--- call the method for increasing the progress bar by a given step with a wait of 1/5 second
               pb.PerformStep();
               //--- Set the number of completed steps in the description of the progress bar
               pb.SetBarDescriptionText("Progress Bar, pass: "+(InpProgressBarPercent ? pb.ValuePercentDescription() : pb.ValueDescription()));
               Sleep(20);
              }
           }
         //--- Wait for 1/2 second, set the description font type to Bold and write a completion message on the progress bar
         Sleep(500);
         pb.SetBarDescriptionFontFlags(FW_BOLD);
         pb.SetBarDescriptionText("Progress Bar: Done");
         //--- Set the glare object type - rectangle, opacity 40, color - white
         pb.SetGlareStyle(CANV_ELEMENT_VISUAL_EFF_STYLE_RECTANGLE);
         pb.SetGlareOpacity(40);
         pb.SetGlareColor(clrWhite);
        }
     }
        
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+


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


このように、宣言したモードはすべてうまく機能します。


次の段階

次回は、TrackBarコントロールの開発に着手します。

目次に戻る

連載のこれまでの記事

 
DoEasy-コントロール(第26部):ToolTipWinFormsオブジェクトの最終確認とProgressBar開発の開始
DoEasy-コントロール(第27部):ProgressBarWinFormsオブジェクトでの作業

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

添付されたファイル |
MQL5.zip (4527.27 KB)
母集団最適化アルゴリズム:カッコウ最適化アルゴリズム(COA) 母集団最適化アルゴリズム:カッコウ最適化アルゴリズム(COA)
次に考察するのは、レヴィフライトを使ったカッコウ検索最適化アルゴリズムです。これは最新の最適化アルゴリズムの1つで、リーダーボードの新しいリーダーです。
母集団最適化アルゴリズム:灰色オオカミオプティマイザー(GWO) 母集団最適化アルゴリズム:灰色オオカミオプティマイザー(GWO)
最新の最適化アルゴリズムの1つである灰色オオカミオプティマイザについて考えてみましょう。テスト関数の元々の動作により、このアルゴリズムは、以前に検討されたものの中で最も興味深いものの1つになります。これは、ニューラルネットワークの訓練に使用される最も優れたアルゴリズムの1つであり、多くの変数を持つ滑らかな関数です。
MQL5クックブック - サービス MQL5クックブック - サービス
この記事では、チャートへの結合を必要としないMQL5プログラムである「サービス」の多彩な機能について説明しています。また、他のMQL5プログラムとのサービスの違いをハイライトし、開発者がサービスで作業する際の微妙な違いを強調しています。例として、読者にはサービスとして実装できる幅広い機能をカバーするさまざまなタスクが提供されます。
母集団最適化アルゴリズム:人工蜂コロニー(ABC) 母集団最適化アルゴリズム:人工蜂コロニー(ABC)
今回は、人工蜂コロニーアルゴリズムを研究し、機能空間を研究する新しい原理で知識を補います。今回は、古典アルゴリズムについて、私の解釈を紹介します。