Diskussion zum Artikel "Grafische Interfaces X: Das Standard Chart-Steuerelement (Build 4)" - Seite 2

 
Artyom Trishkin:

Anatoly, sagen Sie mir, was die Ursache für diesen Fehler ist.

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

Vor diesem Update hat alles gut funktioniert. Jetzt beim Aufbau der CTable Tabelle erscheint dieser Fehler.

Bitte sagen Sie mir, wo es falsch ist - ich habe schon jede Zeile gedruckt - die Schnittstelle ist gebaut, aber nach irgendwo stolpert, und .... Fehler.

Datei mit einem Beispiel im Archiv.

Ich habe vergessen, eine Korrektur zu machen, wie es früher in der CCanvasTable Klasse gemacht wurde.

In der CTable-Klasse müssen Sie die aktuellen Versionen der CreateScrollV()- und CreateScrollH()-Methoden durch die im folgenden Listing gezeigten ersetzen:

//+------------------------------------------------------------------+
//|| Erzeugt eine vertikale Bildlaufleiste
//+------------------------------------------------------------------+
bool CTable::CreateScrollV(void)
  {
//--- Speichern des Formularzeigers
   m_scrollv.WindowPointer(m_wnd);
//--- Koordinaten
   int x=(m_anchor_right_window_side)? m_x-m_x_size+m_scrollv.ScrollWidth() : CElement::X2()-m_scrollv.ScrollWidth();
   int y=CElement::Y();
//--- Abmessungen festlegen
   m_scrollv.Id(CElement::Id());
   m_scrollv.IsDropdown(CElement::IsDropdown());
   m_scrollv.XSize(m_scrollv.ScrollWidth());
   m_scrollv.YSize((m_columns_total>m_visible_columns_total)? m_y_size-m_scrollv.ScrollWidth()+1 : m_y_size);
   m_scrollv.AnchorRightWindowSide(m_anchor_right_window_side);
   m_scrollv.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Erstellen einer Bildlaufleiste
   if(!m_scrollv.CreateScroll(m_chart_id,m_subwin,x,y,m_rows_total,m_visible_rows_total))
      return(false);
//--- Ausblenden, wenn jetzt nicht benötigt
   if(m_rows_total<=m_visible_rows_total)
      m_scrollv.Hide();
//---
   return(true);
  }
//+------------------------------------------------------------------+
//|| Erzeugt eine horizontale Bildlaufleiste
//+------------------------------------------------------------------+
bool CTable::CreateScrollH(void)
  {
//--- Speichern des Formularzeigers
   m_scrollh.WindowPointer(m_wnd);
//--- Koordinaten
   int x=CElement::X();
   int y=(m_anchor_bottom_window_side)? m_y-m_area.Y_Size()+m_scrollh.ScrollWidth() : CElement::Y2()-m_scrollh.ScrollWidth();
//--- Abmessungen festlegen
   m_scrollh.Id(CElement::Id());
   m_scrollh.IsDropdown(CElement::IsDropdown());
   m_scrollh.XSize((m_rows_total>m_visible_rows_total)? m_area.XSize()-m_scrollh.ScrollWidth()+1 : m_area.XSize());
   m_scrollh.YSize(m_scrollh.ScrollWidth());
   m_scrollh.AnchorRightWindowSide(m_anchor_right_window_side);
   m_scrollh.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Erstellen einer Bildlaufleiste
   if(!m_scrollh.CreateScroll(m_chart_id,m_subwin,x,y,m_columns_total,m_visible_columns_total))
      return(false);
//--- Ausblenden, wenn jetzt nicht benötigt
   if(m_columns_total<=m_visible_columns_total)
      m_scrollh.Hide();
//---
   return(true);
  }


//---

Ähnliche Änderungen müssen in der Klasse CLabelsTable vorgenommen werden. Die Korrekturen werden im nächsten Update enthalten sein.

 
Anatoli Kazharski:

Ich habe vergessen, eine Korrektur vorzunehmen, wie sie bereits in der CCanvasTable-Klasse vorgenommen wurde.

In der CTable-Klasse müssen Sie die aktuellen Versionen der Methoden CreateScrollV() und CreateScrollH() durch die in der folgenden Auflistung gezeigten Methoden ersetzen:

...
//---

Ähnliche Änderungen müssen in der Klasse CLabelsTable vorgenommen werden. Die Korrekturen werden im nächsten Update enthalten sein.

О! Ich danke Ihnen!
 
Anatoli Kazharski:

Ich habe vergessen, eine Korrektur vorzunehmen, wie sie bereits in der CCanvasTable-Klasse vorgenommen wurde.

In der Klasse CTable müssen Sie die aktuellen Versionen der Methoden CreateScrollV() und CreateScrollH() durch die in der folgenden Auflistung gezeigten Methoden ersetzen:

//+------------------------------------------------------------------+
//|| Erzeugt eine vertikale Bildlaufleiste
//+------------------------------------------------------------------+
bool CTable::CreateScrollV(void)
  {
//--- Speichern des Formularzeigers
   m_scrollv.WindowPointer(m_wnd);
//--- Koordinaten
   int x=(m_anchor_right_window_side)? m_x-m_x_size+m_scrollv.ScrollWidth() : CElement::X2()-m_scrollv.ScrollWidth();
   int y=CElement::Y();
//--- Abmessungen festlegen
   m_scrollv.Id(CElement::Id());
   m_scrollv.IsDropdown(CElement::IsDropdown());
   m_scrollv.XSize(m_scrollv.ScrollWidth());
   m_scrollv.YSize((m_columns_total>m_visible_columns_total)? m_y_size-m_scrollv.ScrollWidth()+1 : m_y_size);
   m_scrollv.AnchorRightWindowSide(m_anchor_right_window_side);
   m_scrollv.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Erstellen einer Bildlaufleiste
   if(!m_scrollv.CreateScroll(m_chart_id,m_subwin,x,y,m_rows_total,m_visible_rows_total))
      return(false);
//--- Ausblenden, wenn jetzt nicht benötigt
   if(m_rows_total<=m_visible_rows_total)
      m_scrollv.Hide();
//---
   return(true);
  }
//+------------------------------------------------------------------+
//|| Erzeugt eine horizontale Bildlaufleiste
//+------------------------------------------------------------------+
bool CTable::CreateScrollH(void)
  {
//--- Speichern des Formularzeigers
   m_scrollh.WindowPointer(m_wnd);
//--- Koordinaten
   int x=CElement::X();
   int y=(m_anchor_bottom_window_side)? m_y-m_area.Y_Size()+m_scrollh.ScrollWidth() : CElement::Y2()-m_scrollh.ScrollWidth();
//--- Abmessungen festlegen
   m_scrollh.Id(CElement::Id());
   m_scrollh.IsDropdown(CElement::IsDropdown());
   m_scrollh.XSize((m_rows_total>m_visible_rows_total)? m_area.XSize()-m_scrollh.ScrollWidth()+1 : m_area.XSize());
   m_scrollh.YSize(m_scrollh.ScrollWidth());
   m_scrollh.AnchorRightWindowSide(m_anchor_right_window_side);
   m_scrollh.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Erstellen einer Bildlaufleiste
   if(!m_scrollh.CreateScroll(m_chart_id,m_subwin,x,y,m_columns_total,m_visible_columns_total))
      return(false);
//--- Ausblenden, wenn jetzt nicht benötigt
   if(m_columns_total<=m_visible_columns_total)
      m_scrollh.Hide();
//---
   return(true);
  }


//---

Ähnliche Änderungen müssen in der Klasse CLabelsTable vorgenommen werden. Die Korrekturen werden im nächsten Update enthalten sein.

Anatoly, die Änderungen wurden bereits vorgenommen. Nehmen Sie das Beispiel aus MQL5\Indicators\Article07\ChartWindow02\ChartWindow02.mq5, korrigieren Sie die Tabelle in Program.mqh, so dass die Anzahl der Zeilen mit der sichtbaren Anzahl der Zeilen übereinstimmt, oder die Anzahl der Spalten mit der sichtbaren Anzahl der Spalten übereinstimmt, oder beides. Zum Beispiel:

//+------------------------------------------------------------------+
//|| Erstellt eine Tabelle|
//+------------------------------------------------------------------+
bool CProgram::CreateTable(void)
  {
#define COLUMNS1_TOTAL (6)
#define ROWS1_TOTAL    (15)
//--- Speichern des Zeigers auf das Formular
   m_table.WindowPointer(m_window1);
//--- Koordinaten
   int x=m_window1.X()+TABLE1_GAP_X;
   int y=m_window1.Y()+TABLE1_GAP_Y;
//--- Anzahl der sichtbaren Spalten und Zeilen
   int visible_columns_total =6;
   int visible_rows_total    =15;
//--- Eigenschaften vor der Erstellung festlegen
   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);
//--- Ein Steuerelement erstellen
   if(!m_table.CreateTable(m_chart_id,m_subwin,x,y))
      return(false);
//--- Füllen wir die Tabelle aus:
// Die erste Zelle ist leer
   m_table.SetValue(0,0,"-");
//--- Überschriften für Spalten
   for(int c=1; c<COLUMNS1_TOTAL; c++)
     {
      for(int r=0; r<1; r++)
         m_table.SetValue(c,r,"SYMBOL "+string(c));
     }
//--- Überschriften für Zeilen, Textausrichtung - nach rechts
   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);
        }
     }
//--- Daten- und Tabellenformatierung (Hintergrundfarbe und Zellenfarbe)
   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);
        }
     }
//--- Aktualisieren Sie die Tabelle, um die Änderungen anzuzeigen
   m_table.UpdateTable();
//--- Hinzufügen des Objekts zu dem gemeinsamen Array von Objektgruppen
   CWndContainer::AddToElementsArray(0,m_table);
   return(true);
  }
//+------------------------------------------------------------------+

Kompilieren Sie, führen Sie das Beispiel aus, klicken Sie auf die unterste Zeile der Tabelle (alles ist in Ordnung), und klicken Sie dann erneut auf sie. Beim zweiten Klick erscheint ein Fehler:

2016.10.24 03:37:16.407 ChartWindow02 (USDCHF,H1)       array out of range in 'Table.mqh' (1091,86)

Was ist zu tun, und was ist zu tun?

 
Artyom Trishkin:

Anatoly, die Änderungen sind vorgenommen worden. Nehmen Sie das Beispiel aus MQL5\Indicators\Article07\ChartWindow02\ChartWindow02.mq5, korrigieren Sie die Tabelle in Program.mqh so, dass die Anzahl der Zeilen mit der sichtbaren Anzahl der Zeilen übereinstimmt, oder die Anzahl der Spalten mit der sichtbaren Anzahl der Spalten übereinstimmt, oder beides. Zum Beispiel so:

...

Kompilieren Sie, führen Sie das Beispiel aus, klicken Sie auf die unterste Zeile der Tabelle (alles ist in Ordnung), und klicken Sie dann erneut darauf. Beim zweiten Klick erscheint ein Fehler:

2016.10.24 03:37:16.407 ChartWindow02 (USDCHF,H1)       array out of range in 'Table.mqh' (1091,86)

Was tun, und was tun?

In den Klassen CScrollH und CScrollV müssen Sie in den ScrollBarControl()-Methoden eine zusätzliche Prüfung der Sichtbarkeit des Elements hinzufügen, wie im folgenden Listing gezeigt:

//+------------------------------------------------------------------+
//| Bildlaufsteuerung|
//+------------------------------------------------------------------+
bool CScrollH::ScrollBarControl(const int x,const int y,const bool mouse_state)
  {
//--- Beenden, wenn es keinen Zeiger auf das Formular gibt
   if(::CheckPointer(m_wnd)==POINTER_INVALID)
      return(false);
//--- Beenden, wenn das Formular durch ein anderes Element blockiert wird
   if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
      return(false);
//--- Beenden, wenn das Element ausgeblendet ist
   if(!CElement::IsVisible())
     return(false);

//--- Kontrolle des Fokus über den Schieberegler
   m_thumb.MouseFocus(x>m_thumb.X() && x<m_thumb.X2() &&
                      y>m_thumb.Y() && y<m_thumb.Y2());
//--- Den Zustand der Maustaste prüfen und speichern
   CScroll::CheckMouseButtonState(mouse_state);
//--- Ändern Sie die Farbe der Bildlaufleiste der Liste
   CScroll::ChangeObjectsColor();
//--- Wenn die Kontrolle an die Bildlaufleiste übergeben wird, definieren Sie die Position des Schiebereglers
   if(CScroll::ScrollState())
     {
      //--- Verschieben des Schiebereglers
      OnDragThumb(x);
      //--- Ändert die Positionsnummer des Schiebereglers
      CalculateThumbPos();
      return(true);
     }
   return(false);
  }

//---

Die Korrektur wird in der nächsten Bibliotheksaktualisierung verfügbar sein.

 
Anatoli Kazharski:

In den Klassen CScrollH und CScrollV müssen wir in den ScrollBarControl()-Methoden eine zusätzliche Prüfung auf die Sichtbarkeit des Elements hinzufügen, wie im folgenden Listing gezeigt:

...

Der Fix wird im nächsten Bibliotheksupdate verfügbar sein.

Vielen Dank! Ich habe diese Änderungen vorgenommen: in der Datei Scrolls.mqh in den Klassen CScrollH und CScrollV habe ich Zeilen hinzugefügt:

//+------------------------------------------------------------------+
//| Schieberegler|
//+------------------------------------------------------------------+
bool CScrollV::ScrollBarControl(const int x,const int y,const bool mouse_state)
  {
//--- Beenden, wenn es keinen Zeiger auf das Formular gibt
   if(::CheckPointer(m_wnd)==POINTER_INVALID)
      return(false);
//--- Wenn das Formular nicht gesperrt ist und die Bezeichner übereinstimmen
   if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
      return(false);
//--- Beenden, wenn das Element ausgeblendet ist
   if(!CElement::IsVisible())
     return(false);

//--- Kontrolle des Fokus über den Schieberegler
   m_thumb.MouseFocus(x>m_thumb.X() && x<m_thumb.X2() &&
                      y>m_thumb.Y() && y<m_thumb.Y2());
//--- Den Zustand der Maustaste prüfen und speichern
   CScroll::CheckMouseButtonState(mouse_state);
//--- Ändern Sie die Farbe des Schiebereglers
   CScroll::ChangeObjectsColor();
//--- Wenn die Kontrolle an die Bildlaufleiste übergeben wird, definieren Sie die Position des Schiebereglers
   if(CScroll::ScrollState())
     {
      //--- Verschieben des Schiebereglers
      OnDragThumb(y);
      //--- Ändert die Positionsnummer des Schiebereglers
      CalculateThumbPos();
      return(true);
     }
//---
   return(false);
  }
//+------------------------------------------------------------------+


//+------------------------------------------------------------------+
//| Bildlaufsteuerung|
//+------------------------------------------------------------------+
bool CScrollH::ScrollBarControl(const int x,const int y,const bool mouse_state)
  {
//--- Beenden, wenn es keinen Zeiger auf das Formular gibt
   if(::CheckPointer(m_wnd)==POINTER_INVALID)
      return(false);
   if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
      return(false);
//--- Beenden, wenn das Element ausgeblendet ist
   if(!CElement::IsVisible())
     return(false);

//--- Kontrolle des Fokus über den Schieberegler
   m_thumb.MouseFocus(x>m_thumb.X() && x<m_thumb.X2() &&
                      y>m_thumb.Y() && y<m_thumb.Y2());
//--- Den Zustand der Maustaste prüfen und speichern
   CScroll::CheckMouseButtonState(mouse_state);
//--- Ändern Sie die Farbe der Bildlaufleiste der Liste
   CScroll::ChangeObjectsColor();
//--- Wenn die Kontrolle an die Bildlaufleiste übergeben wird, definieren Sie die Position des Schiebereglers
   if(CScroll::ScrollState())
     {
      //--- Verschieben des Schiebereglers
      OnDragThumb(x);
      //--- Ändert die Positionsnummer des Schiebereglers
      CalculateThumbPos();
      return(true);
     }
   return(false);
  }
//+------------------------------------------------------------------+

Ich kompiliere und führe dieselbe Testdatei aus \MQL5\Indicators\Article07\ChartWindow02\ChartWindow02 .mq5 aus, in der ich die Tabellenerstellungsfunktion in Program.mqh so geändert habe, dass die Anzahl aller Spalten und Zeilen mit der Anzahl der sichtbaren Spalten und Zeilen übereinstimmt:

//+------------------------------------------------------------------+
//|| Erstellt eine Tabelle|
//+------------------------------------------------------------------+
bool CProgram::CreateTable(void)
  {
#define COLUMNS1_TOTAL (6)
#define ROWS1_TOTAL    (15)
//--- Speichern des Zeigers auf das Formular
   m_table.WindowPointer(m_window1);
//--- Koordinaten
   int x=m_window1.X()+TABLE1_GAP_X;
   int y=m_window1.Y()+TABLE1_GAP_Y;
//--- Anzahl der sichtbaren Spalten und Zeilen
   int visible_columns_total =6;
   int visible_rows_total    =15;
//--- Eigenschaften vor der Erstellung festlegen
   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);
//--- Ein Steuerelement erstellen
   if(!m_table.CreateTable(m_chart_id,m_subwin,x,y))
      return(false);
//--- Füllen wir die Tabelle aus:
// Die erste Zelle ist leer
   m_table.SetValue(0,0,"-");
//--- Überschriften für Spalten
   for(int c=1; c<COLUMNS1_TOTAL; c++)
     {
      for(int r=0; r<1; r++)
         m_table.SetValue(c,r,"SYMBOL "+string(c));
     }
//--- Überschriften für Zeilen, Textausrichtung - nach rechts
   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);
        }
     }
//--- Daten- und Tabellenformatierung (Hintergrundfarbe und Zellenfarbe)
   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);
        }
     }
//--- Aktualisieren Sie die Tabelle, um die Änderungen anzuzeigen
   m_table.UpdateTable();
//--- Hinzufügen des Objekts zu dem gemeinsamen Array von Objektgruppen
   CWndContainer::AddToElementsArray(0,m_table);
   return(true);
  }
//+------------------------------------------------------------------+

ChartWindow02.ex5 kompilieren und ausführen

Mehrmals klicken wir auf die unterste Zeile der Tabelle und erhalten einen Flug außerhalb des Arrays:

2016.10.25 01:39:22.899 ChartWindow02 (USDCHF,H1)       array out of range in 'Table.mqh' (1096,86)
Scheint es, dass sich nichts geändert hat?
 
Artyom Trishkin:

...

Es hat sich also nichts geändert?

Nach den Änderungen, die ich vorgenommen habe, spielt es nicht mehr. Vielleicht habe ich noch einige andere Änderungen vorgenommen, aber ich erinnere mich nicht. Ich habe keine Historie der kleinen Änderungen.

Versuchen Sie vorsichtshalber, die Methoden CScroll::Show() und CScroll::Hide() durch diese Versionen zu ersetzen, falls sie unterschiedlich sind:

//+------------------------------------------------------------------+
//| Zeigt den Menüpunkt|
//+------------------------------------------------------------------+
void CScroll::Show(void)
  {
//--- Beenden, wenn die Anzahl der Listenelemente nicht größer ist als die Anzahl des sichtbaren Teils der Liste
   if(m_items_total<=m_visible_items_total)
      return;
//---
   m_area.Timeframes(OBJ_ALL_PERIODS);
   m_bg.Timeframes(OBJ_ALL_PERIODS);
   m_inc.Timeframes(OBJ_ALL_PERIODS);
   m_dec.Timeframes(OBJ_ALL_PERIODS);
   m_thumb.Timeframes(OBJ_ALL_PERIODS);
//--- Aktualisieren der Position von Objekten
   Moving(m_wnd.X(),m_wnd.Y(),true);
//--- Sichtbarkeitsstatus
   CElement::IsVisible(true);
  }
//+------------------------------------------------------------------+
//| Blendet den Menüpunkt aus|
//+------------------------------------------------------------------+
void CScroll::Hide(void)
  {
   m_area.Timeframes(OBJ_NO_PERIODS);
   m_bg.Timeframes(OBJ_NO_PERIODS);
   m_inc.Timeframes(OBJ_NO_PERIODS);
   m_dec.Timeframes(OBJ_NO_PERIODS);
   m_thumb.Timeframes(OBJ_NO_PERIODS);
//--- Sichtbarkeitsstatus
   CElement::IsVisible(false);
  }


//---

Wenn das nicht hilft, müssen Sie auf das nächste Update warten.

 
Anatoli Kazharski:

Aber nach den Änderungen, die ich vorgenommen habe, wird es nicht mehr abgespielt. Vielleicht habe ich noch andere Änderungen vorgenommen, aber ich weiß es nicht mehr. Ich markiere den Verlauf kleinerer Änderungen nicht.

Versuchen Sie vorsichtshalber, die Methoden CScroll::Show() und CScroll::Hide() durch diese Versionen zu ersetzen, falls sie unterschiedlich sind:

//+------------------------------------------------------------------+
//| Zeigt den Menüpunkt|
//+------------------------------------------------------------------+
void CScroll::Show(void)
  {
//--- Beenden, wenn die Anzahl der Listenelemente nicht größer ist als die Anzahl des sichtbaren Teils der Liste
   if(m_items_total<=m_visible_items_total)
      return;
//---
   m_area.Timeframes(OBJ_ALL_PERIODS);
   m_bg.Timeframes(OBJ_ALL_PERIODS);
   m_inc.Timeframes(OBJ_ALL_PERIODS);
   m_dec.Timeframes(OBJ_ALL_PERIODS);
   m_thumb.Timeframes(OBJ_ALL_PERIODS);
//--- Aktualisieren der Position von Objekten
   Moving(m_wnd.X(),m_wnd.Y(),true);
//--- Sichtbarkeitsstatus
   CElement::IsVisible(true);
  }
//+------------------------------------------------------------------+
//| Blendet den Menüpunkt aus|
//+------------------------------------------------------------------+
void CScroll::Hide(void)
  {
   m_area.Timeframes(OBJ_NO_PERIODS);
   m_bg.Timeframes(OBJ_NO_PERIODS);
   m_inc.Timeframes(OBJ_NO_PERIODS);
   m_dec.Timeframes(OBJ_NO_PERIODS);
   m_thumb.Timeframes(OBJ_NO_PERIODS);
//--- Sichtbarkeitsstatus
   CElement::IsVisible(false);
  }


//---

Wenn das nicht hilft, müssen Sie auf das nächste Update warten.

Danke, es scheint zu helfen. Es fehlten Zeilen über den Sichtbarkeitsstatus in Show():

//--- Sichtbarkeitsstatus
   CElement::IsVisible(true);

: und Hide():

//--- Sichtbarkeitsstatus
   CElement::IsVisible(false);
 
Artyom Trishkin:

Danke, es scheint funktioniert zu haben. Es fehlten Zeilen über den Sichtbarkeitsstatus in Show():

//--- Sichtbarkeitsstatus
   CElement::IsVisible(true);

und Hide():

//--- Sichtbarkeitsstatus
   CElement::IsVisible(false);

Eine weitere Korrektur ist erforderlich. Die Sichtbarkeit sollte vor dem Aktualisieren der Position des Elements gesetzt werden. Etwa so:

...
//--- Sichtbarkeitsstatus
   CElement::IsVisible(true);
//--- Aktualisieren der Position von Objekten
   Moving(m_wnd.X(),m_wnd.Y(),true);
...
 

Die Interaktivität von Schnittstellenelementen, die über einen Timer implementiert wird, ist eine seltsame Lösung. - Warum sollte sie durch (oder mit) einem Timer implementiert werden? - Natürlich wird das eine Menge Ressourcen verbrauchen.

Man braucht überhaupt keinen Timer, um die Zustände von Steuerelementen zu kontrollieren.

1. Erfassen Sie die aktuellen Koordinaten aller Elemente im Array (Map). Passen Sie die Positionskoordinaten aller Formularobjekte an, wenn Sie das Fenster verschieben.

2. Erstellen Sie eine Funktion zum Auffinden von Elementen nach Koordinaten (Lokalisierer). Die Funktion führt eine Schleife durch die aufgezeichneten aktuellen Elementkoordinaten und findet das Element, das sich jetzt unter dem Cursor befindet.

3. Rufen Sie den Lokalisierer über das Ereignis "CHARTEVENT_MOUSE_MOVE" auf (beim Ereignis der Cursorbewegung).

4. Übergeben Sie den vom Lokalisierer zurückgegebenen Objektnamen an die Interaktivitätsfunktion, wo die Funktion ObjectSetInteger() auf das Objekt angewandt wird, wodurch es gezwungen wird, seine Farbe zu ändern.


Wie Sie sehen können, gibt es in diesem Schema keinen Timer, so dass keine unnötigen Ressourcen verbraucht werden.

 
Реter Konow:

Die Interaktivität von Schnittstellenelementen, die über einen Timer implementiert wird, ist eine seltsame Lösung. - Warum sollte sie durch (oder mit) einem Timer implementiert werden? - Natürlich wird sie eine Menge Ressourcen verbrauchen.

...

Wie Sie sehen können, gibt es in diesem Schema keinen Timer, also gibt es keinen unnötigen Ressourcenverbrauch.

Sie irren sich. Ich habe in den Kommentaren oben bereits ausführlich genug beantwortet, warum das so gemacht wurde.

Es verbraucht jetzt nicht mehr viele Ressourcen (jetzt auch in Windows 10 ). Haben Sie den Artikel (und auch die Kommentare) gelesen?

//---

P.S. Übrigens ist der CPU-Ressourcenverbrauch in verschiedenen Terminals (MT4/MT5) und Betriebssystemversionen (Windows) unter gleichen Bedingungen sehr unterschiedlich. Unter Windows 7 zeigte sich das MetaTrader 4 Terminal deutlich besser als MetaTrader 5. Leider kann ich Ihnen jetzt keine Zahlen nennen, da ich bereits komplett auf Windows 10 umgestiegen bin.

Was die Optimierung angeht, so habe ich noch nicht alle Möglichkeiten ausgeschöpft. Es gibt noch etwas zu optimieren und ein Verständnis dafür, wie.