La tela è forte! - pagina 44

 
Nikolai Semko:

Queste funzioni sono scritte orribilmente male. È una cosa incredibile. Nessun normale anti-aliasing, nessuna normale miscelazione dei colori e gestione della trasparenza. Dovremmo semplicemente accartocciarli, buttarli nel cestino e scriverne di nuovi.
Ne ho già scritto qui.

In ogni caso, dovreste sicuramente sostituire la funzione PixelTransform standard con questa:

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

Ho iniziato a scrivere la mia versione doppia (dove tutti i parametri di input int sono doppi), ma non l'ho finita e l'ho messa sullo scaffale. Non è un compito molto semplice nonostante la sua apparente semplicità. Beh, non è un problema scriverlo accuratamente, il problema è scrivere una qualità molto alta, in modo che l'algoritmo sia veloce. Il mio problema principale è il perfezionismo.

Capisco, non hanno finito)

Non è probabile che io sia tentato di riscrivere l'intera tela. Dovrò disegnarne 2 a un pixel affiancati invece di 1 a due pixel per ora)

 
Andrey Khatimlianskii:

Capisco, non l'hanno finito).

Non è probabile che io sia tentato di riscrivere l'intera tela. Dovrò semplicemente disegnare 2 single-pixel affiancati invece di 1 double-pixel).

In realtà, non è necessario riscrivere l'intera tela. La cosa principale è fare un formato circolare

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

e rendere le linee normali.

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

Questo dovrebbe coprire il 95% delle vostre esigenze

 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Come convertire tutti gli oggetti in 1 oggetto

Nikolai Semko, 2019.10.05 22:39

Infatti, Canvas è la soluzione.

E Canvas è molto più facile di quanto sembri a prima vista.

Ecco un esempio primitivo di un indicatore (MQL5 & MQL4) con un oggetto OBJ_BITMAP_LABEL in cui ci sono molte finestre.

#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:

Grande!

Ho davvero bisogno di questa caratteristica e di poter disegnare i miei indicatori in queste mini-finestre.

Perché una finestra si nasconde sotto un'altra e l'altra sta sopra, potete sistemarla?

Un'altra domanda, se lo stesso indicatore viene eseguito su un altro grafico, funzionerà? Gli eventi non si sovrappongono come nella libreria standard?

E se entrambe le finestre hanno le stesse coordinate, quale finestra sarà trascinata con il mouse?

È possibile ridimensionare la finestra con il mouse?

 
Sergey Chalyshev:

Grande!

Ho davvero bisogno di questa caratteristica e di poter disegnare i miei indicatori in queste mini-finestre.

Perché una finestra si nasconde sotto un'altra e l'altra sta sopra, potete sistemarla?

Un'altra domanda, se lo stesso indicatore viene eseguito su un altro grafico, funzionerà? Gli eventi non si sovrappongono come nella libreria standard?

E se entrambe le finestre hanno le stesse coordinate, quale finestra sarà trascinata con il mouse?

È possibile ridimensionare la finestra con il mouse?

Questo esempio implementa semplicemente l'anzianità della finestra. In realtà, più piccolo è l'indice nell'array della struttura win, più basso è il livello della finestra virtuale.

Potete implementarlo in qualsiasi modo vogliate. Per esempio, se abbiamo "afferrato" una finestra, questa diventa la più alta sullo schermo e nell'array.

Si può anche implementare la trasparenza. Vi ho mostrato come farlo qui . (lì è necessario elaborare ogni piskel).

L'altro grafico può anche essere eseguito sull'altro.
Se le coordinate sono uguali, viene trascinato quello in cima.

con kanvas puoi fare tutto all'interno della tua finestra e di altre finestre MT.
Inoltre, è possibile staccare una finestra da MT5 e mandarla in free floating, anche tra i monitor. Potete vederloqui .

 
Nikolai Semko:

Questo esempio implementa semplicemente l'anzianità della finestra. Essenzialmente, più piccolo è l'indice nell'array della struttura win, più basso è il livello della finestra virtuale.

Potete implementarlo in qualsiasi modo vogliate. Per esempio, se una finestra è "afferrata", allora diventa la più alta sullo schermo e nell'array.

Si può anche implementare la trasparenza. Vi ho mostrato come farlo qui . (lì devi elaborare ogni peekel).

Posso eseguirlo anche su un altro grafico.
Se le coordinate sono uguali, viene trascinato quello in cima.

Con kanvas puoi fare tutto all'interno della tua finestra e di altre finestre MT.
Inoltre, la finestra può essere staccata da МТ5 e spostata nella zona di libero galleggiamento tra i monitor. Potete vederlo qui .

Leggermente sbagliato, probabilmente non ho fatto la domanda correttamente.

Non è difficile organizzare diverse finestre in un programma (script, indicatore).

Voglio fare un indicatore che mostri i dati nella sua piccola finestra su un grafico. Questa finestra può essere posizionata comodamente in un grafico, potete trascinarla con il mouse, ridimensionare la finestra con il mouse (è auspicabile, ma potete farlo comunque). Dobbiamo eseguire diversi indicatori nel grafico, ognuno con i propri parametri. Non ho ancora capito come fare in modo che gli eventi di diversi indicatori non si sovrappongano e che l'indicatore reagisca adeguatamente agli eventi del mouse. Non ho deciso quale sia meglio, più semplice, la tela o gli oggetti. Niente funziona con la libreria Dialog standard.

 
Sergey Chalyshev:

...Non riesco ancora a capire come fare in modo che gli eventi di diversi indicatori non si sovrappongano...

Il modo più semplice è una variabile stringa nella finestra delle proprietà, aggiungerla ai nomi degli oggetti grafici.

 
Dmitry Fedoseev:

Il modo più semplice è una variabile stringa nella finestra delle proprietà, aggiungerla ai nomi degli oggetti grafici. Mente combattuta tra verità e appartenenza?

Naturalmente, è quello che faccio. Il problema è il trascinamento con il mouse. Se gli oggetti hanno le stesse coordinate, uno è esattamente sotto l'altro. Quando ci clicchi sopra, quale reagisce?

Di quali club stai parlando, non sono iscritto a nessun club e non ho intenzione di farlo ))

p.s. puoi mostrarmi un esempio?

 
Sergey Chalyshev:

Naturalmente, è così. Il problema è il trascinamento con il mouse. Se gli oggetti hanno le stesse coordinate, uno è esattamente sotto l'altro. Quando ci clicchi sopra, quale reagisce?

Di quali club stai parlando, non sono iscritto a nessun club e non ho intenzione di farlo ))

p.s. puoi mostrarmi un esempio?

Club sbagliato, scusate... Ho chiuso con questo club)).

Qualche oggetto risponderà. Forse quando si attiva un oggetto cambia il suo ordine Z in modo che sia più alto di tutti gli altri. Dovremmo provare.

 
Sergey Chalyshev:

Naturalmente, è così. Il problema è il trascinamento con il mouse. Se gli oggetti hanno le stesse coordinate, uno è esattamente sotto l'altro. Quando ci clicchi sopra, quale reagisce?

Di quali club stai parlando, non sono iscritto a nessun club e non ho intenzione di farlo ))

p.s. puoi mostrarmi un esempio?

Generalmente, in una situazione del genere, l'oggetto che è stato spostato per ultimo dovrebbe reagire - è in cima...