Diskussion zum Artikel "Erstellung eines Dashboards zur Anzeige von Daten in Indikatoren und EAs" - Seite 4

 
Denis Kirichenko #:
Move(int x, int y)

Irgendwo gibt es einen Fehler. Sie müssen die Koordinaten- und Größenwerte ausdrucken (oder im Debugger nachsehen, aber das funktioniert oft nicht).

Hier ist die Logik in den Kommentaren:

   //--- Wenn die Tafelhöhe nicht größer ist als die Fensterhöhe
   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;
     }
   //--- Wenn das Höhenfeld nicht innerhalb der Größe des Höhenfensters liegt
   else
     {
      //--- Halten Sie das Feld mit einem Abstand von 1 Pixel unter dem oberen Rand des Fensters
      if(y>1)
         y=1;
      //--- Verhindern Sie, dass das Panel mit einem Abstand von 1 Pixel unter den unteren Rand des Fensters fällt
      if(y<this.m_chart_h-h-2)
         y=this.m_chart_h-h-2;
     }
 
Denis Kirichenko #:
Wenn Sie versuchen, das Panel zu verschieben, nachdem Sie die Größe des Diagramms geändert haben, korrigiert es ständig die Koordinaten und lässt Sie das Panel-Fenster nicht frei bewegen...

Wahrscheinlich ist der Wert der Variable this.m_higher_wnd in der Methode Move() nicht relevant. Diese Werte werden im Eventhandler gesetzt:

//+------------------------------------------------------------------+
//| Ereignisbehandler|
//+------------------------------------------------------------------+
void CDashboard::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Wenn ein grafisches Objekt erstellt wird
   if(id==CHARTEVENT_OBJECT_CREATE)
     {
      this.BringToTop();
      ::ObjectSetInteger(this.m_chart_id,sparam,OBJPROP_SELECTED,true);
     }
//--- Wenn der Zeitplan geändert wird
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      //--- Ermitteln der Nummer des Unterfensters des Diagramms, wenn es nicht das Hauptfenster ist (die Nummer kann sich ändern, wenn das Fenster eines beliebigen Indikators gelöscht wird)
      if(this.m_wnd!=0)
         this.m_wnd=this.GetSubWindow();
      //--- Abrufen der neuen Diagrammabmessungen
      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);
      //--- Feststellen, ob die Größe des Feldes außerhalb des Diagrammfensters liegt
      this.m_higher_wnd=this.HigherWnd();
      this.m_wider_wnd=this.WiderWnd();
      //--- Wenn sich die Höhe der Karte geändert hat - passen Sie die vertikale Position des Bedienfelds an
      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);
        }
      //--- Wenn sich die Breite des Diagramms geändert hat - passen Sie die horizontale Position des Panels an
      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);
        }
     }

Es ist durchaus möglich, dass hier irgendwo die Oversize-Flags nicht korrekt gesetzt werden, wenn das Diagrammfenster erweitert wird.

Wenn Sie diese Zeilen

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

ganz am Anfang der Move()-Methode schreiben, um das Setzen der korrekten Werte bei jeder Mausbewegung zu erzwingen, wird der Fehler dann verschwinden? Wenn ja, bedeutet dies, dass der Fehler in den Werten dieser Variablen liegt, und Sie müssen im Event-Handler nachsehen, warum sie ihre Werte nicht erhalten, wenn das Fenster erweitert wird. Wenn dort alles normal ist, müssen Sie die Methode Move() ausdrucken, um den Fehler zu finden.

 

Der Fehler ist verschwunden. Ich habe diese Änderungen an der Methode CDashboard::OnChartEvent() vorgenommen:


//--- Wenn der Zeitplan geändert wird
   if(id == CHARTEVENT_CHART_CHANGE)
     {
      //--- Ermitteln der Nummer des Unterfensters des Diagramms, wenn es nicht das Hauptfenster ist (die Nummer kann sich ändern, wenn das Fenster eines beliebigen Indikators gelöscht wird)
      if(m_wnd != 0)
         m_wnd = GetSubWindow();
      //
      long value;
      // den Fehlerwert zurücksetzen
      ::ResetLastError();
      // den Wert der Eigenschaft ermitteln
      if(!::ChartGetInteger(m_chart_id, CHART_BRING_TO_TOP, m_wnd, value))
        {
         //--- Ausgabe der Fehlermeldung in das "Experten"-Protokoll.
         Print(__FUNCTION__ + ", Error Code = ", ::GetLastError());
         return;
        }
      // wenn das Diagramm nicht über allen anderen angezeigt wird - beenden
      if(value == 0)
         return;
      //--- Abrufen der neuen Diagrammabmessungen
      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);
      //--- Feststellen, ob die Größe des Feldes außerhalb des Diagrammfensters liegt
      //m_higher_wnd = HigherWnd();
      //m_wider_wnd = WiderWnd();
      //--- Wenn sich die Höhe der Karte geändert hat - passen Sie die vertikale Position des Bedienfelds an
      if(m_chart_h != h)
        {
         m_chart_h = h;
         m_higher_wnd = HigherWnd(); // hinzugefügt
         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);
        }
      //--- Wenn sich die Breite des Diagramms geändert hat - passen Sie die horizontale Position des Panels an
      if(m_chart_w != w)
        {
         m_chart_w = w; 
         m_wider_wnd = WiderWnd(); // hinzugefügt
         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);
        }
     }


Um die CDashboard:: Move()-Methode nicht ständig zu laden, habe ich die Überprüfung auf Übergrößen-Flags in den Blöcken hinzugefügt, in denen die Breite und Höhe des Diagrammfensters direkt geändert werden.


 
Denis Kirichenko #:

Der Fehler ist verschwunden. In der Methode CDashboard::OnChartEvent() habe ich diese Änderungen vorgenommen:

Um die Methode CDashboard:: Move() nicht ständig zu laden, habe ich die Überprüfung auf Übergrößen-Flags in den Blöcken hinzugefügt, in denen die Breite und Höhe des Diagrammfensters direkt geändert werden.

Danke dafür. Ich werde es einfügen.