Discusión sobre el artículo "Cómo crear un panel informativo para mostrar datos en indicadores y asesores" - página 4

 
Denis Kirichenko #:
Mover(int x, int y)

Hay un error en alguna parte. Necesitas imprimir (o mirar en el depurador, pero a menudo no funciona) los valores de coordenadas y tamaño.

Aquí está la lógica en los comentarios:

   //--- Si la altura del panel no es mayor que la altura de la ventana
   if(!this.m_higher_wnd)
     {
      if(y+h>this.m_chart_h-2)
         y=this.m_chart_h-h-2;
      if(y<1)
         y=1;
     }
   //--- Si el panel de altura no está dentro del tamaño de la ventana de altura
   else
     {
      //--- Mantenga el panel por debajo del borde superior de la ventana con un espacio de 1 píxel
      if(y>1)
         y=1;
      //--- Evita que el panel caiga por debajo del borde inferior de la ventana con un espacio de 1 pixel
      if(y<this.m_chart_h-h-2)
         y=this.m_chart_h-h-2;
     }
 
Denis Kirichenko #:
Al intentar mover el panel después de cambiar el tamaño del gráfico, corrige constantemente las coordenadas y no deja mover la ventana del panel libremente...

Lo más probable es que el valor de la variable this.m_higher_wnd no sea relevante en el método Move(). Estos valores se establecen en el manejador de eventos:

//+------------------------------------------------------------------+
//| Manejador de eventos|
//+------------------------------------------------------------------+
void CDashboard::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Si se crea un objeto gráfico
   if(id==CHARTEVENT_OBJECT_CREATE)
     {
      this.BringToTop();
      ::ObjectSetInteger(this.m_chart_id,sparam,OBJPROP_SELECTED,true);
     }
//--- Si se cambia el horario
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      //--- Obtener el número de la subventana del gráfico, si no es la ventana principal (el número puede cambiar al borrar la ventana de cualquier indicador)
      if(this.m_wnd!=0)
         this.m_wnd=this.GetSubWindow();
      //--- Obtener las nuevas dimensiones del gráfico
      int w=(int)::ChartGetInteger(this.m_chart_id,CHART_WIDTH_IN_PIXELS,this.m_wnd);
      int h=(int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS,this.m_wnd);
      //--- Determinar si el tamaño del panel está fuera de la ventana del gráfico
      this.m_higher_wnd=this.HigherWnd();
      this.m_wider_wnd=this.WiderWnd();
      //--- Si la altura del gráfico ha cambiado - ajuste la posición vertical del panel
      if(this.m_chart_h!=h)
        {
         this.m_chart_h=h;
         int y=this.m_y;
         if(this.m_y+this.m_h>h-1)
            y=h-this.m_h-1;
         if(y<1)
            y=1;
         this.Move(this.m_x,y);
        }
      //--- Si la anchura del gráfico ha cambiado - ajuste la posición horizontal del panel
      if(this.m_chart_w!=w)
        {
         this.m_chart_w=w;
         int x=this.m_x;
         if(this.m_x+this.m_w>w-1)
            x=w-this.m_w-1;
         if(x<1)
            x=1;
         this.Move(x,this.m_y);
        }
     }

Es muy posible que en algún lugar de aquí no se establezcan correctamente las banderas de sobredimensionamiento cuando se expande la ventana del gráfico.

Si escribe estas líneas

this.m_higher_wnd=this.HigherWnd();
this.m_wider_wnd=this.WiderWnd();

al principio del método Move() - para forzar el establecimiento de los valores correctos en cada movimiento del ratón, ¿desaparecerá el error? Si lo hace, significa que el asunto está en los valores de estas variables, y que necesitas mirar en el manejador de eventos para ver por qué no obtienen sus valores cuando se expande la ventana. Bien, si todo es normal allí, entonces necesitas imprimir el método Move() para encontrar el error.

 

El error ha desaparecido. He hecho estos cambios en el método CDashboard::OnChartEvent():


//--- Si se cambia el horario
   if(id == CHARTEVENT_CHART_CHANGE)
     {
      //--- Obtener el número de la subventana del gráfico, si no es la ventana principal (el número puede cambiar al borrar la ventana de cualquier indicador)
      if(m_wnd != 0)
         m_wnd = GetSubWindow();
      //
      long value;
      // restablecer el valor de error
      ::ResetLastError();
      // obtener el valor de la propiedad
      if(!::ChartGetInteger(m_chart_id, CHART_BRING_TO_TOP, m_wnd, value))
        {
         //--- envía el mensaje de error al registro de "Expertos".
         Print(__FUNCTION__ + ", Error Code = ", ::GetLastError());
         return;
        }
      // si no muestra el gráfico encima de todos los demás - exit
      if(value == 0)
         return;
      //--- Obtener las nuevas dimensiones del gráfico
      int w = (int)::ChartGetInteger(m_chart_id, CHART_WIDTH_IN_PIXELS, m_wnd);
      int h = (int)::ChartGetInteger(m_chart_id, CHART_HEIGHT_IN_PIXELS, m_wnd);
      //--- Determinar si el tamaño del panel está fuera de la ventana del gráfico
      //m_higher_wnd = HigherWnd();
      //m_wider_wnd = WiderWnd();
      //--- Si la altura del gráfico ha cambiado - ajuste la posición vertical del panel
      if(m_chart_h != h)
        {
         m_chart_h = h;
         m_higher_wnd = HigherWnd(); // añadido
         int y = m_y;
         if(m_y + m_h > h - 1)
            y = h - m_h - 1;
         if(y < 1)
            y = 1;
         Move(m_x, y);
        }
      //--- Si la anchura del gráfico ha cambiado - ajuste la posición horizontal del panel
      if(m_chart_w != w)
        {
         m_chart_w = w; 
         m_wider_wnd = WiderWnd(); // añadido
         int x = m_x;
         if(m_x + m_w > w - 1)
            x = w - m_w - 1;
         if(x < 1)
            x = 1;
         Move(x, m_y);
        }
     }


Para no cargar constantemente el método CDashboard:: Move(), he añadido la comprobación de banderas de sobredimensionamiento en aquellos bloques en los que se modifica directamente la anchura y altura de la ventana del gráfico.


 
Denis Kirichenko #:

El error ha desaparecido. En el método CDashboard::OnChartEvent() he hecho estos cambios:

Para no cargar constantemente el método CDashboard:: Move(), he añadido la comprobación de banderas de sobredimensionamiento en aquellos bloques en los que se modifica directamente la anchura y altura de la ventana del gráfico.

Gracias. Lo pondré.