English Русский 中文 Español Deutsch Português
グラフィカルインタフェースX: テキストエディットボックス、ピクチャスライダー、及びシンプルなコントロール(ビルド5)

グラフィカルインタフェースX: テキストエディットボックス、ピクチャスライダー、及びシンプルなコントロール(ビルド5)

MetaTrader 5 | 17 1月 2017, 15:18
1 342 0
Anatoli Kazharski
Anatoli Kazharski
Untitled Document

コンテンツ

はじめに

このライブラリの目的のより良い理解を得るためにはシリーズ最初のグラフィカルインタフェース I: ライブラリストラクチャの準備(チャプター 1)稿をお読みください。各章の末尾では記事へのリンクの完全なリストがみられます。そこではまた、開発の現段階でのライブラリの完全版をダウンロードすることができます。ファイルはアーカイブと同じディレクトリに配置される必要があります。

この記事では、テキストエディットボックス、ピクチャスライダー、および追加的なシンプルなコントロール(テキストラベルとピクチャ)の新しいコントロールについて検討します。これらは様々な場合に有用です。ライブラリは成長を続けており、新しいコントロールの導入に加えて、以前作成されたものも改善されています。ライブラリは現在多数のユーザによって利用されており、複数のコメントや提案を受けとっています。これらのリクエストの多くは、新しいバージョンのライブラリに実装されています。さらに、特定のアルゴリズムも最適化されてきました。これによりCPU負荷は大幅に減少しています。詳細は本稿で後ほどお話しします。

 

テキストエディットボックス

これまでのところ、開発されたライブラリにはすでにエディットボックス( CSpinEdit クラス)が含まれていますが、これは数値のみを入力するように設計されています。ここでは、テキストをフィールドに入力できる別のコントロールを追加します。テキストエディットボックスはさまざまな状況で必要になり得ます。例は端末「サンドボックス」のファイルでの文字列検索の作成です。もう1つの選択肢は、MQLアプリケーションのエンドユーザに、取引する銘柄の配列を入力する機能を提供することです。要するに、これは作業に必要な任意のテキストデータが使えます。

テキストエディットボックスのすべてのコンポーネントを列挙しましょう。

  1. 背景
  2. アイコン
  3. 説明
  4. エディットボックス

 

図1 テキストエディットボックスのコンポーネント


このコントロールのクラスを詳しく見てみましょう。

 

テキストエディットボックス作成クラス

すべてのコントロールに標準的なメソッドを持つCTextEditクラスを持ったTextEdit.mqhファイルを作成しライブラリエンジン(WndContainer.mqhファイル)に関連付けます。下にあるのはユーザがカスタマイズできるコントロールプロパティのリストです。

  • コントロールの背景色
  • アクティブ状態とブロック状態でのコントロールアイコン
  • 2つの軸(x、y)に沿ったアイコンのマージン
  • コントロールの説明テキスト
  • 2つの軸(x、y)に沿ったテキストラベルのマージン
  • コントロールの異なる状態にあるテキストの色
  • エディットボックスの大きさ
  • 2つの軸(x、y)に沿ったエディットボックスのマージン
  • 異なる状態のエディットボックスの色及びそのテキストの色
  • エディットボックス内のテキストの整列モード(左/右/中央)
  • テキスト選択カーソルの表示モード
  • エディットボックスの値のリセットモード
//+------------------------------------------------------------------+
//| テキストエディットボックス作成クラス       |
//+------------------------------------------------------------------+
class CTextEdit : public CElement
  {
private:
   //--- コントロールの背景色
   color             m_area_color;
   //--- アクティブ状態とブロック状態でのコントロールアイコン
   string            m_icon_file_on;
   string            m_icon_file_off;
   //--- アイコンのマージン
   int               m_icon_x_gap;
   int               m_icon_y_gap;
   //--- エディットボックスの説明テキスト
   string            m_label_text;
  //--- テキストラベルのマージン
   int               m_label_x_gap;
   int               m_label_y_gap;
   //--- 異なる状態でのテキストの色
   color             m_label_color;
   color             m_label_color_hover;
   color             m_label_color_locked;
   color             m_label_color_array[];
   //--- エディットボックスの現在値
   string            m_edit_value;
   //--- エディットボックスの大きさ
   int               m_edit_x_size;
   int               m_edit_y_size;
   //--- エディットボックスのマージン
   int               m_edit_x_gap;
   int               m_edit_y_gap;
   //--- 異なる状態のエディットボックスの色及びそのテキストの色
   color             m_edit_color;
   color             m_edit_color_locked;
   color             m_edit_text_color;
   color             m_edit_text_color_locked;
   color             m_edit_text_color_highlight;
   //--- 異なる状態にあるエディットボックスフレームの色
   color             m_edit_border_color;
   color             m_edit_border_color_hover;
   color             m_edit_border_color_locked;
   color             m_edit_border_color_array[];
   //--- 値のリセットモード(空の文字列)
   bool              m_reset_mode;
   //--- テキスト選択ポインタの表示モード
   bool              m_show_text_pointer_mode;
   //--- テキストの配置モード
   ENUM_ALIGN_MODE   m_align_mode;
   //---
public:
   //--- アイコンのマージン
   void              IconXGap(const int x_gap)                      { m_icon_x_gap=x_gap;                 }
   void              IconYGap(const int y_gap)                      { m_icon_y_gap=y_gap;                 }
   //--- (1) 背景色 (2) エディットボックスの説明テキスト (3) テキストレベルのマージン
   void              AreaColor(const color clr)                     { m_area_color=clr;                   }
   string            LabelText(void)                          const { return(m_label.Description());      }
   void              LabelText(const string text)                   { m_label.Description(text);          }
   void              LabelXGap(const int x_gap)                     { m_label_x_gap=x_gap;                }
   void              LabelYGap(const int y_gap)                     { m_label_y_gap=y_gap;                }
   //--- 異なる状態にあるテキストラベルの色
   void              LabelColor(const color clr)                    { m_label_color=clr;                  }
   void              LabelColorHover(const color clr)               { m_label_color_hover=clr;            }
   void              LabelColorLocked(const color clr)              { m_label_color_locked=clr;           }
   //--- (1) エディットボックスの大きさ (2) 右側からのエディットボックスのマージン
   void              EditXSize(const int x_size)                    { m_edit_x_size=x_size;               }
   void              EditYSize(const int y_size)                    { m_edit_y_size=y_size;               }
   //--- エディットボックスのマージン
   void              EditXGap(const int x_gap)                      { m_edit_x_gap=x_gap;                 }
   void              EditYGap(const int y_gap)                      { m_edit_y_gap=y_gap;                 }
   //--- 異なる状態にあるエディットボックスの色
   void              EditColor(const color clr)                     { m_edit_color=clr;                   }
   void              EditColorLocked(const color clr)               { m_edit_color_locked=clr;            }
   //--- 異なる状態にあるエディットボックステキストの色
   void              EditTextColor(const color clr)                 { m_edit_text_color=clr;              }
   void              EditTextColorLocked(const color clr)           { m_edit_text_color_locked=clr;       }
   void              EditTextColorHighlight(const color clr)        { m_edit_text_color_highlight=clr;    }
   //--- 異なる状態にあるエディットボックスフレームの色
   void              EditBorderColor(const color clr)               { m_edit_border_color=clr;            }
   void              EditBorderColorHover(const color clr)          { m_edit_border_color_hover=clr;      }
   void              EditBorderColorLocked(const color clr)         { m_edit_border_color_locked=clr;     }
   //--- (1) テキストラベルを押すときのリセットモード (2) テキスト選択ポインタの表示モード
   bool              ResetMode(void)                                { return(m_reset_mode);               }
   void              ResetMode(const bool mode)                     { m_reset_mode=mode;                  }
   void              ShowTextPointerMode(const bool mode)           { m_show_text_pointer_mode=mode;      }
   //--- テキスト配置モード
   void              AlignMode(ENUM_ALIGN_MODE mode)                { m_align_mode=mode;                  }
   //--- ボタンがアクティブ及びブロックされた状態でのアイコンの設定
   void              IconFileOn(const string file_path);
   void              IconFileOff(const string file_path);
  };

テキスト選択ポインタの表示モードは、マウスカーソルがエディットボックスの上をホバーすると、テキストボックスにテキストを入力できることを示す追加アイコンで補完されることを意味します。この機能のために、もう1つの識別子( MP_TEXT_SELECT )が ENUM_MOUSE_POINTER 列挙体に追加されました。

//+------------------------------------------------------------------+
//| ポインタタイプの列挙 |
//+------------------------------------------------------------------+
enum ENUM_MOUSE_POINTER
  {
   MP_CUSTOM      =0,
   MP_X_RESIZE    =1,
   MP_Y_RESIZE    =2,
   MP_XY1_RESIZE  =3,
   MP_XY2_RESIZE  =4,
   MP_X_SCROLL    =5,
   MP_Y_SCROLL    =6,
   MP_TEXT_SELECT =7
  };

CPointerクラスはこれに対応して変更されました(コードは下記参照)。テキスト選択のカーソルアイコンの画像は、本稿末尾のアーカイブにあります。 

//+------------------------------------------------------------------+
//|                                                      Pointer.mqh |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Element.mqh"
//--- リソース
...
#resource "\\Images\\EasyAndFastGUI\\Controls\\pointer_text_select.bmp"

//+------------------------------------------------------------------+
//| カーソルタイプに基づいてカーソルアイコンを設定する                |
//+------------------------------------------------------------------+
void CPointer::SetPointerBmp(void)
  {
   switch(m_type)
     {
      case MP_X_RESIZE :
         m_file_on  ="Images\\EasyAndFastGUI\\Controls\\pointer_x_rs_blue.bmp";
         m_file_off ="Images\\EasyAndFastGUI\\Controls\\pointer_x_rs.bmp";
         break;
      case MP_Y_RESIZE :
         m_file_on  ="Images\\EasyAndFastGUI\\Controls\\pointer_y_rs_blue.bmp";
         m_file_off ="Images\\EasyAndFastGUI\\Controls\\pointer_y_rs.bmp";
         break;
      case MP_XY1_RESIZE :
         m_file_on  ="Images\\EasyAndFastGUI\\Controls\\pointer_xy1_rs_blue.bmp";
         m_file_off ="Images\\EasyAndFastGUI\\Controls\\pointer_xy1_rs.bmp";
         break;
      case MP_XY2_RESIZE :
         m_file_on  ="Images\\EasyAndFastGUI\\Controls\\pointer_xy2_rs_blue.bmp";
         m_file_off ="Images\\EasyAndFastGUI\\Controls\\pointer_xy2_rs.bmp";
         break;
      case MP_X_SCROLL :
         m_file_on  ="Images\\EasyAndFastGUI\\Controls\\pointer_x_scroll_blue.bmp";
         m_file_off ="Images\\EasyAndFastGUI\\Controls\\pointer_x_scroll.bmp";
         break;
      case MP_Y_SCROLL :
         m_file_on  ="Images\\EasyAndFastGUI\\Controls\\pointer_y_scroll_blue.bmp";
         m_file_off ="Images\\EasyAndFastGUI\\Controls\\pointer_y_scroll.bmp";
         break;
      case MP_TEXT_SELECT :
         m_file_on  ="Images\\EasyAndFastGUI\\Controls\\pointer_text_select.bmp";
         m_file_off ="Images\\EasyAndFastGUI\\Controls\\pointer_text_select.bmp";
         break;

     }
//--- カスタムタイプ(MP_CUSTOM)が指定された場合
   if(m_file_on=="" || m_file_off=="")
      ::Print(__FUNCTION__," > Both icons must be set for the cursor!");
  }

テキストボックスの作成には、5つのprivateメソッドと1つのpublicメソッドが必要です。 

class CTextEdit : public CElement
  {
private:
   //--- エディットボックス作成オブジェクト
   CRectLabel        m_area;
   CBmpLabel         m_icon;
   CLabel            m_label;
   CEdit             m_edit;
   CPointer          m_text_select;
   //---
public:
   //--- エディットボックス作成メソッド
   bool              CreateTextEdit(const long chart_id,const int subwin,const string label_text,const int x,const int y);
   //---
private:
   bool              CreateArea(void);
   bool              CreateIcon(void);
   bool              CreateLabel(void);
   bool              CreateEdit(void);
   bool              CreateTextSelectPointer(void);
  };


CTextEditの残りは、このシリーズの前回の記事ですでに取り上げられてきたものだけです。ご自身でその機能をお調べください。現在のバージョンのテキストエディットボックスには 63文字という制限があります。 

 

ピクチャスライダー

ピクチャスライダーは、グラフィカルインターフェイスの情報コントロールに属します。クイックリファレンスガイドの作成は便利です。ここでは、価格チャートの特定の状況や、使用されているMQLアプリケーションのグラフィカルインターフェイスの特定のコントロールの目的について簡単に説明できます。 

ピクチャスライダーのすべてのコンポーネントを列挙しましょう。

  1. 背景
  2. スライダー矢印ボタン
  3. ラジオボタングループ
  4. ラジオボタングループに関連付けられた画像グループ


 

図2 ピクチャスライダーのコンポーネント

 

ピクチャスライダー作成クラス

他のクラスに存在する標準的なメソッドを持つPicturesSlider.mqhファイルを作成してWndContainer.mqhファイルに含みます。以下は、ユーザがカスタマイズできるコントロールのプロパティです。

  • コントロールの背景色
  • コントロールの背景フレームの色
  • Y軸に沿った画像マージン
  • 2つの軸(x、y)に沿ったスライダー矢印のマージン
  • 2つの軸(x、y)に沿ったラジオボタンのマージン
  • ラジオボタン間のマージン
//+------------------------------------------------------------------+
//| ピクチャスライダー作成クラス                           |
//+------------------------------------------------------------------+
class CPicturesSlider : public CElement
  {
private:
   //--- 背景色と背景フレームの色
   color             m_area_color;
   color             m_area_border_color;
   //--- Y軸に沿った画像マージン
   int               m_pictures_y_gap;
   //--- ボタンのマージン
   int               m_arrows_x_gap;
   int               m_arrows_y_gap;
   //--- ラジオボタンのマージン
   int               m_radio_buttons_x_gap;
   int               m_radio_buttons_y_gap;
   int               m_radio_buttons_x_offset;
   //---
public:
   //--- (1) 背景色 (2) 背景フレームの色
   void              AreaColor(const color clr)              { m_area_color=clr;                      }
   void              AreaBorderColor(const color clr)        { m_area_border_color=clr;               }
   //--- 矢印ボタンのマージン
   void              ArrowsXGap(const int x_gap)             { m_arrows_x_gap=x_gap;                  }
   void              ArrowsYGap(const int y_gap)             { m_arrows_y_gap=y_gap;                  }
   //--- Y軸に沿った画像マージン
   void              PictureYGap(const int y_gap)            { m_pictures_y_gap=y_gap;                }
   //--- (1) ラジオボタンのマージン (2) ラジオボタン間の距離
   void              RadioButtonsXGap(const int x_gap)       { m_radio_buttons_x_gap=x_gap;           }
   void              RadioButtonsYGap(const int y_gap)       { m_radio_buttons_y_gap=y_gap;           }
   void              RadioButtonsXOffset(const int x_offset) { m_radio_buttons_x_offset=x_offset;     }
  };

 ピクチャスライダーの作成には、5つのprivateメソッドと1つのpublicメソッドが必要です。

class CPicturesSlider : public CElement
  {
private:
   //--- コントロール作成のためのオブジェクト
   CRectLabel        m_area;
   CBmpLabel         m_pictures[];
   CRadioButtons     m_radio_buttons;
   CIconButton       m_left_arrow;
   CIconButton       m_right_arrow;
   //---
public:
   //--- コントロール作成メソッド
   bool              CreatePicturesSlider(const long chart_id,const int subwin,const int x,const int y);
   //---
private:
   bool              CreateArea(void);
   bool              CreatePictures(void);
   bool              CreateRadioButtons(void);
   bool              CreateLeftArrow(void);
   bool              CreateRightArrow(void);
  };

コントロールの幅は、ユーザー定義のパラメータに基づいて自動的に計算されます。これらのパラメータには、コントロールの左端からのラジオボタンのグループのマージンもふくまれ、ピクチャスライダーの右矢印ボタンの座標はこれに相対して計算されます。コントロールの高さも画像サイズに依存します。画像サイズは同じであると仮定されているので、計算はグループの最初の画像のサイズを使用します。

コントロールを作成するためのメインメソッドを呼び出す前に、CPicturesSlider :: AddPicture ()メソッドを使用して画像を配列に追加する必要があります。画像へのパスがこのメソッドの唯一の引数として設定されていない場合はデフォルトパスが適用されます。  

//+------------------------------------------------------------------+
//|                                               PicturesSlider.mqh |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
...
//--- デフォルト画像
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp64\\no_image.bmp"
//+------------------------------------------------------------------+
//| ピクチャスライダー作成クラス                            |
//+------------------------------------------------------------------+
class CPicturesSlider : public CElement
  {
private:
   //--- 画像の配列(画像へのパス)
   string            m_file_path[];
   //--- 画像へのデフォルトパス
   string            m_default_path;
   //---
public:
   //--- 画像を追加する
   void              AddPicture(const string file_path="");
  };
//+------------------------------------------------------------------+
//| コンストラクタ                                                     |
//+------------------------------------------------------------------+
CPicturesSlider::CPicturesSlider(void) : m_default_path("Images\\EasyAndFastGUI\\Icons\\bmp64\\no_image.bmp"),
                                         m_area_color(clrNONE),
                                         m_area_border_color(clrNONE),
                                         m_arrows_x_gap(2),
                                         m_arrows_y_gap(2),
                                         m_radio_button_width(12),
                                         m_radio_buttons_x_gap(25),
                                         m_radio_buttons_y_gap(1),
                                         m_radio_buttons_x_offset(20),
                                         m_pictures_y_gap(25)
  {
//--- コントロールクラス名を基本クラスに格納する
   CElement::ClassName(CLASS_NAME);
//--- 左マウスクリックの優先順位を設定する
   m_zorder=0;
  }
//+------------------------------------------------------------------+
//| 画像を追加する                                                |
//+------------------------------------------------------------------+
void CPicturesSlider::AddPicture(const string file_path="")
  {
//--- 配列サイズを1要素で増やす
   int array_size=::ArraySize(m_pictures);
   int new_size=array_size+1;
   ::ArrayResize(m_pictures,new_size);
   ::ArrayResize(m_file_path,new_size);
//--- 受け取ったパラメータの値を格納する
   m_file_path[array_size]=(file_path=="")?m_default_path : file_path;
  }

グループの画像を表示するにはCPicturesSlider::SelectPicture() メソッドを使用します。このメソッドは矢印ボタンとラジオボタンを押すと CPicturesSlider クラスのハンドラで呼び出されます。  

class CPicturesSlider : public CElement
  {
public:
   //--- 指定されたインデックスで画像を切り替える
   void              SelectPicture(const uint index);
  };
//+------------------------------------------------------------------+
//| 表示される画像を指定する                   |
//+------------------------------------------------------------------+
void CPicturesSlider::SelectPicture(const uint index)
  {
//--- 画像数を取得する
   uint pictures_total=PicturesTotal();
//--- グループに画像がない場合は報告する
   if(pictures_total<1)
     {
      ::Print(__FUNCTION__," > This method is to be called, "
              "if a group contains at least one picture!Use the CPicturesSlider::AddPicture() method");
      return;
     }
//--- 配列の範囲を超えた場合、インデックス値を調整する
   uint correct_index=(index>=pictures_total)?pictures_total-1 : index;
//--- このインデックスでラジオボタンを選択する
   m_radio_buttons.SelectRadioButton(correct_index);
//--- 画像へ切り替える
   for(uint i=0; i<pictures_total; i++)
     {
      if(i==correct_index)
         m_pictures[i].Timeframes(OBJ_ALL_PERIODS);
      else
         m_pictures[i].Timeframes(OBJ_NO_PERIODS);
     }
  }

矢印ボタンを押すと、コントロールのイベントハンドラがCPicturesSlider :: OnClickLeftArrow () メソッドとCPicturesSlider :: OnClickRightArrow () メソッドを呼び出します。下のリストは、左マウスボタンのメソッドのコードを示しています。ピクチャスライダーボタンをクリックするイベントは、必要に応じてMQLアプリケーションのカスタムクラスでトレースできます。 

class CPicturesSlider : public CElement
  {
public:
private:
   //--- 左ボタンのクリックの処理
   bool              OnClickLeftArrow(const string clicked_object);
   //--- 右ボタンのクリックの処理
   bool              OnClickRightArrow(const string clicked_object);
  };
//+------------------------------------------------------------------+
//| 左ボタンのクリックの処理                                   |
//+------------------------------------------------------------------+
bool CPicturesSlider::OnClickLeftArrow(const string clicked_object)
  {
//--- クリックされたのがボタンでなければ終了する
   if(::StringFind(clicked_object,CElement::ProgramName()+"_icon_button_",0)<0)
      return(false);
//--- オブジェクト名からコントロールの識別子を取得する
   int id=CElement::IdFromObjectName(clicked_object);
//--- オブジェクト名からコントロールのインデックスを取得する
   int index=CElement::IndexFromObjectName(clicked_object);
//--- コントロールの識別子が一致しない場合は終了する
   if(id!=CElement::Id())
      return(false);
//--- コントロールのインデックスが一致しない場合は終了する
   if(index!=0)
      return(false);
//--- 選択されたラジオボタンの現在のインデックスを取得する
   int selected_radio_button=m_radio_buttons.SelectedButtonIndex();
//--- 画像を切り替える
   SelectPicture(--selected_radio_button);
//--- それについてのメッセージを送信する
   ::EventChartCustom(m_chart_id,ON_CLICK_BUTTON,CElement::Id(),CElement::Index(),"");
   return(true);
  }

下記はピクチャスライダーのイベントハンドラの短縮コードを一覧します。スライダのラジオボタンをクリックしたイベントもここで追跡されることは明らかです。コントロール識別子がピクチャスライダーの識別子と等しいとローカルグループ内のラジオボタンがクリックされたことを理解することができます。 

//+------------------------------------------------------------------+
//| イベントハンドラ                                               |
//+------------------------------------------------------------------+
void CPicturesSlider::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- カーソル移動イベントの処理
...
//--- ラジオボタンのクリックイベントの処理
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_LABEL)
     {
      //--- これがスライダーのラジオボタンの場合は画像を切り替える
      if(lparam==CElement::Id())
         SelectPicture(m_radio_buttons.SelectedButtonIndex());
      //---
      return;
     }
//--- オブジェクトのマウス左クリックイベントの処理
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      //--- スライダーの矢印ボタンがクリックされた場合は画像を切り替える
      if(OnClickLeftArrow(sparam))
         return;
      if(OnClickRightArrow(sparam))
         return;
      //---
      return;
     }
  }

 

テキストラベルとピクチャ

補足として、ライブラリにはシンプルなテキストラベルと画像を作成するための新しい CTextLabel CPictureクラスの2つが含まれています。これらは、他のコントロールにバインドすることなく独立したオブジェクトとして使用できます。内容はとても簡単です。CPictureクラスでユーザが変更できるのは画像へのパスを示す1プロパティだけです。このためにはCPicture::Path()メソッドが実装されています。カスタムパスが指定されていなければデフォルト画像が使用されます。ピクチャは、MQLアプリケーションのグラフィカルインタフェースの作成後も、いつでもプログラムで変更することができます。

//+------------------------------------------------------------------+
//|                                                      Picture.mqh |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Element.mqh"
#include "Window.mqh"
//--- リソース
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp64\\no_image.bmp"
//+------------------------------------------------------------------+
//| 画像作成クラス                                       |
//+------------------------------------------------------------------+
class CPicture : public CElement
  {
private:
   //--- 画像へのパス
   string            m_path;
   //---
public:
   //--- 画像へのパスの取得/設定
   string            Path(void)               const { return(m_path);             }
   void              Path(const string path);
  };
//+------------------------------------------------------------------+
//| コンストラクタ                                                      |
//+------------------------------------------------------------------+
CPicture::CPicture(void) : m_path("Images\\EasyAndFastGUI\\Icons\\bmp64\\no_image.bmp")

  {
//--- コントロールクラス名を基本クラスに格納する
   CElement::ClassName(CLASS_NAME);
//--- 左マウスクリックの優先順位を設定する
   m_zorder=0;
  }
//+------------------------------------------------------------------+
//| 画像を設定する                                                |
//+------------------------------------------------------------------+
void CPicture::Path(const string path)
  {
   m_path=path;
   m_picture.BmpFileOn("::"+path);
   m_picture.BmpFileOff("::"+path);
  }

テキストラベルでは、すべてが非常に単純で、ユーザが定義できるプロパティは4つだけです。

  • ラベルのテキスト
  • テキストの色
  • フォント
  • フォントサイズ
//+------------------------------------------------------------------+
//| テキストラベル作成クラス                                |
//+------------------------------------------------------------------+
class CTextLabel : public CElement
  {
public:
   //--- ラベルテキストを取得/設定する
   string            LabelText(void)             const { return(m_label.Description()); }
   void              LabelText(const string text)      { m_label.Description(text);     }
   //--- テキストラベルの (1) 色 (2) フォント (3) フォントサイズの設定
   void              LabelColor(const color clr)       { m_label.Color(clr);            }
   void              LabelFont(const string font)      { m_label.Font(font);            }
   void              LabelFontSize(const int size)     { m_label.FontSize(size);        }
  };

 

フォントを使用するためのCFontsクラス

フォントの選択を容易にするために、CFontsクラスが実装されています。これは187フォントを含みます。これらは端末のシステムフォントです。これは特定のグラフィックオブジェクトの設定で一覧できると思われます。

 図3 端末のシステムフォント

図3 端末のシステムフォント


フォントファイル(Fonts.mqh)は "MetaTrader 5\MQL5\Include\EasyAndFastGUI\Fonts.mqh"ディレクトリに位置します。このファイルはライブラリのスキーム全体で完全にアクセスできるようにObjects.mqhファイルにインクルードされています。

//+------------------------------------------------------------------+
//|                                                      Objects.mqh |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Enums.mqh"
#include "Defines.mqh"
#include "..\Fonts.mqh"
#include "..\Canvas\Charts\LineChart.mqh"
#include <ChartObjects\ChartObjectSubChart.mqh>
#include <ChartObjects\ChartObjectsBmpControls.mqh>
#include <ChartObjects\ChartObjectsTxtControls.mqh>

CFontsクラスに含まれているのはフォント配列のサイズの取得インデックスによるフォントの取得のための2つのパブリックメソッドのみです。フォントの配列はクラスコンストラクタで初期化されています。 

//+------------------------------------------------------------------+
//|                                                        Fonts.mqh |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| フォントを使用するためのクラス                                     |
//+------------------------------------------------------------------+
class CFonts
  {
private:
   //--- フォントの配列
   string            m_fonts[];
   //---
public:
                     CFonts(void);
                    ~CFonts(void);
   //--- フォント数を返す
   int               FontsTotal(void) const { return(::ArraySize(m_fonts)); }
   //--- フォントをインデックスで返す
   string            FontsByIndex(const uint index);
   //---
private:
   //--- フォントの配列を初期化する
   void              InitializeFontsArray(void);
  };
//+------------------------------------------------------------------+
//| コンストラクタ                                                      |
//+------------------------------------------------------------------+
CFonts::CFonts(void)
  {
//--- フォントの配列を初期化する
   InitializeFontsArray();
  }
//+------------------------------------------------------------------+
//| デストラクタ                                                       |
//+------------------------------------------------------------------+
CFonts::~CFonts(void)
  {
   ::ArrayFree(m_fonts);
  }

CFonts::FontsByIndex()メソッドが呼び出されると配列サイズの超過を予防するための調整が行われます。:

//+------------------------------------------------------------------+
//| フォントをインデックスで返す                                       |
//+------------------------------------------------------------------+
string CFonts::FontsByIndex(const uint index)
  {
//--- 配列サイズ
   uint array_size=FontsTotal();
//--- サイズが超過した場合の調整
   uint i=(index>=array_size)?array_size-1 : index;
//--- フォントを返す
   return(m_fonts[i]);
  }

 

追加的なライブラリ更新

1. ダイアログボックスにツールヒントが正しく表示されない問題を修正しました。これで、メインウィンドウのツールヒントボタンが押された状態が、グラフィカルインタフェースのすべてのウィンドウに適用されます。ボタンを押すと、新しい ON_WINDOW_TOOLTIPSイベント識別子を持つメッセージが生成されます( Defines.mqh ファイルを参照)。

//+------------------------------------------------------------------+
//|                                                      Defines.mqh |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
...
#define ON_WINDOW_TOOLTIPS         (29) // ツールヒントボタンのクリック

したがって、ツールヒントの処理のためにOnClickTooltipsButton()メソッドがCWindowクラスに追加されました。 

//+------------------------------------------------------------------+
//| コントロールフォーム作成クラス                     |
//+------------------------------------------------------------------+
class CWindow : public CElement
  {
private:
   //--- ツールヒントボタンクリックのイベントの処理
   bool              OnClickTooltipsButton(const string clicked_object);
  };
//+------------------------------------------------------------------+
//| チャートイベントハンドラ                                        |
//+------------------------------------------------------------------+
void CWindow::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- オブジェクトクリックイベントの処理
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      //--- ツールヒントボタンがクリックされた場合
      if(OnClickTooltipsButton(sparam))
         return;
     }
  }
//+------------------------------------------------------------------+
//| ツールヒントボタンクリックのイベントの処理           |
//+------------------------------------------------------------------+
bool CWindow::OnClickTooltipsButton(const string clicked_object)
  {
//--- ウィンドウがダイアログボックスの場合はこのボタンは必須でない
   if(m_window_type==W_DIALOG)
      return(false);
//--- クリックされたのがラジオボタンでなければ終了する
   if(::StringFind(clicked_object,CElement::ProgramName()+"_window_tooltip_",0)<0)
      return(false);
//--- オブジェクト名からコントロールの識別子を取得する
   int id=CElement::IdFromObjectName(clicked_object);
//--- コントロールの識別子が一致しない場合は終了する
   if(id!=CElement::Id())
      return(false);
//--- 状態をクラスフィールドに収納する
   m_tooltips_button_state=m_button_tooltip.State();
//--- それについてのメッセージを送信する
   ::EventChartCustom(m_chart_id,ON_WINDOW_TOOLTIPS,CElement::Id(),CElement::Index(),"");
   return(true);
  }

このすべてがライブラリエンジン(CWndEventsクラス)で機能するためには ON_WINDOW_TOOLTIPS 識別子を持つイベントを処理する OnWindowTooltips () メソッドが追加されました : 

class CWndEvents : public CWndContainer
  {
private:
   //--- ツールヒントの有効/無効化
   bool              OnWindowTooltips(void);
  };
//+------------------------------------------------------------------+
//| CHARTEVENT_CUSTOMイベント                                        |
//+------------------------------------------------------------------+
void CWndEvents::ChartEventCustom(void)
  {
//--- フォーム最小化のシグナルの場合
//--- フォーム最大化のシグナルの場合
//--- シグナルがX軸に沿ってコントロールのサイズを変えるための場合
//--- シグナルがY軸に沿ってコントロールのサイズを変えるための場合
//--- シグナルがツールヒントの有効/無効化のための場合
   if(OnWindowTooltips())
      return;

//--- 開始項目の下のコンテキストメニューを非表示にするシグナルの場合
//--- すべてのコンテキストメニューを非表示にするシグナルの場合
//--- ダイアログウィンドウを開くシグナルの場合
//--- ダイアログウィンドウを閉じるシグナルの場合
//--- 指定されたフォームの要素の色をすべてゼロにするシグナルの場合
//--- マウスの左クリックの優先順位をリセットするシグナルの場合
//--- マウスの左クリックの優先順位を復元するシグナルの場合
  }
//+------------------------------------------------------------------+
//| ON_WINDOW_TOOLTIPSイベント                                       |
//+------------------------------------------------------------------+
bool CWndEvents::OnWindowTooltips(void)
  {
//--- ツールヒントの有効/無効化シグナルの場合
   if(m_id!=CHARTEVENT_CUSTOM+ON_WINDOW_TOOLTIPS)
      return(false);
//--- ウィンドウの識別子が一致した場合
   if(m_lparam!=m_windows[0].Id())
      return(true);
//--- すべてのウィンドウでツールヒントモードを同期させる
   int windows_total=WindowsTotal();
   for(int w=0; w<windows_total; w++)
     {
      if(w>0)
         m_windows[w].TooltipButtonState(m_windows[0].TooltipButtonState());
     }
//---
   return(true);
  }

2. 以下のコントロールの作成後に説明のテキストを変更する機能が追加されました。 

 

図4 作成後にテキストを変更できるコントロールのリスト


3. 必要な場合すべてのコントロールでアイコンを設定できるようになりました(下の表を参照)。さらに、作成後にコントロールアイコンを変更する機能が追加されました。


 

図5 作成後にアイコンを変更できるコントロールのリスト

 

上の表のすべてのコントロールのアイコンを置き換えるにはIconFileOn() およびIconFileOff()メソッドが存在します。


4. 作成後に全タイプのボタンとタブの状態(押されている/いない)をプログラムで管理する機能が追加されました。次の表はこの追加を含むコントロールを示します。

 

図6。作成後に状態(押されている/いない)が変更できるコントロールのリスト


5. 下記のコントロールの上にマウスカーソルがホバーされたときに項目を強調表示するアルゴリズムを最適化しました。

 

図7 項目の強調表示アルゴリズムが最適化されたコントロール

 

プログラムは以前は上記のコントロールのリスト内のすべての項目を反復処理してマウスカーソルの位置を確認していました。したがって、カーソル下の項目は異なる色で強調表示され、項目の残りの部分はデフォルト色に設定されていました。しかし、この方法は非常にリソース集中的なので、最適化する必要がありました。今度は、項目の配列全体を反復処理する代わりに、色の変更には2つの項目のみが関与します。サイクル内の検索は、別の項目への遷移があったとき、つまりフォーカスが変更されたときにのみ行われます。 

さらに、例として、CListViewクラスでこれがどのように実装されたかを考えてみましょう。上記を実装するには、(1)最後にフォーカスを当てたアイテムのインデックスを格納するm_prev_item_index_focusクラスフィールドと (2)項目へのフォーカスを確認するCListView :: CheckItemFocus()メソッドの追加と (3) CListView :: ChangeItemsColor >() メソッドのアルゴリズムの変更が必要です。  

//+------------------------------------------------------------------+
//| リストビュー作成クラス                                   |
//+------------------------------------------------------------------+
class CListView : public CElement
  {
private:
   //--- ある項目から別の項目へのマウスカーソルの移動の瞬間を判断する
   int               m_prev_item_index_focus;
   //---
private:
   //--- カーソルが上をホバーしたらリストビュー項目の色を変更する
   void              ChangeItemsColor(void);
   //--- カーソルが上をホバーしたらリストビュー項目のフォーカスを確認する
   void              CheckItemFocus(void);
  };

CListView ::CheckItemFocus() メソッドは、マウスカーソルがコントロール(この場合はCListView)の領域内に入ったとき及びある項目から別の項目に変更されたときだけに呼び出されます (以下のコードを参照)。マウスがホバーしている項目が見つかると、そのインデックスが保存されます。 

//+------------------------------------------------------------------+
//| カーソルが上をホバーしたらリストビュー項目のフォーカスを確認する   |
//+------------------------------------------------------------------+
void CListView::CheckItemFocus(void)
  {
//--- スクロールバースライダーの現在位置を取得する
   int v=m_scrollv.CurrentPos();
//--- カーソルがホバーしている項目を特定して強調表示する
   for(int i=0; i<m_visible_items_total; i++)
     {
      //--- リストビューの範囲を超えていない場合はカウンタを増やす
      if(v>=0 && v<m_items_total)
         v++;
      //--- 選択された項目をスキップする
      if(m_selected_item_index==v-1)
        {
         m_items[i].BackColor(m_item_color_selected);
         m_items[i].Color(m_item_text_color_selected);
         continue;
        }
      //--- カーソルがこの項目でホバーしている場合は強調表示する
      if(m_mouse.X()>m_items[i].X() && m_mouse.X()<m_items[i].X2() &&
         m_mouse.Y()>m_items[i].Y() && m_mouse.Y()<m_items[i].Y2())
        {
         m_items[i].BackColor(m_item_color_hover);
         m_items[i].Color(m_item_text_color_hover);
         //--- 項目を記憶する
         m_prev_item_index_focus=i;
         break;
        }
     }
  }

CListView::CheckItemFocus()メソッドは上記のケースでCListView::ChangeItemsColor()メソッドの中から呼び出されます (以下のコードを参照)。

//+------------------------------------------------------------------+
//| カーソルが上をホバリングした時のリストビュー項目の色の変更  |
//+------------------------------------------------------------------+
void CListView::ChangeItemsColor(void)
  {
//--- カーソルがホバーした時の項目の強調表示が有効になっていないかスクロールバーがアクティブな場合には終了する
   if(!m_lights_hover || m_scrollv.ScrollState())
      return;
//--- これがドロップダウン要素ではなくフォームがブロックされている場合には終了する
   if(!CElement::IsDropdown() && m_wnd.IsLocked())
      return;
//--- 再びリストビューの場合
   if(m_prev_item_index_focus==WRONG_VALUE)
     {
      //--- 現在の項目上のフォーカスを確認する
      CheckItemFocus();
     }
   else
     {
      //--- 現在の行上のフォーカスを確認する
      int i=m_prev_item_index_focus;
      bool condition=m_mouse.X()>m_items[i].X() && m_mouse.X()<m_items[i].X2() &&
                     m_mouse.Y()>m_items[i].Y() && m_mouse.Y()<m_items[i].Y2();
      //--- 他の項目に動いた場合
      if(!condition)
        {
         //--- 前の項目の色をリセットする
         m_items[i].BackColor(m_item_color);
         m_items[i].Color(m_item_text_color);
         m_prev_item_index_focus=WRONG_VALUE;
         //--- 新しい項目の色をリセットする
         CheckItemFocus();
        }
     }
  }

CListView::OnEvent()イベントハンドラではCListView::ChangeItemsColor()メソッドはマウスカーソルがコントロールの領域内にあるときのみに呼び出されます。 カーソルがコントロール領域を離れると、デフォルトの色が設定されて項目のインデックス値がリセットされます。イベントハンドラの短縮版を以下に示します。 

//+------------------------------------------------------------------+
//| イベントハンドラ                                               |
//+------------------------------------------------------------------+
void CListView::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- カーソル移動イベントの処理
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      //--- 要素が隠れている場合は終了する
      //--- サブウィンドウの番号が一致しない場合は終了する
      //--- 要素上のフォーカスの確認
      //--- これはドロップダウンリストでマウスボタンが押下されている
      //--- スライダーの管理が有効になっている場合はリストを移動する

      //--- フォーカスされていない場合は要素の色をリセットする
      if(!CElement::MouseFocus())
        {
         //--- 項目がすでにフォーカスされている
         if(m_prev_item_index_focus!=WRONG_VALUE)
           {
            //--- リストビューの色をリセットする
            ResetColors();
            m_prev_item_index_focus=WRONG_VALUE;
           }
         return;
        }
      //--- カーソルが上をホバーしたらリストビュー項目の色を変更する
      ChangeItemsColor();
      return;
     }
  }

CTableCCalendarCTreeViewクラスでも同じ原則が実装されていますが、各コントロールの特性が考慮されています。

6. 2状態モード(クリックしてからボタンを放していない状態)でCIconButtonタイプのボタンを押すと、別のアイコンが表示されます(設定されている場合)。押されたボタンのアイコンはCIconButton :: IconFilePressedOn()CIconButton :: IconFilePressedOff()メソッドを使用して設定できます。 

//+------------------------------------------------------------------+
//| アイコンボタン作成クラス |
//+------------------------------------------------------------------+
class CIconButton : public CElement
  {
private:
   //--- ボタンのアクティブ、ブロックされた及び押された状態を示すアイコン
   string            m_icon_file_on;
   string            m_icon_file_off;
   string            m_icon_file_pressed_on;
   string            m_icon_file_pressed_off;

   //---
public:
   //--- ボタンが押された、アクティブ及びブロックされた状態でのアイコンの設
   void              IconFileOn(const string file_path);
   void              IconFileOff(const string file_path);
   void              IconFilePressedOn(const string file_path);
   void              IconFilePressedOff(const string file_path);

  };
//+------------------------------------------------------------------+
//| 押された"ON"の状態のアイコンを設定する    |
//+------------------------------------------------------------------+
void CIconButton::IconFilePressedOn(const string file_path)
  {
//--- ボタンの2状態モードが無効な場合は終了する
   if(!m_two_state)
      return;
//--- 画像へのパスを格納する
   m_icon_file_pressed_on=file_path;
//--- ボタンが押下されているかを即時決定する
   if(m_button.State())
      m_icon.BmpFileOn("::"+file_path);
  }
//+------------------------------------------------------------------+
//| 押された"OFF"の状態のアイコンを設定する   |
//+------------------------------------------------------------------+
void CIconButton::IconFilePressedOff(const string file_path)
  {
//--- ボタンの2状態モードが無効な場合は終了する
   if(!m_two_state)
      return;
//--- 画像へのパスを格納する
   m_icon_file_pressed_off=file_path;
//--- ボタンが押下されているかを即時決定する
   if(m_button.State())
      m_icon.BmpFileOff("::"+file_path);
  }

7. テーブル(CTable)の行をプログラムで選択する機能を追加しました。このためにはCTable::SelectRow()メソッドを使用します。すでに選択されている行のインデックスを指定すると選択が解除されます。 

//+------------------------------------------------------------------+
//| エディットボックステーブル作成クラス |
//+------------------------------------------------------------------+
class CTable : public CElement
  {
public:
   //--- テーブルの指定された行を選択する
   void              SelectRow(const uint row_index);
  };
//+------------------------------------------------------------------+
//| テーブルの指定された行を選択する                            |
//+------------------------------------------------------------------+
void CTable::SelectRow(const uint row_index)
  {
//--- 範囲を超過した場合の調整
   uint index=(row_index>=(uint)m_rows_total)?m_rows_total-1 : row_index;
//--- この行がすでに選択されている場合は選択を解除する
   bool is_selected=(index==m_selected_item);
//--- 行のインデックスを格納する
   m_selected_item=(is_selected)?WRONG_VALUE : (int)index;
//--- セルの行を格納する
   m_selected_item_text=(is_selected)?"" : m_vcolumns[0].m_vrows[index];
//--- セルパラメータで文字列を生成する
   string cell_params=string(0)+"_"+string(index)+"_"+m_vcolumns[0].m_vrows[index];
//--- フォーカスをリセットする
   m_prev_item_index_focus=WRONG_VALUE;
//--- テーブルを更新する
   UpdateTable();
//--- 選択された行を強調表示する
   HighlightSelectedItem();
  }

8. CIconTabs コントロールの選択されたタブでの要素表示の問題を修正しました。問題はこのタイプのタブを持つフォームを開いて最大化するときに発生していました。 

 

コントロールを検証するためのアプリケーション

テストアプリケーションを作成しましょう。そこでは、自分で新しいコントロールをすべてテストして練習を行い、異なるモードを評価することができます。アプリケーションのグラフィカルインターフェイスで、次の内容をもつ4つのタブを含むタブコントロール(CTabsクラス)を作成します。

1. 1番目のタブ:

  • プログレスバー(CProgressBar
  • テキストエディットボックス(CTextEdit
  • ドロップダウンリストを持つコンボボックス(CCombobox
  • 数値のためのスピンエディットボックス(CSpinEdit
  • カラーピッカーを呼び出すボタン( CColorButton
  • テキストラベル(CTextLabel

テキストラベル以外のすべてのコントロールのアイコンを設定します。プログレスバーとテキストエディットボックスのコントロールの説明は、そのような機能が利用可能であることを示すために、一定の時間間隔で変更されます。CFontsクラスのすべてのフォントの名前をコンボボックスのリストに置きます。MQLテストアプリケーションのイベントモデルは、コンボボックスからのフォント選択がテキストラベルに反映されるように構築されます。同様に、テキストラベルは、ピッカー内のフォントサイズと色の選択を変更するための数値エディットボックスにバインドされます。 

テキストラベルコントロールのパラメータを管理するイベントハンドラは次のようになります。

//+------------------------------------------------------------------+
//| チャートイベントハンドラ                             |
//+------------------------------------------------------------------+
void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- コンボボックスリストからの選択イベント
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_COMBOBOX_ITEM)
     {
      //--- コントロールの識別子が一致する場合
      if(lparam==m_combobox1.Id())
        {
         //--- フォントを変更する
         m_text_label1.LabelFont(m_combobox1.ButtonText());
        }
      //---
      return;
     }
//--- スピンエディットボックスのボタンのクリックイベント
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_INC ||
      id==CHARTEVENT_CUSTOM+ON_CLICK_DEC)
     {
      //--- コントロールの識別子が一致する場合
      if(lparam==m_spin_edit1.Id())
        {
         //--- フォントサイズを変更する
         m_text_label1.LabelFontSize(int(m_spin_edit1.GetValue()));
        }
      //---
      return;
     }
//--- カラーピッカーを使った色の変更のイベント
   if(id==CHARTEVENT_CUSTOM+ON_END_EDIT)
     {
      //--- コントロールの識別子が一致する場合
      if(lparam==m_spin_edit1.Id())
        {
         //--- フォントサイズを変更する
         m_text_label1.LabelFontSize(int(m_spin_edit1.GetValue()));
        }
      //---
      return;
     }
//--- カラーピッカーを使った色の変更のイベント
   if(id==CHARTEVENT_CUSTOM+ON_CHANGE_COLOR)
     {
      //--- コントロールの識別子が一致する場合
      if(lparam==m_color_picker.Id())
        {
         //--- ボタン1 からの応答の場合
         if(sparam==m_color_button1.LabelText())
           {
            //--- オブジェクトの色を変更する
            m_text_label1.LabelColor(m_color_button1.CurrentColor());
            return;
           }
        }
      return;
     }
//--- ボタン押下イベント
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON)
     {
      //--- カラーピッカーを呼び出す1番目のボタンが押下された場合
      if(sparam==m_color_button1.LabelText())
        {
         //--- ボタンポインタを渡すとカラーピッカーを持つウィンドウが自動的に開く
         m_color_picker.ColorButtonPointer(m_color_button1);
         return;
        }
      //---
      return;
     }
  }

下のスクリーンショットは、グラフィカルインタフェースを使ってテキスト表示を設定する方法を示しています。

図8 2番目のタブのコントロールグループ 

図8 2番目のタブのコントロールグループ


2. 2番目のタブにはピクチャスライダ( CPicturesSlider クラス)の1つのコントロール のみが配置されます。コントロールを自分で簡単にテスト出来るようにグループにはデフォルトの3画像しか追加されません。コントロールが正しく機能するには、同じサイズの画像を用意します。

図9 2番目のタブのピクチャスライダー 

図9 2番目のタブのピクチャスライダー


画像をプログラム的に切り替えるにはCPicturesSlider::SelectPicture()メソッドを使用します。


3. 3番目のタブにはCTableタイプののテーブルが含まれます。プログラム的に行を選択するには、CTable :: SelectRow()メソッドを使用します。 

 図10 3番目のタブのテーブル

図10 3番目のタブのテーブル


4. 4番目のタブには(1) カレンダー、(2)ドロップダウンカレンダー、(3)押されている/いないの2つの状態のためのアイコンを持つボタンがあります。

図11 4番目のタブのコントロールグループ 

図11 4番目のタブのコントロールグループ

 

本稿で紹介されたテストアプリケーションをさらに研究するためには、以下のリンクを使用してダウンロードすることができます。 


おわりに

開発の現段階では、以下の図に示されたような結果が得られるはずです。

 図12 開発の現段階でのライブラリの構造

図12 開発の現段階でのライブラリの構造


次のバージョンでは、ライブラリーは追加のコントロールとともに拡張されます。また、既存のコントロールはさらに開発され、新しい機能で拡張されます。

これらのファイルに含まれている資料の使用についてご質問がある場合は、記事のいずれかでライブラリの開発の詳細をご参照になるか、本稿へのコメント欄でご質問ください。 

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

添付されたファイル |
GUIによる汎用的なオシレーター GUIによる汎用的なオシレーター
この記事では、独自のグラフィカルインターフェイスを使用して、よくあるオシレーターに基づく汎用的なインジケータの作成プロセスについて説明します。GUIは、ユーザーが迅速かつ容易に、グラフ ・ ウィンドウから (開くことがなくそのプロパティ)、各オシレーターの設定を直接変更するとでき、特定のタスクに最適なオプションを選択することができます。
不変なジグザグ 不変なジグザグ
ジグザグは、MT5のユーザーの間で人気の高いインジケーターです。この記事では、ジグザグのさまざまなパターンを作成する可能性について分析します。この結果はEAの開発に有用であるばかりでなく、その関数を拡張する不変なインジケーターとなりえます。
MT4のストラテジーテスターでバイナリーオプションを行う方法 MT4のストラテジーテスターでバイナリーオプションを行う方法
バイナリーオプションストラテジーを構築し、MT4のストラテジーテスターで検証する方法をご紹介します。
トレーダーのライフハック: テストの比較レポート トレーダーのライフハック: テストの比較レポート
この記事では、EAを4 つの異なるトレードでテストします。4つのテストにおけるレポートの最終的な比較は、オンラインストアでの商品のような表にします。追加として、各シンボルの分布図が自動的に作成されます。