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

 

Neuer Artikel Grafische Interfaces X: Das Standard Chart-Steuerelement (Build 4) :

Diesmal betrachten wir das Standard Chart-Steuerelement. Dieses erlaubt es uns, eine ganze Serie von Unter-Charts zu erzeugen, mit der Möglichkeit, diese beim Scrollen horizontal zu synchronisieren. Darüber hinaus werden wir weiterhin den Bibliothekscode für eine Reduzierung der CPU-Last optimieren.

Dem Datei-Navigator wurden neue Icons für Ordner und Dateien hinzugefügt (die CFileNavigator Klasse), welche denen von Windows 10 entsprechen.. Ihr schlankes Design eignet sich besser für grafische Oberflächen, aber ggf. können auch benutzerdefinierte Versionen verwendet werden.

 Abbildung 6. Neue Icons für Verzeichnisse und Dateien in dem Datei-Navigator

Abbildung 6. Neue Icons für Verzeichnisse und Dateien in dem Datei-Navigator

Autor: Anatoli Kazharski

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

Für OBJ_CHART Scrolling, warum einen Timer verwenden? Und für die Interaktion mit der Schnittstelle - eine ähnliche Frage. Es scheint, dass Maus-Ereignisse sollte immer ausreichen.

 
fxsaber:

Für OBJ_CHART Scrolling, warum einen Timer verwenden? Und für die Interaktion mit der Schnittstelle - eine ähnliche Frage. Schließlich scheint es, dass Mausereignisse immer ausreichen sollten.

Was Sie zitiert haben, bezieht sich nicht auf OBJ_CHART, sondern auf den Timer der Library-Engine als Ganzes. Deshalb wurde die Lösung dieses Problems in einen separaten Abschnitt des Artikels "Optimierung des Timers und des Event-Handlers der Library-Engine" als Ergänzung zum Hauptthema aufgenommen.

Der Timer wird verwendet, um die Farbe von Steuerelementen beim Überfahren mit der Maus zu ändern, sowie um das Scrollen von Listen, Tabellen, Kalendern und Werten in Eingabefeldern zu beschleunigen.

//---

P.S. Das Scrollen von OBJ_CHART wird durch das Mauszeigerbewegungsereignis CHARTEVENT_MOUSE_MOVE ausgeführt. Im folgenden Listing ist der Code des Handlers (gekürzte Version) von Ereignissen des Elements "Standard Chart" (Klasse CStandardChart):

//+------------------------------------------------------------------+
//| Ereignisbehandlung|
//+------------------------------------------------------------------+
void CStandardChart::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Behandlung des Ereignisses der Cursorbewegung
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      //--- Beenden, wenn das Element ausgeblendet ist
      if(!CElement::IsVisible())
         return;
      //--- Beenden, wenn im Modus "Größenänderung des Unterfensters
      if(CheckDragBorderWindowMode())
         return;
      //--- Beenden, wenn die Nummern der Teilfenster nicht übereinstimmen
      if(CElement::m_subwin!=CElement::m_mouse.SubWindowNumber())
         return;
      //--- Beenden, wenn das Formular durch ein anderes Element blockiert wird
      if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
         return;
      //--- Fokusprüfung
      CElement::MouseFocus(m_mouse.X()>X() && m_mouse.X()<X2() && m_mouse.Y()>Y() && m_mouse.Y()<Y2());
      //--- Wenn ein Fokus vorhanden ist
      if(CElement::MouseFocus())
         //--- Horizontales Scrollen des Diagramms
         HorizontalScroll();
      //--- Wenn kein Fokus vorhanden ist und die linke Maustaste losgelassen wird
      else if(!m_mouse.LeftButtonState())
        {
         //--- Horizontalen Bildlaufzeiger ausblenden
         m_x_scroll.Hide();
         //--- Entsperren des Formulars
         if(m_wnd.IdActivatedElement()==CElement::Id())
           {
            m_wnd.IsLocked(false);
            m_wnd.IdActivatedElement(WRONG_VALUE);
           }
        }
      //---
      return;
     }
//...
  }
 
Anatoli Kazharski:

Zeitgesteuerter Farbwechsel von Bedienelementen bei Mouseover ist eingerichtet

Warum konnte hier nicht die Maus verwendet werden?
 
fxsaber:
Warum kann ich hier nicht die Maus benutzen?

Weil es einen sanften Farbwechsel gibt (die Anzahl der Schritte wird vom Benutzer festgelegt).

Dies gilt auch für das Scrollen von Listen. Wenn Sie die Methode so verwenden, wie sie in SB implementiert ist, werden Sie einen zackigen (ungleichmäßigen) Bildlauf haben.

 
Anatoli Kazharski:

Weil ein sanfter Farbwechsel vorgesehen ist (die Anzahl der Schritte wird vom Benutzer festgelegt).

Dies gilt auch für das Scrollen von Listen. Wenn Sie die Methode so verwenden, wie sie in SB implementiert ist, erhalten Sie einen zackigen (ungleichmäßigen) Bildlauf.

Warum gibt es keinen gezackten Bildlauf für OBJ_CHART?
 
fxsaber:
Warum dann für OBJ_CHART Tearing nicht herauskommen?

In welchem Fall (bezogen auf den Test Expert Advisor aus dem Artikel)?

  1. In dem Fall, wenn durch den Kalender geblättert wird?
  2. Im Falle des manuellen Scrollens durch das CHARTEVENT_MOUSE_MOVE-Ereignis im Item-Eventhandler(CStandardChart) ?

Wenn ersteres, dann ist das Blättern im Diagramm zeitlich begrenzt, so wie das Blättern im Kalender zeitlich begrenzt ist. Das heißt, die Erzeugung des Ereignisses zur Änderung des Kalenderdatums(ON_CHANGE_DATE) wird in einem Intervall von 16 ms getaktet.

Wenn die Sekunde, die Verschiebung berechnet wird und ist nicht immer gleich 1 bar. So scheint es nur, dass das manuelle Blättern durch das Ereignis CHARTEVENT_MOUSE_MOVE reibungslos funktioniert.

 
Anatoli Kazharski:

Wenn die zweite, die Verschiebung berechnet wird und ist nicht immer gleich 1 bar. Es scheint also , dass der manuelle Bildlauf durch das Ereignis CHARTEVENT_MOUSE_MOVE reibungslos funktioniert.

Verstanden, danke!

 
Ich danke Ihnen für den Artikel. Ich habe mich darauf gefreut. Nicht enttäuscht :)
 

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.

Dateien:
TestTable.zip  734 kb
 

Ich habe es gefunden.

Nehmen Sie Ihr Beispiel aus MQL4\Experts\Article07\TestLibrary02\TestLibrary02.mq4.

Aus Ihrem obigen Beispiel:

Machen Sie die Anzahl der Spalten und die Anzahl der sichtbaren Spalten gleich , kompilieren Sie, führen Sie es aus und erhalten Sie einen Fehler.

//+------------------------------------------------------------------+
//|| Erstellt eine Tabelle|
//+------------------------------------------------------------------+
bool CProgram::CreateTable(void)
  {
//#define SPALTE1_GESAMT (100)
//#define ROWS1_TOTAL (1000)
#define COLUMNS1_TOTAL (6)
#define ROWS1_TOTAL    (1000)
//--- 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 ist rechtsbündig
   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);
  }
//+------------------------------------------------------------------+
Wenn Sie die Anzahl der Zeilen und die Anzahl der sichtbaren Zeilen identisch machen, erhalten Sie denselben Fehler.