こんにちは、たかはしみのるです。
この記事から数回に分けて、裁量支援ツールの作成について書いていきます。
ツール概要
今回作成するツールの主な機能は、
です。結構盛りだくさんですね。
エントリ用の画面、決済用の画面とStopLimit注文の管理画面の3つの画面を想定しています。
※画面は詳細を詰めていく中で変わる可能性があります
今回はエントリー用のダイアログの外観を作成してきます。
画面設計
まずはエントリー用の画面の詳細を細かく設計していきます。
ダイアログにラベル、エディットボックス、ボタン、ラジオボタンを配置していきますので、それぞれどんな配置にするのか考えます。
できました。こんな感じでパーツをどこに配置するかあらかじめ決めておくと、コーディングの際に迷わなくて済みます。
プログラミング
では、実際のコードを見ていきます。
インポート
まずは、部品をインポートします。
#include <Controls\Dialog.mqh>
#include <Controls\Edit.mqh>
#include <Controls\Label.mqh>
#include <Controls\Button.mqh>
#include <Controls\RadioButton.mqh>
これで、Dialog、Edit、Label、Buton、RadioButtonを使用する準備ができました。
メンバー定義
次に今回作成するエントリー画面用のクラスを定義します。CEntryDialogクラスをCAppDialogを継承して作成します。
class CEntryDialog : public CAppDialog{
public:
CEntryDialog();
~CEntryDialog();
//create
virtual bool Create(const long chart,const string name,const int subwin);
//Label
CLabel m_labelEntry;
CLabel m_labelLots;
CLabel m_labelTP;
CLabel m_labelSL;
CLabel m_labelStop;
CLabel m_labelStopLimit;
//Edit
CEdit m_editLots;
CEdit m_editTP;
CEdit m_editSL;
CEdit m_editPO;
CEdit m_editStop;
CEdit m_editLimit;
//Button
CButton m_btnSell;
CButton m_btnBuy;
//RadioButton
CRadioButton m_rbtnStream;
CRadioButton m_rbtnPending;
CRadioButton m_rbtnStopLimit;
protected:
bool CreateLabelEntry();
bool CreateLabelLots();
bool CreateLabelTP();
bool CreateLabelSL();
bool CreateLabelStop();
bool CreateLabelStopLimit();
bool CreateRBtnStream();
bool CreateRBtnPending();
bool CreateRBtnStopLimit();
bool CreateEditLots();
bool CreateEditTP();
bool CreateEditSL();
bool CreateEditPO();
bool CreateEditStop();
bool CreateEditLimit();
bool CreateBtnSell();
bool CreateBtnBuy();
};
CEntryDialog::CEntryDialog(){}
CEntryDialog::~CEntryDialog(){}
ここまででメンバ変数、メンバ関数の宣言が終わりました。
ダイアログのCreate
次はダイアログのCreate関数です。
ここではダイアログ自身を作成し、各部品のCreate関数を呼び出します。
bool CEntryDialog::Create( const long chart, const string name, const int subwin){
int x1 = 50;
int y1 = 50;
int x2 = 310;
int y2 = 340;
int i;
string objName;
if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) return false;
if(!CreateLabelEntry()) return false;
if(!CreateLabelLots()) return false;
if(!CreateLabelTP()) return false;
if(!CreateLabelSL()) return false;
if(!CreateLabelStop()) return false;
if(!CreateLabelStopLimit()) return false;
if(!CreateRBtnStream()) return false;
if(!CreateRBtnPending()) return false;
if(!CreateRBtnStopLimit()) return false;
if(!CreateEditLots()) return false;
if(!CreateEditTP()) return false;
if(!CreateEditSL()) return false;
if(!CreateEditPO()) return false;
if(!CreateEditStop()) return false;
if(!CreateEditLimit()) return false;
if(!CreateBtnSell()) return false;
if(!CreateBtnBuy()) return false;
また、ここでダイアログや部品の色やフォントを変える処理を行います。
ダイアログ自体の部品は、ダイアログのコントロール自体を触ります。
その他のオブジェクトについては、オブジェクト名を指定してフォントや色を変更しています。
string prefix=Name();
int total=ControlsTotal();
for(i=0;i<total;i++){
CWnd*obj=Control(i);
objName=obj.Name();
if(objName==prefix+"Client"){
CWndClient *wndclient=(CWndClient*) obj;
wndclient.ColorBackground(clrLavender);
ChartRedraw();
}
if(objName==prefix+"Caption"){
CEdit *edit=(CEdit*) obj;
edit.ColorBackground(clrLightSteelBlue);
ChartRedraw();
}
}
total = ObjectsTotal();
for(i=0; i < total; i++){
objName = ObjectName(i);
if(objName==prefix+"RadioButton_StreamLabel"){
ObjectSetString(m_chart_id, objName, OBJPROP_FONT, "MS Pゴシック");
ObjectSetInteger(m_chart_id, objName, OBJPROP_BGCOLOR, clrLavender);
ObjectSetInteger(m_chart_id, objName, OBJPROP_BORDER_COLOR, clrLavender);
ChartRedraw();
}
if(objName==prefix+"RadioButton_PendingLabel"){
ObjectSetString(m_chart_id, objName, OBJPROP_FONT, "MS Pゴシック");
ObjectSetInteger(m_chart_id, objName, OBJPROP_BGCOLOR, clrLavender);
ObjectSetInteger(m_chart_id, objName, OBJPROP_BORDER_COLOR, clrLavender);
ChartRedraw();
}
if(objName==prefix+"RadioButton_StopLimitLabel"){
ObjectSetString(m_chart_id, objName, OBJPROP_FONT, "MS Pゴシック");
ObjectSetInteger(m_chart_id, objName, OBJPROP_BGCOLOR, clrLavender);
ObjectSetInteger(m_chart_id, objName, OBJPROP_BORDER_COLOR, clrLavender);
ChartRedraw();
}
}
return true;
}
各部品の作成と配置
最後に各部品の作成と配置の部分を実装します。
bool CEntryDialog::CreateLabelEntry(){
int x1 = 5;
int y1 = 5;
int x2 = 60;
int y2 = 20;
if(!m_labelEntry.Create(m_chart_id, m_name+"Label_Entry", m_subwin, x1, y1, x2, y2)) return false;
if(!m_labelEntry.Text("■エントリー")) return false;
if(!m_labelEntry.Font("MS Pゴシック")) return false;
if(!Add(m_labelEntry)) return false;
return true;
}
bool CEntryDialog::CreateLabelLots(){
int x1 = 15;
int y1 = 22;
int x2 = 80;
int y2 = 37;
if(!m_labelLots.Create(m_chart_id, m_name+"Label_Lots", m_subwin, x1, y1, x2, y2)) return false;
if(!m_labelLots.Text("ロット数")) return false;
if(!m_labelLots.Font("MS Pゴシック")) return false;
if(!Add(m_labelLots)) return false;
return true;
}
bool CEntryDialog::CreateLabelTP(){
int x1 = 15;
int y1 = 44;
int x2 = 150;
int y2 = 59;
if(!m_labelTP.Create(m_chart_id, m_name+"Label_TP", m_subwin, x1, y1, x2, y2)) return false;
if(!m_labelTP.Text("利益確定")) return false;
if(!m_labelTP.Font("MS Pゴシック")) return false;
if(!Add(m_labelTP)) return false;
return true;
}
bool CEntryDialog::CreateLabelSL(){
int x1 = 15;
int y1 = 66;
int x2 = 150;
int y2 = 81;
if(!m_labelSL.Create(m_chart_id, m_name+"Label_SL", m_subwin, x1, y1, x2, y2)) return false;
if(!m_labelSL.Text("損切")) return false;
if(!m_labelSL.Font("MS Pゴシック")) return false;
if(!Add(m_labelSL)) return false;
return true;
}
bool CEntryDialog::CreateLabelStop(){
int x1 = 45;
int y1 = 154;
int x2 = 170;
int y2 = 169;
if(!m_labelStop.Create(m_chart_id, m_name+"Label_Stop", m_subwin, x1, y1, x2, y2)) return false;
if(!m_labelStop.Text("到達価格")) return false;
if(!m_labelStop.Font("MS Pゴシック")) return false;
if(!Add(m_labelStop)) return false;
return true;
}
bool CEntryDialog::CreateLabelStopLimit(){
int x1 = 45;
int y1 = 176;
int x2 = 170;
int y2 = 181;
if(!m_labelStopLimit.Create(m_chart_id, m_name+"Label_StopLimit", m_subwin, x1, y1, x2, y2)) return false;
if(!m_labelStopLimit.Text("エントリー価格")) return false;
if(!m_labelStopLimit.Font("MS Pゴシック")) return false;
if(!Add(m_labelStopLimit)) return false;
return true;
}
bool CEntryDialog::CreateRBtnStream(){
int x1 = 15;
int y1 = 88;
int x2 = 150;
int y2 = 108;
if(!m_rbtnStream.Create(m_chart_id, m_name+"RadioButton_Stream", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_rbtnStream)) return false;
if(!m_rbtnStream.Text("成行")) return false;
return true;
}
bool CEntryDialog::CreateRBtnPending(){
int x1 = 15;
int y1 = 110;
int x2 = 150;
int y2 = 130;
if(!m_rbtnPending.Create(m_chart_id, m_name+"RadioButton_Pending", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_rbtnPending)) return false;
if(!m_rbtnPending.Text("指値(逆指値)")) return false;
return true;
}
bool CEntryDialog::CreateRBtnStopLimit(){
int x1 = 15;
int y1 = 132;
int x2 = 150;
int y2 = 152;
if(!m_rbtnStopLimit.Create(m_chart_id, m_name+"RadioButton_StopLimit", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_rbtnStopLimit)) return false;
if(!m_rbtnStopLimit.Text("StopLimit")) return false;
return true;
}
bool CEntryDialog::CreateEditLots(){
int x1 = 170;
int y1 = 22;
int x2 = 240;
int y2 = 42;
if(!m_editLots.Create(m_chart_id, m_name+"Edit_Lots", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_editLots)) return false;
m_editLots.Font("Arial");
m_editLots.FontSize(9);
m_editLots.Text("0.1");
return true;
}
bool CEntryDialog::CreateEditTP(){
int x1 = 170;
int y1 = 44;
int x2 = 240;
int y2 = 64;
if(!m_editTP.Create(m_chart_id, m_name+"Edit_TP", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_editTP)) return false;
m_editTP.Font("Arial");
m_editTP.FontSize(9);
return true;
}
bool CEntryDialog::CreateEditSL(){
int x1 = 170;
int y1 = 66;
int x2 = 240;
int y2 = 86;
if(!m_editSL.Create(m_chart_id, m_name+"Edit_SL", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_editSL)) return false;
m_editSL.Font("Arial");
m_editSL.FontSize(9);
return true;
}
bool CEntryDialog::CreateEditPO(){
int x1 = 170;
int y1 = 110;
int x2 = 240;
int y2 = 130;
if(!m_editPO.Create(m_chart_id, m_name+"Edit_PO", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_editPO)) return false;
m_editPO.Font("Arial");
m_editPO.FontSize(9);
return true;
}
bool CEntryDialog::CreateEditStop(){
int x1 = 170;
int y1 = 154;
int x2 = 240;
int y2 = 174;
if(!m_editStop.Create(m_chart_id, m_name+"Edit_Stop", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_editStop)) return false;
m_editStop.Font("Arial");
m_editStop.FontSize(9);
return true;
}
bool CEntryDialog::CreateEditLimit(){
int x1 = 170;
int y1 = 176;
int x2 = 240;
int y2 = 196;
if(!m_editLimit.Create(m_chart_id, m_name+"Edit_Limit", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_editLimit)) return false;
m_editLimit.Font("Arial");
m_editLimit.FontSize(9);
return true;
}
bool CEntryDialog::CreateBtnSell(){
int x1 = 20;
int y1 = 210;
int x2 = 120;
int y2 = 250;
if(!m_btnSell.Create(m_chart_id, m_name+"Btn_Sell", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_btnSell)) return false;
m_btnSell.Text("Sell");
m_btnSell.FontSize(20);
m_btnSell.ColorBackground(clrAqua);
return true;
}
bool CEntryDialog::CreateBtnBuy(){
int x1 = 140;
int y1 = 210;
int x2 = 240;
int y2 = 250;
if(!m_btnBuy.Create(m_chart_id, m_name+"Btn_Buy", m_subwin, x1, y1, x2,y2)) return false;
if(!Add(m_btnBuy)) return false;
m_btnBuy.Text("Buy");
m_btnBuy.FontSize(20);
m_btnBuy.ColorBackground(clrMagenta);
return true;
}
先に設計した通りに部品を配置しましょう。部品の左上の座標や右上の座標を意識すると記述しやすいです。
これでダイアログの作成は完了です。
作成したダイアログ
では、実際に出来上がったダイアログを表示してみます。
元の設計通りに表示されました。
ただラジオボタンは排他処理がされていないので、現時点では3つとも押すことができます。他のボタンの動作も記述していないので押しても動作しません。
これらはの本体プログラムのOnChartEventで実装する予定です。
本記事を書くにあたって以下のページを参考にしました。興味のある方は読んでみてください。
ここまでお付き合いいただき、ありがとうございました。
次回は残りのダイアログを作る予定です。
コメント
こんにちは。参考にさせていただいております。
if(objName==prefix+”RadioButton_StreamLabel”){}
のRadioButton_StreamLabelはどこかで宣言されているのでしょうか? コード内を検索しても、ここの1箇所しかヒットしないので教えてください。
返信が遅くなり申し訳ありません。
“RadioButton_StreamLabel”は、エントリー用ダイアログの中にある
「成行」と書かれたラベルのオブジェクト名です。
このオブジェクトはCEntryDialog::CreateRBtnStream()の中で作成しています。