ENUM_CHART_EVENT列挙型における、識別子の1つであるCHARTEVENT_MOUSE_WHEELの挙動が確認できるサンプルコードを、小分けにしていきながらわかりやすく解説していきたいと思います。
OnInit関数部分
//+------------------------------------------------------------------+
//| エキスパート初期化関数 |
//+------------------------------------------------------------------+
init OnInit()
{
//--- マウスホイールスクロールメッセージの有効化
ChartSetInteger(0, CHART_EVENT_MOUSE_WHEEL, 1);
//--- チャートプロパティを強制的に更新して、イベント処理の準備を整える
ChartRedraw();
//---
return(INIT_SUCCEEDED);
}
解説
このセクションは、エキスパートアドバイザー(EA)が初期化される際に実行されるOnInit関数の部分です。OnInit関数はEAの初期設定を行うための関数です。以下に各処理内容と文法要素について解説します。
マウスホイールスクロールメッセージの有効化
この行は、マウスホイールのスクロールイベントを有効にするための設定です。
ChartSetInteger関数を使用して、現在のチャートでマウスホイールイベントを有効にします。この設定により、マウスホイールのスクロールイベントが発生した際にOnChartEvent関数で処理されるようになります。
チャートプロパティの強制更新
次に、ChartRedraw関数を使用してチャートのプロパティを強制的に更新します。これにより、設定したマウスホイールイベントが正しく反映されるようになります。チャートの再描画を行うことで、変更が適用され、イベント処理の準備が整います。
初期化成功の返り値
最後に、INIT_SUCCEEDEDを返すことで、OnInit関数の終了と初期化が成功したことを示します。この返り値により、EAは初期設定が正しく完了したことを認識します。
以上の処理により、OnInit関数はEAの初期設定を行い、マウスホイールイベントの処理が可能な状態にします。
ChartEvent関数部分その1
//+------------------------------------------------------------------+
//| ChartEvent関数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if(id == CHARTEVENT_MOUSE_WHEEL)
{
//--- このイベントのマウスボタンとホイールの状態を考慮する
int flg_keys = (int)(lparam >> 32); // CtrlキーとShiftキー、およびマウスボタンの状態のフラグ
int x_cursor = (int)(short)lparam; // マウスホイールイベントが発生したX座標
int y_cursor = (int)(short)(lparam >> 16); // マウスホイールイベントが発生したY座標
int delta = (int)dparam; // +120または-120に達したときにトリガーされるマウススクロールの合計値
}
}
解説
このセクションは、チャート上のイベントを処理するためのOnChartEvent関数の部分です。OnChartEvent関数は、さまざまなチャートイベントに応答するために使用されます。以下に各処理内容と文法要素について解説します。
CHARTEVENT_MOUSE_WHEELイベントの処理
この部分は、マウスホイールのスクロールイベントを処理するためのコードです。idがCHARTEVENT_MOUSE_WHEELである場合に、このブロック内の処理が実行されます。
マウスボタンとホイールの状態を考慮する
次に、lparamを使用してマウスボタンとホイールの状態を取得します。
- flg_keysは、lparamを右に32ビットシフトすることで、CtrlキーとShiftキー、およびマウスボタンの状態を示すフラグを取得します。
- x_cursorは、lparamの下位16ビットからマウスホイールイベントが発生したX座標を取得します。
- y_cursorは、lparamの次の16ビットからマウスホイールイベントが発生したY座標を取得します。
- deltaは、dparamからマウススクロールの合計値を取得します。+120または-120に達したときにトリガーされる値です。
>> 演算子について
右シフト演算子(>>)は、数値を指定されたビット数だけ右にシフトします。右シフトによって、数値の各ビットは右に移動し、左側には0が挿入されます。この操作により、高位ビットから必要な情報を取り出すことができます。例えば、lparam >> 32 では、lparamの上位32ビットを取得します。
タイプキャストについて
タイプキャストは、あるデータ型の値を別のデータ型に変換する操作です。例えば、(int)(short)lparam では、まずlparamを16ビットのShort型に変換し、その後int型に変換しています。これにより、必要なビット範囲の値を正確に取得できます。このように、データの形式を変換し、適切な処理を行うことができます。
なぜ2回タイプキャストを行うのか
lparamを(short)で一度16ビットに変換するのは、lparamの下位16ビットの値を取得するためです。その後、(int)で再度int型に変換するのは、取得した16ビットの値を整数として使用するためです。例えば、lparamには多くの情報が詰め込まれており、16ビットの範囲だけを取り出して処理する必要がある場合、まず16ビットのShort型にタイプキャストし、その後int型にタイプキャストして使用します。この操作により、特定のビット範囲のデータを正確に取得し、処理することができます。
このコードブロックにより、CHARTEVENT_MOUSE_WHEELイベントが発生した際の詳細な状態を取得し、それに基づいて適切な処理を行うことができます。
ChartEvent関数部分その2
//--- フラグの処理
string str_keys="";
if((flg_keys&0x0001)!=0) str_keys+="LMOUSE ";
if((flg_keys&0x0002)!=0) str_keys+="RMOUSE ";
if((flg_keys&0x0004)!=0) str_keys+="SHIFT ";
if((flg_keys&0x0008)!=0) str_keys+="CTRL ";
if((flg_keys&0x0010)!=0) str_keys+="MMOUSE ";
if((flg_keys&0x0020)!=0) str_keys+="X1MOUSE ";
if((flg_keys&0x0040)!=0) str_keys+="X2MOUSE ";
解説
このセクションは、OnChartEvent関数内でマウスホイールイベントが発生した際のマウスボタンやキーボードの状態を処理する部分です。以下に各処理内容と文法要素について解説します。
フラグの処理
この部分では、flg_keys変数に格納されているフラグをチェックして、各マウスボタンやキーボードキーが押されているかどうかを判定し、その結果をstr_keys文字列に追加しています。
16進数表記
コード内では16進数が使われています。16進数は、0から9までの数字とAからFまでの文字を使って数値を表現する方法です。例えば、0x0001は10進数の1、0x0002は10進数の2、0x0004は10進数の4です。このように、各ビットの位置を簡潔に表現できます。
!=演算子
!=演算子は、「等しくない」という意味を持つ比較演算子です。例えば、(flg_keys & 0x0001) != 0 は、「flg_keysの1ビット目が0ではない(つまり、1である)」という条件をチェックしています。これは、特定のキーやボタンが押されているかどうかを確認するために使用されます。
+=演算子について
+=演算子は、代入演算子の一種で、変数に値を追加するために使用されます。例えば、str_keys += “LMOUSE “は、str_keysに”LMOUSE “を追加するという意味です。この演算子を使用することで、元の変数の値に新しい値を追加して更新することができます。具体的には、次のような処理を行っています:
- str_keys += “LMOUSE “は、str_keysの現在の値に”LMOUSE “を追加します。
- 同様に、str_keys += “RMOUSE “やstr_keys += “SHIFT “なども、対応する文字列をstr_keysに追加します。
ビット演算
&演算子はビット演算の一種で、2つの数値の各ビットを論理積(AND)します。例えば、(flg_keys & 0x0001)は、flg_keysの1ビット目と0x0001の1ビット目を比較し、両方が1ならば結果も1になります。これにより、特定のビットがセットされているかどうかを確認することができます。
このようにして、各マウスボタンやキーボードキーの状態をチェックし、押されているキーやボタンに対応する文字列をstr_keysに追加しています。これにより、イベントの詳細な状態を把握し、適切な処理を行うことが可能になります。
ChartEvent関数部分その3
if(str_keys!="")
str_keys=", keys='"+StringSubstr(str_keys,0,StringLen(str_keys)-1) + "'";
PrintFormat("%s: X=%d, Y=%d, delta=%d%s",EnumToString(CHARTEVENT_MOUSE_WHEEL),x_cursor,y_cursor,delta,str_keys);
}
解説
このセクションは、OnChartEvent関数内でマウスホイールイベントが発生した際の処理の最後の部分です。ここでは、マウスのボタンやキーボードキーの状態を含めた情報を整形し、エキスパートログに出力するための処理を行っています。
str_keysの整形
if(str_keys!="")
str_keys=", keys='"+StringSubstr(str_keys,0,StringLen(str_keys)-1) + "'";
この部分では、str_keysが空でない場合に、その内容を整形して出力用の文字列を作成しています。
- StringSubstr関数は、文字列を部分抽出する関数です。この場合、str_keysの先頭から末尾の1文字を除いた部分文字列を抽出しています。
- StringLen関数は、文字列の長さを返す関数です。ここではstr_keysの長さを取得しています。
+
演算子は文字列の連結に使用されます。この部分では、”keys='”とstr_keysの一部を連結しています。
これにより、str_keysの末尾に余分なスペースが含まれないようにしつつ、”keys=”というラベルを追加しています。
PrintFormat関数による出力
PrintFormat("%s: X=%d, Y=%d, delta=%d%s", EnumToString(CHARTEVENT_MOUSE_WHEEL), x_cursor, y_cursor, delta, str_keys);
この部分では、イベントの詳細をエキスパートログに出力しています。
PrintFormat関数の役割
PrintFormat関数は、書式化された文字列をエキスパートログに出力するための関数です。指定されたフォーマットに従って、変数の値を文字列に変換し、ログに記録します。
EnumToString関数の役割
EnumToString関数は、列挙型の値を文字列に変換する関数です。ここでは、CHARTEVENT_MOUSE_WHEELという列挙型の値を対応する文字列に変換しています。
フォーマット指定子と変数の紐付け
PrintFormat関数内のフォーマット指定子は以下のような対応関係になっています。
%s
:文字列に対応します。ここではEnumToString(CHARTEVENT_MOUSE_WHEELの結果が該当します。CHARTEVENT_MOUSE_WHEELLのイベント名を文字列に変換しています。%d
:整数に対応します。この指定子は3つあり、それぞれ次の変数に対応しています。x_cursor
:マウスホイールイベントが発生したX座標y_cursor
:マウスホイールイベントが発生したY座標delta
:マウススクロールの合計値(+120または-120に達したときにトリガーされる)%s
:文字列に対応します。ここではstr_keysの内容が該当します。マウスボタンやキーボードキーの状態を示す文字列です。
この行では、CHARTEVENT_MOUSE_WHEELのイベント名、マウスのX座標、Y座標、スクロール量、キーの状態を含む文字列を整形してエキスパートログに出力します。これにより、マウスホイールイベントが発生した際の詳細な情報をログに記録し、デバッグやモニタリングに役立てることができます。
サンプルコードの全体記述
サンプルコードの全体記述は以下の通りです。
//+------------------------------------------------------------------+
//| エキスパート初期化関数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- マウスホイールスクロールメッセージの有効化
ChartSetInteger(0, CHART_EVENT_MOUSE_WHEEL, 1);
//--- チャートプロパティを強制的に更新して、イベント処理の準備を整える
ChartRedraw();
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| ChartEvent関数 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if(id == CHARTEVENT_MOUSE_WHEEL)
{
//--- このイベントのマウスボタンとホイールの状態を考慮する
int flg_keys = (int)(lparam >> 32); // CtrlキーとShiftキー、およびマウスボタンの状態のフラグ
int x_cursor = (int)(short)lparam; // マウスホイールイベントが発生したX座標
int y_cursor = (int)(short)(lparam >> 16); // マウスホイールイベントが発生したY座標
int delta = (int)dparam; // +120または-120に達したときにトリガーされるマウススクロールの合計値
//--- フラグの処理
string str_keys = "";
if((flg_keys & 0x0001) != 0) str_keys += "LMOUSE "; // マウスの左ボタンが押されている場合
if((flg_keys & 0x0002) != 0) str_keys += "RMOUSE "; // マウスの右ボタンが押されている場合
if((flg_keys & 0x0004) != 0) str_keys += "SHIFT "; // SHIFTキーが押されている場合
if((flg_keys & 0x0008) != 0) str_keys += "CTRL "; // CTRLキーが押されている場合
if((flg_keys & 0x0010) != 0) str_keys += "MMOUSE "; // マウスの中央ボタンが押されている場合
if((flg_keys & 0x0020) != 0) str_keys += "X1MOUSE "; // マウスの追加ボタン1が押されている場合
if((flg_keys & 0x0040) != 0) str_keys += "X2MOUSE "; // マウスの追加ボタン2が押されている場合
//--- str_keysが空でない場合、末尾のスペースを除去し、keys=を追加
if(str_keys != "")
str_keys = ", keys='" + StringSubstr(str_keys, 0, StringLen(str_keys) - 1) + "'";
//--- イベントの詳細をエキスパートログに出力
PrintFormat("%s: X=%d, Y=%d, delta=%d%s", EnumToString(CHARTEVENT_MOUSE_WHEEL), x_cursor, y_cursor, delta, str_keys);
}
}
コメント