Bibliotheken: Easy Canvas - Seite 12

 
Nikolai Semko:

Gilt dies für den normalen Modus oder für den Testmodus?

Normaler Modus, Nikolai.

 
Nikolai Semko:

Ich danke Ihnen!

Ist diese Funktion nicht geeignet?

Leider nicht. Sie verschiebt das Bitmap-Objekt selbst, ich brauche eine Funktion, die den Inhalt x-Punkte verschiebt. Ich weiß, dass der Speicher intern aus einem x, y Array besteht, aber es gibt kein memmove oder so in mql. Ich weiß nicht, wie ich den Speicher schnell verschieben kann.

 
Владислав Качило :

Normaler Modus, Nikolai.

Ich folge normalerweise dem folgenden Schema:

  1. Ich führe alle Zeichnungen, die an Balken oder Zeit gebunden sind, in einer einzigen Funktion aus, zum Beispiel void Draw()
  2. in OnChartEvent füge ich die Zeile
    if (id == CHARTEVENT_CHART_CHANGE ) Draw (); 
    und verfolge das Chart Change Event (ein neuer Balken ist auch ein Chart Change Event).
  3. in OnCalculate für den Testmodus füge ich eine Zeile für das Neuzeichnen hinzu, wenn z.B. ein neuer Balken auftritt, da OnChartEvent nicht funktioniert:
    .
     if(rate_total-prev_calculated == 1) if (Canvas.tester) {ChartChanged (); Draw ();}

Wenn es in MT4 nicht funktioniert, dann ist etwas mit dem CHARTEVENT_CHART_CHANGE-Ereignis falsch. Ich kann es jetzt nicht überprüfen, es gibt noch keine Kursdaten.

 
Nikolai Semko:

Normalerweise gehe ich wie folgt vor:

  1. Ich führe alle Zeichenvorgänge, die an Balken oder Zeit gebunden sind, in einer Funktion aus, zum Beispiel void Draw()
  2. Ich füge eine Zeile in OnChartEvent ein, um das Chart Change Event zu verfolgen (ein neuer Balken ist auch ein Chart Change Event).
  3. In OnCalculate für den Testmodus füge ich eine Zeile für das Neuzeichnen hinzu, z. B. wenn ein neuer Balken auftritt, da OnChartEvent nicht funktioniert:

Wenn es in MT4 nicht funktioniert, dann ist etwas mit dem CHARTEVENT_CHART_CHANGE-Ereignis falsch. Ich kann es jetzt nicht überprüfen, es gibt noch keine Kursdaten.

Nicholas, damit Sie nicht Ihre Zeit verschwenden, habe ich oben eine Lösung geschrieben, die mein Problem gelöst hat, nämlich, wie Sie richtig bemerkt haben, den folgenden Code in OnCalcucate() eingefügt:

if(rates_total - prev_calculated == 1)ChartChanged();

 
Mighty7:

Leider nicht. Es bewegt das Bitmap-Objekt selbst, ich brauche eine Funktion, die den Inhalt x Punkte bewegt. Ich weiß, dass der Speicher intern aus einem x, y Array besteht, aber es gibt kein memmove oder so in mql. Ich weiß nicht, wie ich den Speicher schnell verschieben kann.

Ich habe es nicht verstanden, müssen Sie den rechteckigen Bereich innerhalb der gesamten Leinwand zu bewegen?

 
Vladyslav Katsylo:

Nicholas, damit Sie nicht Ihre Zeit verschwenden, habe ich oben eine Lösung geschrieben, die mein Problem gelöst hat, nämlich, wie Sie richtig bemerkt haben, den folgenden Code in OnCalcucate() eingefügt:

Im normalen Nicht-Test-Modus sollten Sie dies nicht tun, da die Funktion ChartChanged() zweimal hintereinander ausgeführt wird, was nicht sinnvoll ist. Schließlich wird sie ausgeführt, wenn das Ereignis CHARTEVENT_CHART_CHANGE in der Datei iCanvas.mqh eintritt.
Es ist korrekt, Ihre an Balken oder Zeit gebundene Leinwand in OnChartEvent neu zu zeichnen, wenn das Fensterwechselereignis ( CHARTEVENT_CHART_CHANGE) eintritt, ohne ChartChanged() zu verwenden.

 
Vladyslav Katsylo:

Nicholas, damit Sie nicht Ihre Zeit verschwenden, habe ich oben eine Lösung geschrieben, die mein Problem gelöst hat, nämlich, wie Sie richtig bemerkt haben, den folgenden Code in OnCalcucate() eingefügt:

Sie müssen Folgendes berücksichtigen:

  • ChartChanged() wird jedes Mal ausgeführt, wenn das Ereignis CHARTEVENT_CHART_CHANGE in OnChartEvent innerhalb der iCanvas-Klasse auftritt
  • Das OnChartEvent innerhalb der iCanvas-Klasse wird zuerst ausgeführt , und dann wird das OnChartEvent Ihres Codes ausgeführt .

Ihr Problem lag darin, dass OnCalculate offenbar vor OnChartEvent ausgeführt wird und daher ChartChanged() noch nicht verarbeitet wurde.
Deshalb ist es sinnvoll, den Redraw-Handler genau in OnChartEvent und nicht in OnCalculate zu implementieren
. Dies ist insbesondere deshalb sinnvoll, weil der Benutzer die Größe des Fensters jederzeit ändern kann. Das CHARTEVENT_CHART_CHANGE-Ereignis ist für all dies zuständig

 
Nikolai Semko:

Ich habe es nicht verstanden. Müssen Sie den rechteckigen Bereich innerhalb der gesamten Leinwand verschieben?

Ja. Beispiel: Ich zeichne einen Kreis in der Mitte der bildschirmfüllenden Leinwand und möchte den Kreis nach links verschieben, aber ich möchte nicht den gesamten Bereich löschen und den Kreis bei jeder Bewegung neu zeichnen, sondern einfach den Speicher nach links verschieben.

Der CCanvas ist einfach ein x/y Array von Punkten.

   uint              m_pixels[];               // Array von Pixeln
//+------------------------------------------------------------------+
//| Pixelfarbe erhalten|
//+------------------------------------------------------------------+
uint CCanvas::PixelGet(const int x,const int y) const
  {
//--- Koordinaten prüfen
   if(x>=0 && x<m_width && y>=0 && y<m_height)
      return(m_pixels[y*m_width+x]);
//--- Fehler
   return(0);
  }

Ich meine eine Funktion, die die m_pixels nach links, rechts, oben, unten verschiebt.

 
Mighty7:

Ja. Beispiel: Ich zeichne einen Kreis in der Mitte der Vollbildleinwand und möchte den Kreis nach links verschieben, aber ich möchte nicht den gesamten Bereich löschen und den Kreis bei jeder Bewegung neu malen, sondern einfach den Speicher nach links verschieben.

Der CCanvas ist einfach ein x/y Array von Punkten.

Ich meine eine Funktion, die die m_pixels nach links, rechts, oben, unten verschiebt.

Ja, das ist ein vernünftiger Wunsch.
Außerdem ist es nicht schwer, das zu implementieren.
Ich habe darüber nachgedacht, bin aber zu dem Schluss gekommen, dass es einen einfacheren Weg gibt, den rechteckigen Teil der gemeinsamen Leinwand zu verschieben, wenn das nötig ist:

  • Erstellen Sie eine neue, kleinere Leinwand. In diesem Fall muss man sich nicht darum kümmern, den Hintergrund des zu verschiebenden Teils zu füllen.

Ja, ein wohlbegründeter Wunsch.
Außerdem ist es nicht schwer, ihn zu verwirklichen.
Ich habe darüber nachgedacht, bin aber zu dem Schluss gekommen, dass es einen einfacheren Weg gibt, den rechteckigen Teil der gemeinsamen Leinwand zu verschieben, wenn das notwendig ist:
  • Erstellen Sie eine neue, kleinere Leinwand. In diesem Fall müssen Sie sich nicht darum kümmern, den Hintergrund des verschobenen Teils zu füllen.
 
Nikolai Semko:

Ja, das ist ein vernünftiger Wunsch.
Außerdem ist es nicht schwer, ihn zu verwirklichen.
Ich habe darüber nachgedacht, bin aber zu dem Schluss gekommen, dass es eine einfachere Möglichkeit gibt, den rechteckigen Teil der allgemeinen Leinwand zu verschieben, wenn das notwendig ist:

  • Erstellen Sie eine neue, kleinere Leinwand. In diesem Fall müssen Sie sich nicht darum kümmern, den Hintergrund des zu verschiebenden Teils zu füllen.

Ja, ein wohlbegründeter Wunsch.
Außerdem ist es nicht schwer, ihn zu verwirklichen.
Ich habe darüber nachgedacht, bin aber zu dem Schluss gekommen, dass es einen einfacheren Weg gibt, den rechteckigen Teil der gemeinsamen Leinwand zu verschieben, wenn das notwendig ist:
  • Erstellen Sie eine neue, kleinere Leinwand. In diesem Fall müssen Sie sich nicht darum kümmern, den Hintergrund des verschobenen Teils zu füllen.

Das funktioniert nicht, weil mein Canvas der Vollbildschirm ist. Es ist wie ein Zeckendiagramm, aber es kostet zu viel Zeit, den gesamten Hintergrund zu löschen und alles neu zu konstruieren und zu malen, also muss ich den Inhalt nach links verschieben (z. B. 8 Pixel) und nur die neuen 8 Pixel (8 px in x-Richtung und voller Höhe) mit neuen Daten zeichnen. Ich habe versucht, den Canvas mit MoveCanvas um 8 px nach links zu verschieben und das funktioniert auch, aber ich kann die Größe nicht so ändern, dass von links 8 px Breite entfernt werden und rechts 8 px hinzugefügt werden. Ich hoffe, Sie verstehen das...