Leinwand ist cool! - Seite 44

 
Nikolai Semko:

Diese Funktionen sind erschreckend schlecht geschrieben. Das ist eine Wahnsinns Sache. Kein normales Anti-Aliasing, keine normale Farbmischung und Transparenzbehandlung. Wir sollten sie einfach zerknüllen, in den Müll werfen und neue schreiben.
Ich habe hier schon einmal darüber geschrieben.

Auf jeden Fall sollten Sie die Standardfunktion PixelTransform durch diese Funktion ersetzen:

https://www.mql5.com/ru/forum/1111/page2553#comment_13054823

Ich habe angefangen, meine doppelte Version zu schreiben (bei der alle int-Eingabeparameter doppelt sind), habe sie aber nicht fertiggestellt und ins Regal gestellt. Trotz ihrer scheinbaren Einfachheit ist dies keine einfache Aufgabe. Nun, es ist kein Problem, ihn genau zu schreiben, das Problem ist, eine sehr hohe Qualität zu schreiben, damit der Algorithmus schnell ist. Mein Hauptproblem ist der Perfektionismus.

Ich sehe, sie sind noch nicht fertig)

Es ist unwahrscheinlich, dass ich in Versuchung komme, die gesamte Leinwand umzuschreiben. Ich werde 2 Ein-Pixel-Zeichen nebeneinander zeichnen müssen, anstatt eines Zwei-Pixel-Zeichens für jetzt)

 
Andrey Khatimlianskii:

Verstehe, sie haben es nicht zu Ende gebracht.)

Ich werde wohl kaum in Versuchung kommen, die gesamte Leinwand umzuschreiben. Ich muss einfach 2 Ein-Pixel-Bilder nebeneinander zeichnen, statt einem Doppel-Pixel-Bild).

Sie müssen nicht die ganze Leinwand umschreiben. Die Hauptsache ist, dass ein Kreisformat entsteht

Circle(double x, double y, double r1, double r2=0, uint clr)  

und machen die Linien normal.

Polyline(const double &x[],const double &y[], const uint clr,const double size,const uint style,ENUM_LINE_END end_style)

Dies sollte 95 % Ihres Bedarfs decken

 

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Wie man alle Objekte in 1 Objekt umwandelt

Nikolai Semko, 2019.10.05 22:39

Canvas ist in der Tat die Lösung.

Und Canvas ist viel einfacher, als es auf den ersten Blick scheint.

Hier ist ein primitives Beispiel für einen Indikator (MQL5 & MQL4) mit einem Objekt OBJ_BITMAP_LABEL, in dem es viele Fenster gibt.

#property indicator_chart_window
#include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164 - MQL5
                              //https://www.mql5.com/en/code/23840 - MQL4

struct win {
   int               x;
   int               y;
   int               width;
   int               height;
   uint              clr;
};
win wnd[30];
int OnInit() {
   for (int i=0; i<ArraySize(wnd); i++) {
      wnd[i].width=rand()%200+70;
      wnd[i].height=rand()%150+50;
      wnd[i].x=rand()%(W.Width-wnd[i].width);
      wnd[i].y=rand()%(W.Height-wnd[i].height);
      wnd[i].clr=ARGB(255,rand()%150+100,rand()%150+100,rand()%150+100);
   }
   ShowAllWind();
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+

int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) {
   return(rates_total);
}

//+------------------------------------------------------------------+

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam) {
   static bool click = false;
   static int x_mouse=0, y_mouse=0;
   static int focus=-1, xfocus=0, yfocus=0;
   int x=(int)lparam;
   int y=(int)dparam;
   if (sparam!="1" && click) focus=-1;
   if (sparam=="1" && !click) {
      focus=-1;
      for (int i=ArraySize(wnd)-1; i>=0; i--) {
         if (wnd[i].x<x && wnd[i].y<y && wnd[i].x+wnd[i].width>x && wnd[i].y+20>y) {
            focus=i;
            xfocus=x;
            yfocus=y;
            break;
         }
      }
      if (focus>=0) ChartSetInteger(0,CHART_MOUSE_SCROLL,false);
      else ChartSetInteger(0,CHART_MOUSE_SCROLL,true);
   }
   click=(sparam=="1")?true:false;
   if (id==CHARTEVENT_MOUSE_MOVE && focus>=0) {
      wnd[focus].x+=x-xfocus;
      wnd[focus].y+=y-yfocus;
      xfocus=x;
      yfocus=y;
      ShowAllWind();
   }
   if (id==CHARTEVENT_CHART_CHANGE) ShowAllWind();
}

//+------------------------------------------------------------------+

void ShowAllWind() {
   Canvas.Erase();
   for (int i=0; i<ArraySize(wnd); i++) {
      Canvas.FillRectangle(wnd[i].x,wnd[i].y,wnd[i].x+wnd[i].width,wnd[i].y+wnd[i].height,ARGB(255,GETRGBR(wnd[i].clr)*0.5,GETRGBG(wnd[i].clr)*0.5,GETRGBB(wnd[i].clr)*0.5));
      Canvas.FillRectangle(wnd[i].x+3,wnd[i].y+23,wnd[i].x+wnd[i].width-3,wnd[i].y+wnd[i].height-3,wnd[i].clr);
      Canvas.FillRectangle(wnd[i].x+3,wnd[i].y+3,wnd[i].x+wnd[i].width-3,wnd[i].y+20,ARGB(255,GETRGBR(wnd[i].clr)*0.7,GETRGBG(wnd[i].clr)*0.7,GETRGBB(wnd[i].clr)*0.7));
   }
   Canvas.Update();
}
//+------------------------------------------------------------------+

 
Nikolai Semko:

Großartig!

Ich brauche diese Funktion und die Möglichkeit, meine eigenen Indikatoren in diesen Minifenstern zu zeichnen.

Warum ist ein Fenster unter einem anderen versteckt und das andere liegt darüber, können Sie das beheben?

Eine weitere Frage: Funktioniert derselbe Indikator auch, wenn er in einem anderen Diagramm ausgeführt wird? Die Ereignisse überschneiden sich nicht wie in der Standardbibliothek?

Und wenn beide Fenster die gleichen Koordinaten haben, welches Fenster wird dann mit der Maus gezogen?

Ist es möglich, die Größe des Fensters mit der Maus zu ändern?

 
Sergey Chalyshev:

Großartig!

Ich brauche diese Funktion und die Möglichkeit, meine eigenen Indikatoren in diesen Minifenstern zu zeichnen.

Warum ist ein Fenster unter einem anderen versteckt und das andere liegt darüber, können Sie das beheben?

Eine weitere Frage: Funktioniert derselbe Indikator auch, wenn er in einem anderen Diagramm ausgeführt wird? Die Ereignisse überschneiden sich nicht wie in der Standardbibliothek?

Und wenn beide Fenster die gleichen Koordinaten haben, welches Fenster wird dann mit der Maus gezogen?

Ist es möglich, die Größe des Fensters mit der Maus zu ändern?

In diesem Beispiel wird lediglich das Fensterdienstalter eingeführt. Je kleiner der Index im Array der Win-Struktur ist, desto niedriger ist die virtuelle Fensterebene.

Sie können es auf jede beliebige Weise umsetzen. Wenn wir zum Beispiel ein Fenster "gepackt" haben, wird es das oberste auf dem Bildschirm und im Array.

Sie können auch Transparenz herstellen. Ich habe Ihnen hier gezeigt, wie man das macht. (dort ist es notwendig, jedes Piskel zu bearbeiten).

Das andere Diagramm kann auch über das andere laufen.
Wenn die Koordinaten übereinstimmen, wird die oberste gezogen.

Mit Kanvas können Sie alles innerhalb Ihres Fensters und anderer MT-Fenster tun.
Außerdem können Sie ein Fenster von MT5 abtrennen und es frei schwebend senden, auch zwischen Monitoren. Sie können eshier sehen.

 
Nikolai Semko:

In diesem Beispiel wird lediglich das Fensterdienstalter eingeführt. Je kleiner der Index in der Win-Struktur ist, desto niedriger ist die Ebene des virtuellen Fensters.

Sie können es auf jede beliebige Weise umsetzen. Wenn zum Beispiel ein Fenster "gegriffen" wird, wird es das oberste auf dem Bildschirm und im Array.

Sie können auch Transparenz herstellen. Ich habe Ihnen hier gezeigt, wie Sie das machen können. (dort müssen Sie jedes Peekel bearbeiten).

Ich kann es auch auf einer anderen Karte laufen lassen.
Wenn die Koordinaten übereinstimmen, wird die oberste gezogen.

Mit Kanvas können Sie alles innerhalb Ihres Fensters und anderer MT-Fenster tun.
Außerdem kann das Fenster von МТ5 abgetrennt und in den frei schwebenden Bereich zwischen den Monitoren verschoben werden. Sie können es hier sehen.

Ein bisschen falsch, wahrscheinlich habe ich die Frage nicht richtig gestellt.

Es ist nicht schwierig, mehrere Fenster in einem Programm zu organisieren (Skript, Indikator).

Ich möchte einen Indikator erstellen, der Daten in einem eigenen kleinen Fenster in einem Diagramm anzeigt. Dieses Fenster kann bequem in einem Diagramm platziert werden, Sie können es mit der Maus ziehen, die Größe des Fensters mit der Maus verändern (das ist wünschenswert, aber Sie können es trotzdem tun). Wir müssen mehrere Indikatoren im Diagramm ausführen, jeder mit seinen eigenen Parametern. Ich habe noch nicht herausgefunden, wie man die Ereignisse verschiedener Indikatoren so gestaltet, dass sie sich nicht überschneiden und der Indikator angemessen auf Mausereignisse reagiert. Ich habe mich noch nicht entschieden, was besser ist, einfacher, die Leinwand oder die Objekte. Mit der Standard-Dialogbibliothek funktioniert nichts.

 
Sergey Chalyshev:

...Ich kann immer noch nicht herausfinden, wie ich es schaffe, dass sich die Ereignisse der verschiedenen Indikatoren nicht überschneiden...

Der einfachste Weg ist eine String-Variable im Eigenschaftsfenster, die Sie zu den Namen der grafischen Objekte hinzufügen.

 
Dmitry Fedoseev:

Der einfachste Weg ist eine String-Variable im Eigenschaftsfenster, die zu den Namen der grafischen Objekte hinzugefügt wird. Hin- und hergerissen zwischen Wahrheit und Mitgliedschaft?

Das tue ich natürlich auch. Das Problem ist das Ziehen und Ablegen mit der Maus. Wenn Objekte die gleichen Koordinaten haben, liegt eines genau unter dem anderen. Wenn man sie anklickt, welche reagiert dann?

Von welchen Vereinen sprechen Sie? Ich bin in keinem Verein angemeldet und habe es auch nicht vor).

p.s. Können Sie mir ein Beispiel zeigen?

 
Sergey Chalyshev:

Natürlich tue ich das. Das Problem ist das Ziehen und Ablegen mit der Maus. Wenn die Objekte die gleichen Koordinaten haben, liegt eines genau unter dem anderen. Wenn man sie anklickt, welche reagiert dann?

Von welchen Vereinen sprechen Sie? Ich bin in keinem Verein angemeldet und habe es auch nicht vor).

p.s. Können Sie mir ein Beispiel zeigen?

Falscher Verein, sorry... Ich bin fertig mit diesem Club)).

Irgendein Objekt wird antworten. Vielleicht sollte man bei der Aktivierung eines Objekts dessen Z-Reihenfolge so ändern, dass es höher als alle anderen ist. Wir sollten es versuchen.

 
Sergey Chalyshev:

Natürlich tue ich das. Das Problem ist das Ziehen und Ablegen mit der Maus. Wenn die Objekte die gleichen Koordinaten haben, liegt eines genau unter dem anderen. Wenn man sie anklickt, welche reagiert dann?

Von welchen Vereinen sprechen Sie? Ich bin in keinem Verein angemeldet und habe es auch nicht vor).

p.s. Können Sie mir ein Beispiel zeigen?

Im Allgemeinen sollte in einer solchen Situation das zuletzt bewegte Objekt reagieren - es liegt oben...