MQL4の標準ライブラリにあるCAppDialog(ダイアログ)にボタンを載せると、マウスでドラッグして動かせるボタンが簡単に作れます。
ボタン(CButton)単体をドラッグ対応にするのは手間がかかりますが、ダイアログはタイトルバーをつかんで動かす機能を最初から持っているためです。

ボタンのドラッグ
やることは次の3つだけです。
- ボタンをダイアログに
Add()する OnChartEvent()の中でダイアログのChartEvent()を呼ぶ(これでドラッグと最小化が動きます)OnDeinit()でダイアログのDestroy()を呼ぶ(EAを外したときにチャートに残さないため)
CAppDialogは、MT4のデータフォルダ内にある MQL4\Include\Controls\Dialog.mqh に定義されています。
本格的に作るならCAppDialogを継承した専用クラスを作るのが定番ですが、この記事では仕組みをつかみやすくするため、継承せずにCAppDialogをそのまま使います。
Dialog作成
まずはダイアログを作り、その中にボタンを1つ載せます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// DialogとButtonをインクルード #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> CAppDialog testDialog; CButton button_01; int OnInit(){ // ダイアログ作成 // long chart, string name, int subwin, int x1,const int y1,const int x2,const int y2 testDialog.Create(0, "", 0, 200, 50, 360, 160); // ボタン作成 button_01.Create(0, "TestButton", 0, 10, 10, 102, 32); button_01.Text("Button"); // ダイアログにボタンを追加 testDialog.Add(button_01); // ダイアログの実行 testDialog.Run(); return(INIT_SUCCEEDED); } |
ボタンの座標(10, 10)は、チャート上の位置ではなくダイアログの中での位置として扱われます。
ダイアログの中にボタンを載せたUIができました。

ただし、このコードには OnChartEvent() がないため、まだドラッグはできません。次のサンプルで対応します。
サンプルコード(ドラッグ対応)
ボタンをクリックすると、MT4のターミナルの「エキスパート」タブに「Button Pressed」と表示されるようにします。
OnChartEvent() の中で testDialog.ChartEvent() を呼ぶと、ダイアログのドラッグと最小化ができるようになります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <Controls\Dialog.mqh> #include <Controls\Button.mqh> CAppDialog testDialog; CButton button_01; int OnInit(){ // long chart, string name, int subwin, int x1, int y1, int x2, int y2 testDialog.Create(0, "", 0, 200, 100, 310, 160); button_01.Create(0, "TestButton", 0, 0, 0, 102, 32); button_01.Font("Arial"); button_01.Text("Button"); button_01.Color(clrBlue); button_01.ColorBackground(clrAqua); button_01.ColorBorder(clrBlue); testDialog.Add(button_01); testDialog.Run(); return(INIT_SUCCEEDED); } void OnDeinit(const int reason){ testDialog.Destroy(reason); } void OnTick(){ } // Get the object event void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam){ testDialog.ChartEvent(id, lparam, dparam, sparam); if(id == CHARTEVENT_OBJECT_CLICK){ // Button click if(sparam == "TestButton"){ Print("Button Pressed"); } } } |
ダイアログのサイズをボタンに合わせたので、ボタンだけのダイアログになりました。タイトルバーをつかむと、ボタンごと好きな位置へ動かせます。

トレードパネルへの展開
ダイアログにボタンを増やしていけば、トレードパネルのように展開できます。

注意点とつまずきやすいところ
- ドラッグできない、最小化・閉じるボタンが反応しない
OnChartEvent()の中でChartEvent()を呼んでいるか確認してください。これを呼ばないと、ダイアログはマウス操作を受け取れません。 - EAを外してもパネルが残る
OnDeinit()でDestroy(reason)を呼んでいないと、ダイアログやボタンのオブジェクトがチャートに残ることがあります。 - ボタンの名前は重複させない
Create()に渡した名前(例: “TestButton”)は、チャート上のオブジェクト名としても使われます。クリック判定もこの名前で行うので、他のオブジェクトと被らない名前にしてください。 - 作成の失敗に気づけるようにする
サンプルでは省略していますが、実際に使うときはif(!testDialog.Create(...)) return(INIT_FAILED);のように、Create()の戻り値を確認しておくと安心です。 - ボタンが増えてきたら継承する
ボタンが多くなるとOnChartEvent()の中の条件分岐が長くなります。その場合は、CAppDialogを継承したクラスを作り、EVENT_MAP_BEGIN~ON_EVENTでクリック処理を書く方法が見通しやすくなります(MetaQuotesの公式サンプル「Controls」もこの書き方です)。




















