ダイアログを使用して取引支援ツールを作る(2)

前回のつづき。
今回は、ダイアログの中に任意のコンポーネントを配置して、クリック時に処理を実行するところまでコーディングする。

とりあえず、前回のコードを流用してボタンをダイアログ内に配置する。

#property copyright "nisai"
#property link      "https://nisaifx.com"
#property version   "1.00"

#include <Controls/Dialog.mqh>
//ボタンをインクルード
#include <Controls/Button.mqh>

CAppDialog dialog;
//ボタンを宣言
CButton button;

int OnInit(){
   dialog.Create(0, "Dialog", 0, 20, 20, 300, 300);

   //ボタンを生成
   button.Create(
      0,                      //表示させるチャート(0なら現在のチャート)
      dialog.Name()+"Button", //ボタンの名前
      0,                      //表示させるウィンドウ
      10,                     //左上のX座標
      10,                     //左上のY座標
      100,                    //右下のX座標
      40                      //右下のY座標
   );
   
   //ボタンのテキストを設定
   button.Text("ボタン");
   
   //ボタンの文字色・背景色・枠線色を設定
   button.Color(clrWhite);
   button.ColorBackground(clrBlue);
   button.ColorBorder(clrBlue);
   
   //ダイアログにボタンを追加
   dialog.Add(button);
   
   dialog.Run();
   return(INIT_SUCCEEDED);
}

void OnChartEvent(const int id,
                  const long& lparam,
                  const double& dparam,
                  const string& sparam){
   dialog.ChartEvent(id,lparam,dparam,sparam);
}

void OnDeinit(const int reason){
   dialog.Destroy(reason);
}

実行してみる。

ボタンが表示された。
ダイアログを構成するオブジェクトなので、ボタンの名前もダイアログの接頭辞を付けておいたが、これは必須ではない。
ダイアログに対してちゃんとAddされていれば、ダイアログを構成するオブジェクトとして登録され、ダイアログが消えればボタンも一緒に消える。

続いて、ボタンがクリックされた時の処理を書く。
例によってOnChartEventの中で、クリックイベントがボタンに対して発生したかどうかを判定し、処理を行う。

#property copyright "nisai"
#property link      "https://nisaifx.com"
#property version   "1.00"

#include <Controls/Dialog.mqh>
#include <Controls/Button.mqh>

CAppDialog dialog;
CButton button;

int OnInit(){
   dialog.Create(0, "Dialog", 0, 20, 20, 300, 300);
   
   button.Create(0,dialog.Name()+"Button",0,10,10,100,40);

   button.Text("ボタン");
   button.Color(clrWhite);
   button.ColorBackground(clrBlue);   
   button.ColorBorder(clrBlue);
   
   dialog.Add(button);
   
   dialog.Run();
   return(INIT_SUCCEEDED);
}

void OnChartEvent(const int id,
                  const long& lparam,
                  const double& dparam,
                  const string& sparam){
   dialog.ChartEvent(id,lparam,dparam,sparam);
   //クリックイベントがボタンに対して発生したか判定
   if(id==CHARTEVENT_OBJECT_CLICK && sparam==dialog.Name()+"Button"){
      Alert("ボタンがクリックされた");
   }
}

void OnDeinit(const int reason){
   dialog.Destroy(reason);
}

実行し、ボタンをクリックしてみる。

正しく動作した。

ちょっと脇に逸れて、mql5.com(MQLの公式サイト)でサンプルとして書かれているコードについて触れておく。
mql5.comのドキュメントでは、ダイアログなどの使い方を紹介するサンプルコードは、全てダイアログを継承した独自クラスを定義しており、前述のように直接CAppDialogを使用していない。

別にどちらでも構わないのだが、EAやインジケータの作成ではクラス定義というものを行わないことも多いため、独自クラス定義からスタートすると少々とっつきにくく感じるかもしれないと思い、ここまでは公式のサンプルに沿わない形でコーディングした。

公式のサンプルに沿い、CAppDialogを継承した独自クラスを定義して、前述のソースコードを書き直してみる。
またサンプルに従って、オブジェクト生成や色などの変更操作時の戻り値を確認し、どこかで失敗している場合はOnInitで弾くようにする。

#property copyright "nisai"
#property link      "https://nisaifx.com"
#property version   "1.00"

#include <Controls/Dialog.mqh>
#include <Controls/Button.mqh>

//CAppDialogを継承する独自クラスMyDialogを定義
class MyDialog:public CAppDialog{
private:
   //privateメンバとしてボタンを持たせる
   CButton button;
public:
   //WndのCreate、OnEventをオーバーライド(実装は下の方に)
   virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
   virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
protected:
   //ボタンのCreate関数の宣言(実装は下の方に)
   bool CreateButton(void);
};

//イベントハンドラの登録(OnEventの実装)
EVENT_MAP_BEGIN(MyDialog)
   //buttonにON_CLICKが発生したら、OnClickButton関数(実装は下の方に)を呼ぶ
   ON_EVENT(ON_CLICK,button,OnClickButton)
EVENT_MAP_END(CAppDialog)

//ダイアログのCreate関数を実装
bool MyDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2){
   //CAppDialogを生成
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);
   //ボタンを生成
   if(!CreateButton())
      return(false);
   return(true);
}

//ボタンのCreate関数を実装
bool MyDialog::CreateButton(void){
   if(!button.Create(
      m_chart_id,       //m_chart_id:Wndが持つメンバー変数。ここではMyDialogのチャートIDを指す。
      m_name+"Button",  //m_name:Wndが持つメンバー変数。ここではMyDialogの名前を指す。
      m_subwin,         //m_subwin:Wndが持つメンバー変数。ここではMyDialogのウィンドウIDを指す。
      10, 10, 100, 40))
      return(false);
   if(!button.Text("ボタン"))
      return(false);
   if(!button.Color(clrWhite))
      return(false);
   if(!button.ColorBackground(clrBlue))
      return(false);
   if(!button.ColorBorder(clrBlue))
      return(false);
   //MyDialogにボタンを追加
   if(!Add(button))
      return(false);
   return(true);
}

//ボタンに登録するコールバック関数の実装
void OnClickButton(){
   Alert("ボタンがクリックされた");
}

MyDialog dialog;

int OnInit(){
   if(!dialog.Create(0, "Dialog", 0, 20, 20, 300, 300))
      return(INIT_FAILED);
   if(!dialog.Run())
      return(INIT_FAILED);
   return(INIT_SUCCEEDED);
}

void OnChartEvent(const int id,
                  const long& lparam,
                  const double& dparam,
                  const string& sparam){
   dialog.ChartEvent(id,lparam,dparam,sparam);
}

void OnDeinit(const int reason){
   dialog.Destroy(reason);
}

書き方は違うが、結局はCAppDialogを生成しているので、全く一緒だ。
当然、実行結果も全く同じになる。
以降このコードを使っていく。

次回は、もう少し具体的なコンポーネントの配置とポジション操作等を行う。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

コメントする