//+——————————————————————+ //| Panel_Buttons.mq5 | //| Copyright 2017, MetaQuotes Software Corp. | //| https://www.mql5.com | //+——————————————————————+ #property copyright “Copyright 2017, MetaQuotes Software Corp.” #property link “https://www.mql5.com” #property version “1.00” #property description “The panel with several CButton buttons” #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> //+——————————————————————+ //| define | //+——————————————————————+ //— インデントとギャップ #define INDENT_LEFT (11) // 左からのインデント(境界幅の余裕を含む) #define INDENT_TOP (11) // 上からのインデント(境界幅の余裕を含む) #define CONTROLS_GAP_X (5) // ギャップのX座標 #define CONTROLS_GAP_Y (5) // ギャップのY座標 //— ボタン #define BUTTON_WIDTH (100) // サイズのX座標 #define BUTTON_HEIGHT (20) // サイズのY座標 //— 表示領域 #define EDIT_HEIGHT (20) // サイズのY座標 //— カスタム関数型を作成する typedef int(*TAction)(string,int); //+——————————————————————+ //| ファイルを開く | //+——————————————————————+ int Open(string name,int id) { PrintFormat(“%s function called (name=%s id=%d)”,__FUNCTION__,name,id); return(1); } //+——————————————————————+ //| ファイルを保存する | //+——————————————————————+ int Save(string name,int id) { PrintFormat(“%s function called (name=%s id=%d)”,__FUNCTION__,name,id); return(2); } //+——————————————————————+ //| ファイルを閉じる | //+——————————————————————+ int Close(string name,int id) { PrintFormat(“%s function called (name=%s id=%d)”,__FUNCTION__,name,id); return(3); } //+——————————————————————+ //| イベント処理関数を使用してボタンクラスを作成する | //+——————————————————————+ class MyButton: public CButton { private: TAction m_action; // チャートイベントハンドラ public: MyButton(void){} ~MyButton(void){} //— ボタンテキストとイベント処理関数へのポインタを指定するコンストラクタ MyButton(string text,TAction act) { Text(text); m_action=act; } //— OnEvent() イベントハンドラから呼び出されたカスタム関数を設定する void SetAction(TAction act){m_action=act;} //— 標準的なチャートイベントハンドラ virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) override { if(m_action!=NULL && lparam==Id()) { //— カスタムハンドラを呼び出す m_action(sparam,(int)lparam); return(true); } else //— CButton親クラスからハンドラを呼び出した結果を返す return(CButton::OnEvent(id,lparam,dparam,sparam)); } }; //+——————————————————————+ //| CControlsDialogクラス | //| 目的:アプリケーションを管理するためのグラフィカルパネル | //+——————————————————————+ class CControlsDialog : public CAppDialog { private: CArrayObj m_buttons; // ボタン配列 public: CControlsDialog(void){}; ~CControlsDialog(void){}; //— 作成する virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2) override; //— ボタンを追加する bool AddButton(MyButton &button){return(m_buttons.Add(GetPointer(button)));m_buttons.Sort();}; protected: //— ボタンを作成する bool CreateButtons(void); }; //+——————————————————————+ //| チャートにCControlsDialogオブジェクトを作成する | //+——————————————————————+ bool CControlsDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2) { if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2)) return(false); return(CreateButtons()); //— } //+——————————————————————+ //| CControlsDialogパネルを作成してボタンを追加する | //+——————————————————————+ bool CControlsDialog::CreateButtons(void) { //— ボタン座標を計算する int x1=INDENT_LEFT; int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y); int x2; int y2=y1+BUTTON_HEIGHT; //— 関数ポインタとともにボタンオブジェクトを追加する AddButton(new MyButton(“Open”,Open)); AddButton(new MyButton(“Save”,Save)); AddButton(new MyButton(“Close”,Close)); //— グラフィカルにボタンを作成する for(int i=0;i<m_buttons.Total();i++) { MyButton *b=(MyButton*)m_buttons.At(i); x1=INDENT_LEFT+i*(BUTTON_WIDTH+CONTROLS_GAP_X); x2=x1+BUTTON_WIDTH; if(!b.Create(m_chart_id,m_name+“bt”+b.Text(),m_subwin,x1,y1,x2,y2)) { PrintFormat(“Failed to create button %s %d”,b.Text(),i); return(false); } //— CControlsDialogコンテナにそれぞれのボタンを追加する if(!Add(b)) return(false); } //— 成功 return(true); } //— オブジェクトをグローバルレベルで宣言してプログラムを起動するときに自動的に作成する CControlsDialog MyDialog; //+——————————————————————+ //| エキスパート初期化に使用される関数 | //+——————————————————————+ int OnInit() { //— チャートにオブジェクトを作成する if(!MyDialog.Create(0,“Controls”,0,40,40,380,344)) return(INIT_FAILED); //— アプリケーションを起動する MyDialog.Run(); //— アプリケーションがっ正常に初期化された return(INIT_SUCCEEDED); } //+——————————————————————+ //| エキスパート初期化解除に使用される関数 | //+——————————————————————+ void OnDeinit(const int reason) { //— ダイアログを破壊する MyDialog.Destroy(reason); } //+——————————————————————+ //| エキスパートチャートイベント関数 | //+——————————————————————+ void OnChartEvent(const int id, // イベントID const long& lparam, // long型のイベントパラメータ const double& dparam, // double型のイベントパラメータ const string& sparam) // string型のイベントパラメータ { //— チャートイベントのハンドラを親クラス(ここではCAppDialog)から呼び出す MyDialog.ChartEvent(id,lparam,dparam,sparam); } |