ダイアログを使用して取引支援ツールを作る(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を生成しているので、全く一緒だ。
当然、実行結果も全く同じになる。
以降このコードを使っていく。
次回は、もう少し具体的なコンポーネントの配置とポジション操作等を行う。