記事"グラフィカルインタフェースX: 標準チャートコントロール(ビルド4)"についてのディスカッション

 

新しい記事 グラフィカルインタフェースX: 標準チャートコントロール(ビルド4) はパブリッシュされました:

今回は、標準のチャートコントロールについて考えていきます。これによって水平スクロールを同期させる機能を持つサブチャートの配列の作成が可能になります。また、引き続き、ライブラリのコードを最適化してCPU負荷を軽減します。

サブチャートをナビゲートするのに、端末によってメインチャートに実装されているのと別の方法が必要であるとします。MetaTrader端末で«Space»または«Enter»キーが押されると、チャートの左下に編集ボックスが表示されます(下記のスクリーンショット参照)。これはコマンドラインの一種で、チャート上のその日付にジャンプするために日付を入力することができます。このコマンドラインを使用して、チャートの銘柄と時間枠を変更することもできます。  

 図1 チャートの左隅のコマンドライン

図1 チャートの左隅のコマンドライン


作者: Anatoli Kazharski

 
Если к этому прибавить ещё перемещение курсора мыши в области графика и активное взаимодействие с графическим интерфейсом MQL-приложения, то потребление вырастет ещё больше. Задача состоит в том, чтобы ограничить работу таймера движка библиотеки и исключить перерисовку графика по приходу события перемещения курсора мыши.

OBJ_CHARTの スクロールに、なぜタイマーを使うのですか?また、インターフェースとのインタラクションについても同様の疑問があります。マウス・イベントで十分だと思います。

 
fxsaber:

OBJ_CHARTの スクロールに、なぜタイマーを使うのですか?また、インターフェイスとのインタラクションについても同様の疑問があります。結局のところ、マウスイベントで常に十分だと思われます。

あなたが引用したのはOBJ_CHARTの ことではなく、ライブラリエンジン全体のタイマーの ことです。そのため、この問題の解決策は、メイントピックの追加として「ライブラリエンジンのタイマーとイベントハンドラの最適化」という記事の別のセクションに置かれました。

タイマーは、マウスオーバー時にコントロールの色を変更したり、リスト、テーブル、カレンダー、入力フィールドの値のスクロールを加速するために使用されます。

//---

追伸: また、OBJ_CHARTの スクロールは、マウス・カーソルの移動イベントCHARTEVENT_MOUSE_MOVEによって 実行されます。以下のリストは、"Standard Chart "要素(クラスCStandardChart)のイベントのハンドラ(短縮版)のコードです:

//+------------------------------------------------------------------+
//| イベント処理|
//+------------------------------------------------------------------+
void CStandardChart::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- カーソル移動イベントの処理
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      //--- アイテムが非表示の場合は終了する
      if(!CElement::IsVisible())
         return;
      //--- サブウィンドウのサイズ変更モードの場合は終了する。
      if(CheckDragBorderWindowMode())
         return;
      //--- サブウィンドウの番号が一致しない場合は終了する。
      if(CElement::m_subwin!=CElement::m_mouse.SubWindowNumber())
         return;
      //--- フォームが他の要素によってブロックされたら終了する。
      if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
         return;
      //--- フォーカスチェック
      CElement::MouseFocus(m_mouse.X()>X() && m_mouse.X()<X2() && m_mouse.Y()>Y() && m_mouse.Y()<Y2());
      //--- フォーカスがある場合
      if(CElement::MouseFocus())
         //--- グラフの水平スクロール
         HorizontalScroll();
      //--- フォーカスがなく、マウスの左ボタンが離された場合
      else if(!m_mouse.LeftButtonState())
        {
         //--- 水平スクロールポインタを隠す
         m_x_scroll.Hide();
         //--- フォームのロックを解除する
         if(m_wnd.IdActivatedElement()==CElement::Id())
           {
            m_wnd.IsLocked(false);
            m_wnd.IdActivatedElement(WRONG_VALUE);
           }
        }
      //---
      return;
     }
//...
  }
 
Anatoli Kazharski:

マウスオーバー時のコントロール・エレメントのカラー・チェンジをタイマー・ベースでアレンジ

なぜマウスが使えないのか?
 
fxsaber:
なぜここではマウスが使えないのか?

スムーズな色の変化があるからです(ステップ数はユーザーが設定します)。

これはリストのスクロールにも当てはまります。SBで実装されている方法をそのまま使うと、ギザギザの(不均一な)スクロールになってしまいます。

 
Anatoli Kazharski:

なぜなら、スムーズな色の変化が提供されるからです(ステップ数はユーザーが設定します)。

これはリストのスクロールにも当てはまります。SBで実装されているような方法を使用すると、ギザギザ(不均一)なスクロールになります。

なぜOBJ_CHARTには ギザギザのスクロールがないのですか?
 
fxsaber:
OBJ_CHARTの ティアリングが出ないのはなぜですか?

どのような場合に(記事のテストExpert Advisorと相対的に)?

  1. カレンダーをスクロールした場合?
  2. アイテムイベントハンドラ(CStandardChart)のCHARTEVENT_MOUSE_MOVE イベントによる手動スクロールの場合

もし前者であれば、チャートのスクロールは、カレンダーのスクロールと同じように時間指定されます。つまり、カレンダーの日付変更イベント(ON_CHANGE_DATE)の発生は、16 ミリ秒間隔でタイミングがとられます。

秒の場合、シフトは計算され、常に1 小節に等しいとは限りません。そのため、CHARTEVENT_MOUSE_MOVE イベントによる手動スクロールがスムーズなだけと思われます。

 
Anatoli Kazharski:

2番目の場合、シフトは計算され、常に1 小節に等しいとは限りません。つまり、CHARTEVENT_MOUSE_MOVE イベントによる手動スクロールがスムーズなよう です。

ありがとう!

 
記事をありがとう。楽しみにしていたよ。失望はしていない)
 

アナトリー、エラーの原因を教えてください。

2016.10.19 03:09:04.993 TestTable (EURUSD,H1)   invalid pointer access in 'Scrolls.mqh' (698,10)

このアップデートの前はすべてうまくいっていました。今、CTable テーブルを構築するときに、このエラーがポップアップします。

どこが間違っているのか教えてください - すべての行をすでに印刷しました - インターフェイスは構築されていますが、どこかでつまずいた後、....エラー。

アーカイブ内の例のファイル。

ファイル:
TestTable.zip  734 kb
 

見つけた。

MQL4Expertsの例を取ってみよう。

上の例から:

列数と可視列数を同じにして 、コンパイルして、実行して、エラーになる。

//+------------------------------------------------------------------+
//|| テーブルの作成|
//+------------------------------------------------------------------+
bool CProgram::CreateTable(void)
  {
//#define COLUMNS1_TOTAL (100)
//#define ROWS1_TOTAL (1000)
#define COLUMNS1_TOTAL (6)
#define ROWS1_TOTAL    (1000)
//--- フォームへのポインタを保存する
   m_table.WindowPointer(m_window1);
//--- 座標
   int x=m_window1.X()+TABLE1_GAP_X;
   int y=m_window1.Y()+TABLE1_GAP_Y;
//--- 見える列と行の数
   int visible_columns_total =6;
   int visible_rows_total    =15;
//--- 作成前にプロパティを設定する
   m_table.XSize(600);
   m_table.RowYSize(20);
   m_table.FixFirstRow(true);
   m_table.FixFirstColumn(true);
   m_table.LightsHover(true);
   m_table.SelectableRow(true);
   m_table.TextAlign(ALIGN_CENTER);
   m_table.HeadersColor(C'255,244,213');
   m_table.HeadersTextColor(clrBlack);
   m_table.CellColorHover(clrGold);
   m_table.TableSize(COLUMNS1_TOTAL,ROWS1_TOTAL);
   m_table.VisibleTableSize(visible_columns_total,visible_rows_total);
//--- コントロールの作成
   if(!m_table.CreateTable(m_chart_id,m_subwin,x,y))
      return(false);
//--- テーブルを埋めてみよう:
// 最初のセルは空
   m_table.SetValue(0,0,"-");
//--- 列の見出し
   for(int c=1; c<COLUMNS1_TOTAL; c++)
     {
      for(int r=0; r<1; r++)
         m_table.SetValue(c,r,"SYMBOL "+string(c));
     }
//--- 行の見出し、テキストの整列方法 - 右寄せ
   for(int c=0; c<1; c++)
     {
      for(int r=1; r<ROWS1_TOTAL; r++)
        {
         m_table.SetValue(c,r,"PARAMETER "+string(r));
         m_table.TextAlign(c,r,ALIGN_RIGHT);
        }
     }
//--- データと表のフォーマット(背景色とセルの色)
   for(int c=1; c<COLUMNS1_TOTAL; c++)
     {
      for(int r=1; r<ROWS1_TOTAL; r++)
        {
         m_table.SetValue(c,r,string(c)+":"+string(r));
         m_table.TextColor(c,r,(c%2==0)? clrRed : clrRoyalBlue);
         m_table.CellColor(c,r,(r%2==0)? clrWhiteSmoke : clrWhite);
        }
     }
//--- 変更を示すためにテーブルを更新する
   m_table.UpdateTable();
//--- オブジェクト・グループの共通配列にオブジェクトを追加する。
   CWndContainer::AddToElementsArray(0,m_table);
   return(true);
  }
//+------------------------------------------------------------------+
実は、行数と可視行数を同じにしても同じエラーが出る。