記事「指標やEAのデータを表示するダッシュボードの作成」についてのディスカッション - ページ 4

 
Denis Kirichenko #:
移動(int x, int y)

どこかにバグがある。座標とサイズの値をプリントする必要がある(デバッガで見ることもできるが、うまくいかないことが多い)。

以下はコメントにあるロジックです:

   //--- パネルの高さがウィンドウの高さサイズより大きくない場合
   if(!this.m_higher_wnd)
     {
      if(y+h>this.m_chart_h-2)
         y=this.m_chart_h-h-2;
      if(y<1)
         y=1;
     }
   //--- 高さパネルが高さウィンドウのサイズ内にない場合
   else
     {
      //--- パネルをウィンドウの上端より下に、1ピクセルの隙間を空けておく。
      if(y>1)
         y=1;
      //--- 1ピクセルのギャップで、パネルがウィンドウの下端より下に落ちないようにする。
      if(y<this.m_chart_h-h-2)
         y=this.m_chart_h-h-2;
     }
 
Denis Kirichenko #:
チャートサイズを変更した後にパネルを移動させようとすると、常に座標が修正され、パネルウィンドウを自由に移動させることができない...。

Move()メソッドではthis.m_higher_wnd変数の値は関係ない可能性が高い。これらの値はイベントハンドラで設定されます

//+------------------------------------------------------------------+
//| イベントハンドラ|
//+------------------------------------------------------------------+
void CDashboard::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- グラフィカル・オブジェクトが作成された場合
   if(id==CHARTEVENT_OBJECT_CREATE)
     {
      this.BringToTop();
      ::ObjectSetInteger(this.m_chart_id,sparam,OBJPROP_SELECTED,true);
     }
//--- スケジュールが変更された場合
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      //--- チャートのサブウィンドウがメインウィンドウでない場合、その番号を取得します。
      if(this.m_wnd!=0)
         this.m_wnd=this.GetSubWindow();
      //--- 新しいチャートの寸法を取得する。
      int w=(int)::ChartGetInteger(this.m_chart_id,CHART_WIDTH_IN_PIXELS,this.m_wnd);
      int h=(int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS,this.m_wnd);
      //--- パネル・サイズがチャート・ウィンドウの外側にあるかどうかを判断する。
      this.m_higher_wnd=this.HigherWnd();
      this.m_wider_wnd=this.WiderWnd();
      //--- チャートの高さが変わった場合、パネルの垂直位置を調整する。
      if(this.m_chart_h!=h)
        {
         this.m_chart_h=h;
         int y=this.m_y;
         if(this.m_y+this.m_h>h-1)
            y=h-this.m_h-1;
         if(y<1)
            y=1;
         this.Move(this.m_x,y);
        }
      //--- チャートの幅が変更された場合、パネルの水平位置を調整する。
      if(this.m_chart_w!=w)
        {
         this.m_chart_w=w;
         int x=this.m_x;
         if(this.m_x+this.m_w>w-1)
            x=w-this.m_w-1;
         if(x<1)
            x=1;
         this.Move(x,this.m_y);
        }
     }

ここのどこかで、チャート・ウィンドウが拡張されたときにオーバーサイズのフラグが正しく設定されていない可能性があります。

これらの行を

this.m_higher_wnd=this.HigherWnd();
this.m_wider_wnd=this.WiderWnd();

をMove()メソッドの一番最初に書いて、マウスが動くたびに正しい値が設定されるようにすれば、このバグは消えるでしょうか?もしそうなら、問題はこれらの変数の値にあり、なぜウィンドウが展開されたときに変数の値が取得されないのか、イベント・ハンドラを調べる必要があるということです。そこですべてが正常であれば、エラーを見つけるためにMove()メソッドを表示する必要があります。

 

バグが消えました。CDashboard::OnChartEvent()メソッドに以下の 変更を加えた:


//--- スケジュールが変更された場合
   if(id == CHARTEVENT_CHART_CHANGE)
     {
      //--- チャートのサブウィンドウがメインウィンドウでない場合、その番号を取得します。
      if(m_wnd != 0)
         m_wnd = GetSubWindow();
      //
      long value;
      // エラー値をリセットする
      ::ResetLastError();
      // プロパティの値を取得する
      if(!::ChartGetInteger(m_chart_id, CHART_BRING_TO_TOP, m_wnd, value))
        {
         //--- エラーメッセージを "Experts "ログに出力する。
         Print(__FUNCTION__ + ", Error Code = ", ::GetLastError());
         return;
        }
      // グラフが他のすべてのグラフの上に表示されていない場合、終了する。
      if(value == 0)
         return;
      //--- 新しいチャートの寸法を取得する。
      int w = (int)::ChartGetInteger(m_chart_id, CHART_WIDTH_IN_PIXELS, m_wnd);
      int h = (int)::ChartGetInteger(m_chart_id, CHART_HEIGHT_IN_PIXELS, m_wnd);
      //--- パネル・サイズがチャート・ウィンドウの外側にあるかどうかを判断する。
      //m_higher_wnd = HigherWnd();
      //m_wider_wnd = WiderWnd();
      //--- チャートの高さが変わった場合、パネルの垂直位置を調整する。
      if(m_chart_h != h)
        {
         m_chart_h = h;
         m_higher_wnd = HigherWnd(); // 追加
         int y = m_y;
         if(m_y + m_h > h - 1)
            y = h - m_h - 1;
         if(y < 1)
            y = 1;
         Move(m_x, y);
        }
      //--- チャートの幅が変更された場合、パネルの水平位置を調整する。
      if(m_chart_w != w)
        {
         m_chart_w = w; 
         m_wider_wnd = WiderWnd(); // 追加
         int x = m_x;
         if(m_x + m_w > w - 1)
            x = w - m_w - 1;
         if(x < 1)
            x = 1;
         Move(x, m_y);
        }
     }


CDashboard:: Move()メソッドを常に読み込まないようにするため、チャート・ウィンドウの幅と高さが直接変更されるブロックにサイズ超過フラグのチェックを追加した。


 
Denis Kirichenko #:

バグが消えました。CDashboard::OnChartEvent()メソッドの中で、私は以下の 変更を行った:

CDashboard:: Move()メソッドを常に読み込まないようにするため、チャート・ウィンドウの幅と高さが直接変更されるブロックにサイズ超過フラグのチェックを追加した。

ありがとう。それを入れておきます。