El lienzo es genial. - página 44

 
Nikolai Semko:

Estas funciones están terriblemente mal escritas. Es un infierno. No hay antialiasing normal, ni manejo normal de la mezcla de colores y la transparencia. Deberíamos arrugarlos y tirarlos a la papelera y escribir otros nuevos.
Ya he escrito sobre ello aquí.

En cualquier caso, debería sustituir la función estándar PixelTransform por ésta:

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

Empecé a escribir mi versión doble (donde todos los parámetros de entrada int son dobles), pero no la terminé y la dejé en la estantería. No es una tarea muy sencilla a pesar de su aparente simplicidad. Bueno, no es un problema escribirlo con precisión, el problema es escribir una calidad muy alta, para que el algoritmo sea rápido. Mi principal problema es el perfeccionismo.

Ya veo, no lo terminaron).

No es probable que tenga la tentación de reescribir todo el lienzo. Tendré que dibujar 2 de un solo píxel uno al lado del otro en lugar de 1 de dos píxeles por ahora )

 
Andrey Khatimlianskii:

Ya veo, no lo terminaron).

No es probable que tenga la tentación de reescribir todo el lienzo. Tendré que dibujar dos de un solo píxel uno al lado del otro en lugar de uno de dos píxeles).

No es necesario reescribir todo el lienzo. Lo principal es hacer un formato de círculo

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

y hacer las líneas normales.

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

Esto debería cubrir el 95% de sus necesidades

 

Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio

Cómo convertir todos los objetos en 1 objeto

Nikolai Semko, 2019.10.05 22:39

Efectivamente, Canvas es la solución.

Y Canvas es mucho más fácil de lo que parece a primera vista.

Aquí hay un ejemplo primitivo de un indicador (MQL5 & MQL4) con un objeto OBJ_BITMAP_LABEL en el que hay muchas ventanas.

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

¡Genial!

Realmente necesito esta función, y poder dibujar mis propios indicadores en estas miniventanas.

¿Por qué una ventana se esconde debajo de otra y la otra está encima, se puede arreglar?

Otra pregunta, si el mismo indicador se ejecuta en un gráfico diferente, ¿funcionará? ¿Los eventos no se solaparán como en la biblioteca estándar?

Y si ambas ventanas tienen las mismas coordenadas, ¿qué ventana se arrastrará con el ratón?

¿Es posible cambiar el tamaño de la ventana con el ratón?

 
Sergey Chalyshev:

¡Genial!

Realmente necesito esta función, y poder dibujar mis propios indicadores en estas miniventanas.

¿Por qué una ventana se esconde debajo de otra y la otra está encima, se puede arreglar?

Otra pregunta, si el mismo indicador se ejecuta en un gráfico diferente, ¿funcionará? ¿Los eventos no se solaparán como en la biblioteca estándar?

Y si ambas ventanas tienen las mismas coordenadas, ¿qué ventana se arrastrará con el ratón?

¿Es posible cambiar el tamaño de la ventana con el ratón?

Este ejemplo simplemente implementa la antigüedad de la ventana. En realidad, cuanto más pequeño es el índice en la matriz de la estructura win, más baja es la capa de la ventana virtual.

Puedes implementarlo de la manera que quieras. Por ejemplo, si "agarramos" una ventana, ésta se convierte en la más alta de la pantalla y del array.

También puede aplicar la transparencia. Te he mostrado cómo hacerlo aquí . (allí es necesario procesar cada piskel).

El otro gráfico también se puede ejecutar en el otro.
Si las coordenadas son iguales, se arrastra la que está encima.

con kanvas puedes hacer todo dentro de tu ventana y otras ventanas de MT.
Además, puede desprender una ventana de MT5 y enviarla a flotar libremente, incluso entre monitores. Puede verloaquí .

 
Nikolai Semko:

Este ejemplo simplemente implementa la antigüedad de la ventana. Esencialmente, cuanto menor sea el índice en la matriz de la estructura win, menor será la capa de la ventana virtual.

Puedes implementarlo de la manera que quieras. Por ejemplo, si se "agarra" una ventana, ésta se convierte en la más alta de la pantalla y del array.

También puede aplicar la transparencia. Te he mostrado cómo hacerlo aquí . (ahí tienes que procesar cada peekel).

También puedo ejecutarlo en otro gráfico.
Si las coordenadas son iguales, se arrastra la que está encima.

Con kanvas puedes hacer todo dentro de tu ventana y otras ventanas de MT.
Además, la ventana puede separarse de МТ5 y trasladarse a la zona de flotación libre entre monitores. Puede verlo aquí .

Un poco equivocado, probablemente no haya formulado la pregunta correctamente.

No es difícil organizar varias ventanas en un programa (script, indicador).

Quiero hacer un indicador que muestre los datos en su propia ventana pequeña en un gráfico. Esta ventana se puede colocar cómodamente en un gráfico, se puede arrastrar con el ratón, cambiar el tamaño de la ventana con el ratón (es deseable, pero se puede hacer de todos modos). Tenemos que ejecutar varios indicadores en el gráfico, cada uno con sus propios parámetros. Todavía no he descubierto cómo hacer que los eventos de diferentes indicadores no se superpongan y que el indicador reaccione adecuadamente a los eventos del ratón. No he decidido qué es mejor, si el lienzo o los objetos. No hay nada que funcione con la biblioteca estándar de Diálogo.

 
Sergey Chalyshev:

...Todavía no puedo averiguar cómo hacer que los eventos de diferentes indicadores no se superpongan...

La forma más fácil es una variable de cadena en la ventana de propiedades, añadirla a los nombres de los objetos gráficos.

 
Dmitry Fedoseev:

La forma más fácil es una variable de cadena en la ventana de propiedades, añadirla a los nombres de los objetos gráficos. ¿Mente dividida entre la verdad y la pertenencia?

Naturalmente, eso es lo que hago. El problema es arrastrar y soltar con el ratón. Si los objetos tienen las mismas coordenadas, uno está exactamente debajo del otro. Al hacer clic en ellos, ¿cuál reacciona?

De qué clubes hablas, yo no estoy apuntado a ningún club ni tengo intención de hacerlo ))

p.d. ¿puede mostrarme un ejemplo?

 
Sergey Chalyshev:

Naturalmente que sí. El problema es arrastrar y soltar con el ratón. Si los objetos tienen las mismas coordenadas, uno está exactamente debajo del otro. Al hacer clic en ellos, ¿cuál reacciona?

De qué clubes hablas, yo no estoy apuntado a ningún club ni tengo intención de hacerlo ))

p.d. ¿puede mostrarme un ejemplo?

Club equivocado, lo siento... He terminado con este club)).

Algún objeto responderá. Tal vez al activar un objeto cambie su orden Z para que esté más alto que todos los demás. Deberíamos probarlo.

 
Sergey Chalyshev:

Naturalmente que sí. El problema es arrastrar y soltar con el ratón. Si los objetos tienen las mismas coordenadas, uno está exactamente debajo del otro. Al hacer clic en ellos, ¿cuál reacciona?

De qué clubes hablas, yo no estoy apuntado a ningún club ni tengo intención de hacerlo ))

p.d. ¿puede mostrarme un ejemplo?

Por lo general, en una situación así, el objeto que se ha movido en último lugar debería reaccionar: está encima...

Razón de la queja: