チャートをダブルクリックした際の処理

おはようございます。
fx-onエンジニアの岩淵です。
最近チャートをダブルクリックした際に処理を実行したいなと思ったのですが、
そういえばダブルクリックなんてイベント見覚えないなとなりました。
CHARTEVENT_CLICKでシングルクリックは取得できるのですが、
CHARTEVENT_DOUBLE_CLICKみたいなのは無いみたいですね。
そこで試しにMQL4でダブルクリックの判定を実装してみました。
準備
まずグローバル変数を3つほど用意します。bool is_click = false; ulong click_time = 0; int dclick_msec = 500;is_clickは今回の肝になるフラッグです。 こいつの状態を操作してダブルクリックかシングルクリックかを判定します。 click_timeは1回目のクリックが発生した際の時間を保持するための変数です。 この変数の時間から一定時間経過したらis_clickを操作します。 dclick_msecは1回目のクリックと2回目のクリックの間の猶予時間をミリ秒単位で設定する変数です。 この変数の数値を弄ればダブルクリックの間隔が調整できるよう作っていきます。
OnChartEventの実装
1.イベントのidを確認してCHARTEVENT_CLICKの場合に処理を書いていきます。if(id == CHARTEVENT_CLICK){
// ここに処理を書いていきます
}
2.is_clickがfalseの場合はis_clickをtrueに変更してclick_timeに現在の時間を記録する。
if(id == CHARTEVENT_CLICK){
if(is_click ==false){
is_click = true;
click_time = GetMicrosecondCount();
}
}
3.is_clickがtrue(ダブルクリック時)の場合、is_clickをfalseに戻してダブルクリック時の処理を実行する。
if(id == CHARTEVENT_CLICK){
if(is_click ==false){
is_click = true;
click_time = GetMicrosecondCount();
}
else{
is_click = false;
// ダブルクリック時の処理
// .........
}
}
OnChartEvent側の実装はこれで完了です。
OnTimerの実装
OnChartEventの処理だけですとダブルクリックというよりは2回クリックで処理発生になってしまいます。 OnTimerを使って一定時間でis_clickをfalseに戻す処理を加えてダブルクリックっぽくしていきます。 1.OnInit内でEventSetMillisecondTimer、OnDeinit内でEventKillTimerを呼び出す。int OnInit(){
EventSetMillisecondTimer(100);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason){
EventKillTimer();
}
今回は短い間隔で判定をおこないたいので、EventSetTimerではなくEventSetMillisecondTimerを使用してミリ秒単位で指定しています。
サンプルのコードだと100ミリ秒なので0.1秒毎に処理が発生してくれます。
2.OnTimer内で時間を判定し、1回目のクリックから一定時間経過していればis_clickをfalseに戻す。
void OnTimer(){
if(is_click == true){
if(GetMicrosecondCount() > click_time + dclick_msec){
is_click = false;
}
}
}
以上で実装は完了です。
サンプル
ダブルクリック時に「hoge」とアラートするインジケーターのサンプルコードです。#property version "1.00"
#property strict
#property indicator_chart_window
bool is_click = false;
ulong click_time = 0;
int dclick_msec = 500;
int OnInit(){
Comment("ダブルクリックしてね");
EventSetMillisecondTimer(dclick_msec);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason){
Comment("");
EventKillTimer();
}
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam){
if(id == CHARTEVENT_CLICK){
if(is_click ==false){
is_click = true;
click_time = GetMicrosecondCount();
}
else{
is_click = false;
Alert("hoge");
}
}
}
void OnTimer(){
if(is_click == true){
if(GetMicrosecondCount() > click_time + dclick_msec){
is_click = false;
}
}
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
return(rates_total);
}
間隔が0.5秒なので気合入れてダブルクリックしてみてください。



