EAからMT4 を終了させる。

3日ほど前に、SwingPointView のようなインジケータを作ると、ウィンドウの縦幅が取得できなくて困っていると書いたら、何故かCodeBase に縦幅を取得するコードがアップされていました。これを使えば、チャートサイズに依存することなく、テキストオブジェクトをピクセル単位で2行並べることができそうです。ある程度動作確認できたら、更新版をアップする予定です。

それから、昨日紹介した手法は、オフラインチャートでMetaClick1を動かすことができるそうです。(情報提供:T.Yさん
MetaClick1ユーザの人は、是非、2分足や3分足でトレードしてみてください。(意味無いかな…





さて、今日は、EAやインジケータからMetaTrader自身を終了させてしまう方法を紹介します。
これもアプリケーションをWindowsメッセージによってコントロールできる例の1つです。



やり方は、まず、チャートのウィンドウハンドルを WindowHandle で取得して、その親の親の親のウィンドウ=MetaTrader本体のウィンドウに「ウィンドウを閉じろ」メッセージを送るようにします。
コードサンプルは以下の通り。

#import "user32.dll" // 親ウィンドウを取得する為の関数を追加
int GetParent(int);
#import
#include 

int start()
{
  if(!IsDllsAllowed()){
   Alert("Tool Menu -> Option -> Expert Advisors TAB --> Check Allow DLL imports");
   return(0);
  }
  // 親の親の親のハンドルを取得
   int hwnd = GetParent(GetParent(GetParent(WindowHandle(Symbol(),Period()))));
   PostMessageA(hwnd, WM_CLOSE,0, 0); // 「ウィンドウを閉じろ」メッセージを送る
}


話としてはこれで終わりですが、、、何を根拠に親の親の親のウィンドウハンドルを取得しているのかだけ説明しておきますね。
MetaTraderのウィンドウは、

上図のように1つのウィンドウに見えても、内部では複雑な階層構造で管理されています。
WinSpy++というツールで階層構造を確認してみると、

こんな感じになっています。Windowsと呼ばれるだけあって、まさに、ウィンドウだらけです..。
こういう階層構造を調べることで、「親の親の親のウィンドウ」がメインのウィンドウだと分かるのです。
また、この図から、チャートウィンドウは、実は、WindowHandle で取得したウィンドウの親が、チャートウィンドウの本体だと分かります。
チャートウィンドウを閉じたい場合は、

   int hwnd = GetParent(WindowHandle(Symbol(),Period())); // 親のハンドルを取得
   PostMessageA(hwnd, WM_CLOSE,0, 0); // 「ウィンドウを閉じろ」メッセージを送る
}

と書けばOK です。
チャートウィンドウを閉じるテクニックを使う機会は無いと思いますが、EAからMT4を終了させる手法は、MetaTraderのプロファイルをEAから切り替えたい場合に使える・・・かもしれないので、記憶の片隅に残しておいても良いかもしれません。