この記事では、ENUM_CHART_EVENT列挙型における、識別子の1つであるCHARTEVENT_MOUSE_MOVE挙動が確認できるサンプルコードを、小分けにしていきながらわかりやすく解説していきたいと思います
OnInit関数部分
//+------------------------------------------------------------------+
void OnInit()
{
//--- CHART_EVENT_MOUSE_MOVE メッセージを有効にする
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1);
//--- チャートのコンテキストメニューを無効にします(右側)
ChartSetInteger(0,CHART_CONTEXT_MENU,0);
//--- 十字線を無効にします(中央のボタンで)
ChartSetInteger(0,CHART_CROSSHAIR_TOOL,0);
//--- チャートプロパティを強制的に更新して、イベント処理の準備を整える
ChartRedraw();
}
解説
このセクションは、エキスパートアドバイザー(EA)が初期化される際に実行されるOnInit関数の部分です。OnInit関数はEAの初期設定を行うための関数です以下に各処理内容と文法要素について解説します。
CHART_EVENT_MOUSE_MOVEメッセージを有効にする
この行は、マウスの移動イベントを有効にするための設定です。ChartSetInteger関数を使用して、現在のチャート(0)でCHARTEVENT_MOUSE_MOVEイベントを有効にします。これにより、マウスがチャート上で移動したときにOnChartEvent関数でそのイベントを処理できるようになります。
チャートのコンテキストメニューを無効にする
この行は、チャートのコンテキストメニュー(右クリックメニュー)を無効にする設定です。CHART_CONTEXT_MENUを0に設定することで、右クリックメニューが表示されなくなります。
十字線を無効にする
この行は、チャート上で中央ボタンを使用した十字線ツールを無効にする設定です。CHART_CROSSHAIR_TOOLを0に設定することで、中央ボタンを押しても十字線ツールが表示されなくなります。
チャートプロパティの強制更新
この行は、チャートのプロパティを強制的に更新するための設定です。ChartRedraw関数を使用して、チャートの再描画を強制します。これにより、設定した変更が即座に反映され、イベント処理の準備が整います。
以上の処理により、OnInit関数はEAの初期設定を行い、マウスの移動イベントやその他の設定を適切に行うことで、EAの動作環境を整えます。
MouseState関数の定義部分
//+------------------------------------------------------------------+
//| マウスの状態 |
//+------------------------------------------------------------------+
string MouseState(uint state)
{
string res;
res+="\nML: " +(((state & 1) == 1) ? "DN" : "UP"); // 左ボタン
res+="\nMR: " +(((state & 2) == 2) ? "DN" : "UP"); // 右ボタン
res+="\nMM: " +(((state & 16) == 16) ? "DN" : "UP"); // 中央ボタン
res+="\nMX: " +(((state & 32) == 32) ? "DN" : "UP"); // 追加ボタン1
res+="\nMY: " +(((state & 64) == 64) ? "DN" : "UP"); // 追加ボタン2
res+="\nSHIFT: "+(((state & 4) == 4) ? "DN" : "UP"); // shiftキー
res+="\nCTRL: " +(((state & 8) == 8) ? "DN" : "UP"); // controlキー
return(res);
}
解説
このセクションは、マウスの状態を表すMouseState関数の定義部分です。MouseState関数は、マウスボタンやキーボードキーの状態を示す文字列を生成します。以下に各処理内容と文法要素について解説します。
ビット演算子について
ビット演算子(&)は、2つの数値の各ビットを論理積(AND)します。例えば、(state & 1)は、stateの1ビット目と1を比較し、両方が1ならば結果も1になります。これにより、特定のビットがセットされているかどうかを確認することができます。
関係演算子について
関係演算子(==)は、2つの値が等しいかどうかを比較します。例えば、((state & 1) == 1)は、「stateの1ビット目が1かどうか」を確認します。このようにして、マウスボタンやキーボードキーが押されているかどうかを判断します。
三項演算子について
三項演算子(?:)は、条件式によって異なる値を返すための演算子です。構文は 条件式 ? 式1 : 式2
で、条件式が真の場合は式1を、偽の場合は式2を返します。例えば、((state & 1) == 1) ? “DN” : “UP” は、「stateの1ビット目が1ならば”DN”、そうでなければ”UP”」を返します。このようにして、各ボタンやキーの状態を示す文字列を生成します。
各ボタンとキーの状態
state & 1
: 左ボタンの状態を確認します。state の値と「1のビット単位論理積」を取った結果(0001)が1と等しい”DN”(押されている)、そうでなければ”UP”(押されていない)。state & 2
: 右ボタンの状態を確認します。state の値と「2のビット単位論理積」を取った結果が2と等しいなら”DN”(押されている)、そうでなければ”UP”(押されていない)。state & 16
: 中央ボタンの状態を確認します。state の値と「16のビット単位論理積」を取った結果が2と等しいなら”DN”(押されている)、そうでなければ”UP”(押されていない)。state & 32
: 追加ボタン1の状態を確認します。state の値と「32のビット単位論理積」を取った結果が32と等しいなら”DN”(押されている)、そうでなければ”UP”(押されていない)。state & 64
: 追加ボタン2の状態を確認します。state の値と「64のビット単位論理積」を取った結果が64と等しいなら”DN”(押されている)、そうでなければ”UP”(押されていない)。state & 4
: Shiftキーの状態を確認します。state の値と「4のビット単位論理積」を取った結果が4と等しいなら”DN”(押されている)、そうでなければ”UP”(押されていない)。state & 8
: Ctrlキーの状態を確認します。state の値と「8のビット単位論理積」を取った結果が8と等しいなら”DN”(押されている)、そうでなければ”UP”(押されていない)。
以上の処理により、MouseState関数はマウスボタンやキーボードキーの現在の状態を示す文字列を生成します。
OnChartEvent関数部分
//+------------------------------------------------------------------+
//| ChartEvent 関数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
if(id==CHARTEVENT_MOUSE_MOVE)
Comment("POINT: ",(int)lparam,",",(int)dparam,"\n",MouseState((uint)sparam));
}
解説
このセクションは、チャート上のイベントを処理するためのOnChartEvent関数の部分です。OnChartEvent関数は、さまざまなチャートイベントに応答するために使用されます。以下に各処理内容と文法要素について解説します。
CHARTEVENT_MOUSE_MOVEイベントの処理
if(id==CHARTEVENT_MOUSE_MOVE)
この行は、イベントIDがCHARTEVENT_MOUSE_MOVEであるかどうかを確認しています。CHARTEVENT_MOUSE_MOVEは、マウスがチャート上で移動したときに発生するイベントです。
Comment関数の使用
Comment("POINT: ",(int)lparam,",",(int)dparam,"\n",MouseState((uint)sparam));
この行は、チャート上のコメント領域にマウスの位置情報とマウスボタンの状態を表示するためのコードです。
- Comment関数は、チャート上にテキストを表示するための関数です。
"POINT: "
は表示する文字列の一部で、マウスの位置情報を示します。(int)lparam
は、マウスのX座標を整数型にタイプキャストしています。","
は、X座標とY座標を区切るためのカンマです。(int)dparam
は、マウスのY座標を整数型にタイプキャストしています。"\n"
は、改行文字で次の行に移動します。MouseState((uint)sparam)
は、マウスの状態を示す文字列を取得します。
タイプキャストについて
タイプキャストは、あるデータ型の値を別のデータ型に変換する操作です。このコードでは、次のように使用されています。
(int)lparam
は、lparamの値を整数型に変換します。(int)dparam
は、dparamの値を整数型に変換します。(uint)sparam
は、sparamの値を符号なし整数型に変換します。
タイプキャストを使用することで、異なるデータ型の値を適切な形式で処理し、正確な情報を表示することができます。
改行文字(\n)について
改行文字(\n)は、テキスト内で改行を示す特殊文字です。このコードでは、表示されるテキストを次の行に移動するために使用されています。"\n"
をテキスト内ChartSetInteger関数に挿入することで、改行を実現します。
以上の処理により、OnChartEvent関数はマウスの移動イベントが発生した際に、マウスの位置情報とボタンの状態をチャート上に表示します。これにより、リアルタイムでマウスの動きを視覚的に確認することができます。
サンプルコードの全体記述
サンプルコードの全体記述は以下の通りです。
//+------------------------------------------------------------------+
//| エキスパート初期化に使用される関数 |
//+------------------------------------------------------------------+
void OnInit()
{
//--- CHART_EVENT_MOUSE_MOVE メッセージを有効にする
ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, 1);
//--- チャートのコンテキストメニューを無効にします(右側)
ChartSetInteger(0, CHART_CONTEXT_MENU, 0);
//--- 十字線を無効にします(中央のボタンで)
ChartSetInteger(0, CHART_CROSSHAIR_TOOL, 0);
//--- チャートプロパティを強制的に更新して、イベント処理の準備を整える
ChartRedraw();
}
//+------------------------------------------------------------------+
//| マウスの状態 |
//+------------------------------------------------------------------+
string MouseState(uint state)
{
string res;
res += "\nML: " +(((state & 1) == 1) ? "DN" : "UP"); // 左ボタン
res += "\nMR: " +(((state & 2) == 2) ? "DN" : "UP"); // 右ボタン
res += "\nMM: " +(((state & 16) == 16) ? "DN" : "UP"); // 中央ボタン
res += "\nMX: " +(((state & 32) == 32) ? "DN" : "UP"); // 追加ボタン1
res += "\nMY: " +(((state & 64) == 64) ? "DN" : "UP"); // 追加ボタン2
res += "\nSHIFT: "+(((state & 4) == 4) ? "DN" : "UP"); // shiftキー
res += "\nCTRL: " +(((state & 8) == 8) ? "DN" : "UP"); // controlキー
return(res);
}
//+------------------------------------------------------------------+
//| ChartEvent 関数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if(id == CHARTEVENT_MOUSE_MOVE)
Comment("POINT: ", (int)lparam, ",", (int)dparam, "\n", MouseState((uint)sparam));
}