MQL4プログラミング 第11回 キー入力でチャート最大化

キーボート押下でチャートを最大化する

今回は前回の「MQL4プログラミング 第10回 バックグラウンドの色を変える(2)」と同じようにキー入力で選択中のチャートを最大化するプログラムを作ります。
私がこの機能を作ったのには理由があります。MT4上でチャートをたくさん並べて見ている時に、あるチャートを最大化しようと「ウィンドウの最大化」ボタンを押すつもりが、その右隣の「ウィンドウを閉じる」ボタンを押してしまい焦る事が何度もあったのでこれを防ぐために今回紹介する機能を取り込みました。
今回の追加機能ではWindows OSの「user32.dll」を直接利用するのでインジケーターの設定時も「DLLの使用を許可する」にチェックを入れる必要があります。なお、今回の機能についてはMac OS上での動作は確認しておりません。ご理解のほど、宜しくお願い致します。

チャートを操作するためのウインドウハンドルを取得

まず、ウィンドウハンドルのイメージを簡単に図に表すと

上記の図よりチャートを最大化する場合は自分の親のウィンドウハンドルに対して設定変更する必要があります。
この点を理解できれば今回の追加機能のソースコードの理解もしやすいと思います。
では、今回のソースコードを切り取りながら解説いたします。

81行目:OnChartEvent関数でキーボードから「Q」キーを取得する設定です。
82行目:「ChartGetInteger(0, CHART_WINDOW_HANDLE)」で自分自身のウィンドウハンドルを取得してGetParent関数で親のウィンドウハンドルを取得してHnd変数に保存します。
85行目:「GetWindowPlacement(Hnd, dpl);」はHndで指定したウィンドウの表示状態と、復元、最小化、最大化された位置を取得しdplに保存します。dplは84行目で定義されている「WINDOWPLACEMENT」の構造体(いつくかのデータの集合体)で

上記14~24行目までの構造体変数にウィンドウの状態が保存されます。

87~89行目:もし親ウィンドウが最大化であれば通常のウィンドウサイズにします。
90~93行目:上記以外(つまり親ウィンドウが最大化でない)の場合は最大化にします。

今回出た新しい機能の解説はここまでです。ソースコードについてもっと詳しく知りたいな、と思ったらご自身でいろいろ検索して調べてみてください。より一層理解が深まると思います。
それではソースコード全体を示します。

// prg-0011.mq4
#property copyright "Copyright 2024, smile-invest-blog.com"
#property link      "https://www.smile-invest-blog.com/prg-0011/"
#property strict
#property indicator_chart_window

/*-- DLLで使用する定数の宣言 ---------------------------------------*/
#define SW_MAXIMIZE      3
#define SW_RESTORE       9
#define SW_SHOWMAXIMIZED 3

/*-- インポートするDLL用の構造体 -----------------------------------*/
struct WINDOWPLACEMENT {
   int Length;
   int Flg;
   int ShowCmd;
   int MinPosX;
   int MinPosY;
   int MaxPosX;
   int MaxPosY;
   int NormalPosLeft;
   int NormalPosTop;
   int NormalPosRight;
   int NormalPosBottom;
};

/*-- インポートするDLLの宣言 ---------------------------------------*/
#import "user32.dll"
   int GetParent(int hWnd);
   int GetWindowPlacement(int hWnd, WINDOWPLACEMENT &lpwndpl);
   int ShowWindow(int hWnd,int nCmdShow);
#import


int    realBars = 0;

color upColor     = C'2,90,98';
color downColor   = C'57,14,71';
color lookColor   = C'73,77,2';
color normalColor;

//+------------------------------------------------------------------+
//| initialization function
//+------------------------------------------------------------------+
int init() {
//---- indicators
   normalColor = getChartBackColor();
//----
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| deinitialization function
//+------------------------------------------------------------------+
int deinit() {
   getChartBackColor(normalColor);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| OnChartEvent function
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---

//キー押下
   if(id == CHARTEVENT_KEYDOWN) {
      if (lparam == 65) { // Aキー
         if (getChartBackColor() != normalColor) {
            setChartBackColor(normalColor);
         }
         else {
            setChartBackColor(lookColor);
         }
      }

      if (lparam == 81) { // Qキー
          int Hnd = GetParent((int)ChartGetInteger(0, CHART_WINDOW_HANDLE));
          //ウィンドウの状態を取得
          WINDOWPLACEMENT dpl;
          GetWindowPlacement(Hnd, dpl);
          //最大化になっている場合
          if (dpl.ShowCmd == SW_SHOWMAXIMIZED) {
              //通常に戻す
              ShowWindow(Hnd, SW_RESTORE);
          } else {
              //最大化する
              ShowWindow(Hnd, SW_MAXIMIZE);
          }
      }
   }
}

//+------------------------------------------------------------------+
//| start function
//+------------------------------------------------------------------+
int start() {
   return(0);
}

//+------------------------------------------------------------------+
//| チャートの背景色を取得する
//| 引数1 チャートID(指定なしの場合は0つまり現在のチャート)
//+------------------------------------------------------------------+
color getChartBackColor(const long chart_ID=0) {
//--- 色を受け取る変数を準備する
   long result = clrNONE;
//--- エラー値をリセットする
   ResetLastError();
//--- チャートの背景色を受け取る
   if(!ChartGetInteger(chart_ID, CHART_COLOR_BACKGROUND, 0, result)) {
      //--- エキスパートジャーナルにエラーメッセージを表示する
      Print(__FUNCTION__+", Error Code = ", GetLastError());
   }
//--- チャートのプロパティの値を返します
   return((color)result);
}

//+------------------------------------------------------------------+
//| チャートの背景色を設定する
//| 引数1 背景色のcolor値
//| 引数2 チャートID(指定なしの場合は0つまり現在のチャート)
//+------------------------------------------------------------------+
bool setChartBackColor(const color clr, const long chart_ID=0) {
//--- エラー値をリセットする
   ResetLastError();
//--- チャートの背景色を設定する
   if(!ChartSetInteger(chart_ID, CHART_COLOR_BACKGROUND, clr)) {
      //--- エキスパート操作ログでエラーメッセージを表示する
      Print(__FUNCTION__+", Error Code = ", GetLastError());
      return(false);
   }
//--- 実行成功
   return(true);
}

コメントを残す

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

CAPTCHA