リアルタイム系EAでマウスの位置とウィンドウサイズを知る。

MetaTrader5 のパブリックベータテストが10/12..つまり明日から始まる予定ですが、最新の情報ではインジケータからオブジェクトが作れるようになったらしいです。..ということは、既存のインジケータの移植の手間が大幅に省けそうなのでホッとしています。




さて、「Label Object をクリックしたら、数字が変わる」を実現する為には、オブジェクトの位置とマウスの位置関係とマウスの状態を知る必要があります。そこで、今日は、「リアルタイム系EAでマウスの位置とウィンドウサイズを知る。」方法を考えます。


今日は一般向けの便利ツール公開は無いので、マウスの位置取得に興味のない人は読み飛ばし推奨です..。
WindowsAPI を使って何か作りたい初心者な人向けの解説が書いてあるだけです..orz



まずは下準備で、いくつかのWindowsAPIを使えるようにします。

#import "user32.dll"
int GetAsyncKeyState(int vKey);
bool GetClientRect(int HWND, int& LPRECT);
bool GetCursorPos(int& LPPOINT
);
bool ScreenToClient(int HWND, int& LPRECT[]);
#import

これらのAPIについては、以下に資料があります。
vKeyのコード一覧表
http://msdn.microsoft.com/en-us/library/ms645540(VS.85).aspx
GetAsyncKeyState
http://msdn.microsoft.com/ja-jp/library/cc364583.aspx
GetCursorPos
http://msdn.microsoft.com/ja-jp/library/cc364640.aspx
ScreenToClient
http://msdn.microsoft.com/ja-jp/library/cc410572.aspx
GetClientRect
http://msdn.microsoft.com/ja-jp/library/cc364604.aspx
ちなみに、、関数解説のページの一番下に
インポートライブラリ:User32.lib を使用
と書かれているので、user32.dll にこの関数があると分かります。
これ以外のDLL では、kernel32.dll , gdi32.dll , Shell32.dll を知って置けば十分です。


…で、まずは、ウィンドウサイズの取得から。

int hwnd =WindowHandle(Symbol(),0);
int ClinetRectValue[4];
GetClientRect(hwnd, ClinetRectValue);
int windowX = ClinetRectValue[2];
int windowY = ClinetRectValue[3];

これで、チャート描画部分のウィンドウサイズが分かります。サブウィンドウも含めたサイズが求まるので、メインウィンドウやサブウィンドウの高さを個別に求めたい場合は、こちらを参考にしてください。


次は、マウスの位置取得。

int MousePosition[2];
GetCursorPos(MousePosition);
ScreenToClient(hwnd, MousePosition);
int mouseX = MousePosition[0];
int mouseY = MousePosition[1];

GetCursorPos では、デスクトップ座標系でマウスの位置が求まるので、ScreenToClient でウィンドウ座標系での位置に変換しています。(正しくは、スクリーン座標とクライアント座標って言う....汗)



最後に、マウスの状態取得。
vKeyのコード一覧表には、

VK_LBUTTON (0x01) Left mouse button
VK_RBUTTON (0x02) Right mouse button

と書かれているので、左ボタンが押されているかどうかを知りたかったら 0x01、右ボタンだったら 0x02 という値を使って、 (GetAsyncKeyState(vKeyの値) & 0x8000) が 0 でないかを調べることで状態がわかります。
左ボタンが押されていたら赤、右ボタンが押されていたら黄色に設定するには以下のように書きます。

if( (GetAsyncKeyState(0x01) & 0x8000) != 0) MyColor = Red;
if( (GetAsyncKeyState(0x02) & 0x8000) != 0) MyColor = Yellow;


これらのコードを使ったサンプルをRTMouse_EA.mq4 に用意しました。
マウスを動かしたり、ウィンドウサイズを変えると数値が変化してゆくのが見られるだけのサンプルです。




ちなみに、Label Object の座標は、

int objX = ObjectGet(objname,OBJPROP_XDISTANCE);
int objY = ObjectGet(objname,OBJPROP_YDISTANCE);

で得られるので、今日の知識を組み合わせれば、「Label Object をクリックしたら、数字が変わる」を実現できるのですが、実用上はまだ不十分で致命的な欠陥があります。明日は、その続きを説明します。


重ね合せた複数のチャートで RTMouse_EA.mq4 を動かすと、欠陥に気づくかな・・・?