Discusión sobre el artículo "Interfaces gráficas X: Control "Gráfico estándar" (build 4)"

 

Artículo publicado Interfaces gráficas X: Control "Gráfico estándar" (build 4):

En este artículo vamos a analizar el control de la interfaz gráfica como «Gráfico estándar». Nos permitirá crear los arrays de objetos-gráficos con posibilidad del desplazamiento horizontal sincronizado del gráfico. Aparte de eso, continuaremos optimizando el código de la librería para reducir el consumo de los recursos de CPU.

Supongamos que necesita otro modo de navegación por los objetos-gráficos, tal como ha sido implementado para el gráfico principal a través de los medios del terminal. Si pulsa la tecla «Space» o «Enter» en el terminal de trading MetaTrader, en la esquina inferior izquierda del gráfico aparecerá el campo de edición (véase la captura de pantalla a continuación). Es una especie de la línea de comandos en la que se puede introducir una fecha para ir rápidamente a ella en el gráfico. Además, se puede usar esta línea de comandos para cambiar el símbolo y el período de tiempo del gráfico. 

 Fig. 1. Línea de comandos del gráfico en la esquina inferior izquierda.

Fig. 1. Línea de comandos del gráfico en la esquina inferior izquierda.

Autor: Anatoli Kazharski

 
Если к этому прибавить ещё перемещение курсора мыши в области графика и активное взаимодействие с графическим интерфейсом MQL-приложения, то потребление вырастет ещё больше. Задача состоит в том, чтобы ограничить работу таймера движка библиотеки и исключить перерисовку графика по приходу события перемещения курсора мыши.

Para el desplazamiento OBJ_CHART, ¿por qué utilizar un temporizador? Y para la interacción con la interfaz - una pregunta similar. Parece que los eventos del ratón siempre debería ser suficiente.

 
fxsaber:

Para el desplazamiento OBJ_CHART, ¿por qué utilizar un temporizador? Y para la interacción con la interfaz - una pregunta similar. Después de todo, parece que los eventos del ratón deberían ser siempre suficientes.

Lo que has citado no se refiere a OBJ_CHART, sino al temporizador del motor de la librería en su conjunto. Es por eso que la solución de este problema se puso en una sección separada del artículo "Optimización del temporizador y manejador de eventos del motor de la biblioteca" como una adición al tema principal.

El temporizador se utiliza para cambiar el color de los controles al pasar el ratón por encima, así como para acelerar el desplazamiento de listas, tablas, calendario y valores en los campos de entrada.

//---

P.D. Y el desplazamiento del OBJ_CHART se realiza simplemente mediante el evento de movimiento del cursor del ratón - CHARTEVENT_MOUSE_MOVE. En el siguiente listado se muestra el código del manejador (versión abreviada) de eventos del elemento "Gráfico Estándar" (clase CStandardChart):

//+------------------------------------------------------------------+
//| Manejo de eventos|
//+------------------------------------------------------------------+
void CStandardChart::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Manejo del evento de movimiento del cursor
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      //--- Salir si el elemento está oculto
      if(!CElement::IsVisible())
         return;
      //--- Salir si está en modo de redimensionamiento de subventana
      if(CheckDragBorderWindowMode())
         return;
      //--- Salir si los números de subventana no coinciden
      if(CElement::m_subwin!=CElement::m_mouse.SubWindowNumber())
         return;
      //--- Salir si el formulario está bloqueado por otro elemento
      if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
         return;
      //--- Comprobación de enfoque
      CElement::MouseFocus(m_mouse.X()>X() && m_mouse.X()<X2() && m_mouse.Y()>Y() && m_mouse.Y()<Y2());
      //--- Si hay un foco
      if(CElement::MouseFocus())
         //--- Desplazamiento horizontal del gráfico
         HorizontalScroll();
      //--- Si no hay foco y se suelta el botón izquierdo del ratón
      else if(!m_mouse.LeftButtonState())
        {
         //--- Ocultar el puntero de desplazamiento horizontal
         m_x_scroll.Hide();
         //--- Desbloquear el formulario
         if(m_wnd.IdActivatedElement()==CElement::Id())
           {
            m_wnd.IsLocked(false);
            m_wnd.IdActivatedElement(WRONG_VALUE);
           }
        }
      //---
      return;
     }
//...
  }
 
Anatoli Kazharski:

El cambio de color temporizado de los elementos de control al pasar el ratón está arreglado

¿Por qué no se puede utilizar aquí el ratón?
 
fxsaber:
¿Por qué no puedo utilizar el ratón aquí?

Porque hay un cambio de color suave (el número de pasos lo fija el usuario).

Esto también se aplica al desplazamiento de las listas. Si utiliza el método tal y como está implementado en SB, tendrá un desplazamiento irregular.

 
Anatoli Kazharski:

Porque se proporciona un cambio de color suave (el número de pasos lo fija el usuario).

Esto también se aplica al desplazamiento de las listas. Si utiliza el método tal y como está implementado en SB, obtendrá un desplazamiento irregular.

¿Por qué no hay desplazamiento irregular para OBJ_CHART?
 
fxsaber:
¿Por qué entonces para OBJ_CHART desgarro no sale?

¿En qué caso (en relación con el Asesor Experto de prueba del artículo)?

  1. ¿En el caso de desplazamiento por el calendario?
  2. ¿ En caso de desplazamiento manual mediante el evento CHARTEVENT_MOUSE_MOVE en el manejador de eventos del elemento(CStandardChart) ?

Si es lo primero, entonces el desplazamiento por el gráfico está temporizado, al igual que el desplazamiento por el calendario. Es decir, la generación del evento de cambio de fecha del calendario(ON_CHANGE_DATE) se temporiza con un intervalo de 16 ms.

En el segundo, el desplazamiento se calcula y no siempre es igual a 1 compás. Así que sólo parece que el desplazamiento manual mediante el evento CHARTEVENT_MOUSE_MOVE es suave.

 
Anatoli Kazharski:

Si es el segundo, el desplazamiento se calcula y no siempre es igual a 1 barra. Así que parece que el desplazamiento manual por CHARTEVENT_MOUSE_MOVE evento es suave.

Entendido, ¡gracias!

 
Gracias por el artículo. Lo esperaba con impaciencia. No me ha decepcionado :)
 

Anatoly, dime cuál es la causa del error.

2016.10.19 03:09:04.993 TestTable (EURUSD,H1)   invalid pointer access in 'Scrolls.mqh' (698,10)

Todo funcionaba bien antes de esta actualización. Ahora al construir la tabla CTable aparece este error.

Por favor, dime dónde está mal - Ya he impreso cada línea - la interfaz se construye, pero después de algún lugar tropieza, y .... error.

Archivo con un ejemplo en el archivo.

Archivos adjuntos:
TestTable.zip  734 kb
 

Lo encontré.

Tome su ejemplo de MQL4\Experts\Article07\TestLibrary02\TestLibrary02.mq4.

A partir de su ejemplo anterior:

Hacer que el número de columnas y el número de columnas visibles el mismo , compilar, ejecutar, y obtener un error.

//+------------------------------------------------------------------+
//|| Crea una tabla|
//+------------------------------------------------------------------+
bool CProgram::CreateTable(void)
  {
//#define COLUMNS1_TOTAL (100)
//#define ROWS1_TOTAL (1000)
#define COLUMNS1_TOTAL (6)
#define ROWS1_TOTAL    (1000)
//--- Guardar el puntero al formulario
   m_table.WindowPointer(m_window1);
//--- Coordenadas
   int x=m_window1.X()+TABLE1_GAP_X;
   int y=m_window1.Y()+TABLE1_GAP_Y;
//--- Número de columnas y filas visibles
   int visible_columns_total =6;
   int visible_rows_total    =15;
//--- Establecer propiedades antes de la creación
   m_table.XSize(600);
   m_table.RowYSize(20);
   m_table.FixFirstRow(true);
   m_table.FixFirstColumn(true);
   m_table.LightsHover(true);
   m_table.SelectableRow(true);
   m_table.TextAlign(ALIGN_CENTER);
   m_table.HeadersColor(C'255,244,213');
   m_table.HeadersTextColor(clrBlack);
   m_table.CellColorHover(clrGold);
   m_table.TableSize(COLUMNS1_TOTAL,ROWS1_TOTAL);
   m_table.VisibleTableSize(visible_columns_total,visible_rows_total);
//--- Crear un control
   if(!m_table.CreateTable(m_chart_id,m_subwin,x,y))
      return(false);
//--- Rellenemos la tabla:
// La primera celda está vacía
   m_table.SetValue(0,0,"-");
//--- Títulos de las columnas
   for(int c=1; c<COLUMNS1_TOTAL; c++)
     {
      for(int r=0; r<1; r++)
         m_table.SetValue(c,r,"SYMBOL "+string(c));
     }
//--- Encabezados para las filas, método de alineación del texto - a la derecha
   for(int c=0; c<1; c++)
     {
      for(int r=1; r<ROWS1_TOTAL; r++)
        {
         m_table.SetValue(c,r,"PARAMETER "+string(r));
         m_table.TextAlign(c,r,ALIGN_RIGHT);
        }
     }
//--- Datos y formato de la tabla (color de fondo y color de las celdas)
   for(int c=1; c<COLUMNS1_TOTAL; c++)
     {
      for(int r=1; r<ROWS1_TOTAL; r++)
        {
         m_table.SetValue(c,r,string(c)+":"+string(r));
         m_table.TextColor(c,r,(c%2==0)? clrRed : clrRoyalBlue);
         m_table.CellColor(c,r,(r%2==0)? clrWhiteSmoke : clrWhite);
        }
     }
//--- Actualizar la tabla para mostrar los cambios
   m_table.UpdateTable();
//--- Añade el objeto al array común de grupos de objetos
   CWndContainer::AddToElementsArray(0,m_table);
   return(true);
  }
//+------------------------------------------------------------------+
En realidad, si usted hace el número de filas y el número de filas visibles el mismo, se obtiene el mismo error.