Discussão do artigo "Interfaces Gráficas X: O Controle Gráfico Padrão (build 4)"

 

Novo artigo Interfaces Gráficas X: O Controle Gráfico Padrão (build 4) foi publicado:

Desta vez, nós vamos discutir o controle gráfico padrão. Ele permitirá criar arrays de objetos gráficos com a possibilidade de sincronizar o deslocamento horizontal. Além disso, nós continuaremos a otimizar o código da biblioteca para reduzir o consumo de recursos do CPU.

A imagem abaixo mostra o resultado final. Neste exemplo, os dados do objeto gráfico pode ser deslocado horizontalmente, de forma semelhante como ele foi implementado ao gráfico principal. Além disso, a navegação entre objetos gráficos funciona através do calendário, incluindo o avanço rápido das datas.

 Fig. 2. Teste do controle Gráfico Padrão.

Fig. 2. Teste do controle Gráfico Padrão.

Autor: Anatoli Kazharski

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

Para a rolagem do OBJ_CHART, por que usar um cronômetro? E para a interação com a interface - uma pergunta semelhante. Parece que os eventos do mouse sempre devem ser suficientes.

 
fxsaber:

Para a rolagem do OBJ_CHART, por que usar um cronômetro? E para a interação com a interface - uma pergunta semelhante. Afinal de contas, parece que os eventos do mouse sempre devem ser suficientes.

O que você citou não se refere ao OBJ_CHART, mas ao timer do mecanismo da biblioteca como um todo. É por isso que a solução desse problema foi colocada em uma seção separada do artigo "Otimização do timer e do manipulador de eventos do mecanismo da biblioteca" como um acréscimo ao tópico principal.

O timer é usado para alterar a cor dos controles ao passar o mouse, bem como para acelerar a rolagem de listas, tabelas, calendário e valores em campos de entrada.

//---

P.S. E a rolagem do OBJ_CHART é realizada apenas pelo evento de movimento do cursor do mouse - CHARTEVENT_MOUSE_MOVE. Na listagem abaixo está o código do manipulador (versão abreviada) dos eventos do elemento "Standard Chart" (classe CStandardChart):

//+------------------------------------------------------------------+
//| Tratamento de eventos|
//+------------------------------------------------------------------+
void CStandardChart::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Tratamento do evento de movimento do cursor
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      //--- Sair se o item estiver oculto
      if(!CElement::IsVisible())
         return;
      //--- Sair se estiver no modo de redimensionamento de subjanela
      if(CheckDragBorderWindowMode())
         return;
      //--- Sair se os números das subjanelas não corresponderem
      if(CElement::m_subwin!=CElement::m_mouse.SubWindowNumber())
         return;
      //--- Sair se o formulário for bloqueado por outro elemento
      if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
         return;
      //--- Verificação de foco
      CElement::MouseFocus(m_mouse.X()>X() && m_mouse.X()<X2() && m_mouse.Y()>Y() && m_mouse.Y()<Y2());
      //--- Se houver um foco
      if(CElement::MouseFocus())
         //--- Rolagem horizontal do gráfico
         HorizontalScroll();
      //--- Se não houver foco e o botão esquerdo do mouse for liberado
      else if(!m_mouse.LeftButtonState())
        {
         //--- Ocultar o ponteiro de rolagem horizontal
         m_x_scroll.Hide();
         //--- Desbloquear o formulário
         if(m_wnd.IdActivatedElement()==CElement::Id())
           {
            m_wnd.IsLocked(false);
            m_wnd.IdActivatedElement(WRONG_VALUE);
           }
        }
      //---
      return;
     }
//...
  }
 
Anatoli Kazharski:

A mudança de cor baseada em temporizador dos elementos de controle ao passar o mouse é organizada

Por que o mouse não poderia ser usado aqui?
 
fxsaber:
Por que não posso usar o mouse aqui?

Porque há uma mudança de cor suave (o número de etapas é definido pelo usuário).

Isso também se aplica à rolagem de listas. Se você usar o método como está implementado no SB, terá uma rolagem irregular.

 
Anatoli Kazharski:

Porque é fornecida uma mudança de cor suave (o número de etapas é definido pelo usuário).

Isso também se aplica à rolagem de listas. Se você usar o método como está implementado no SB, terá uma rolagem irregular (irregular).

Por que não há rolagem irregular para OBJ_CHART?
 
fxsaber:
Por que então o rompimento do OBJ_CHART não ocorre?

Em que caso (em relação ao Expert Advisor de teste do artigo)?

  1. No caso em que a rolagem pelo calendário é realizada?
  2. No caso de rolagem manual pelo evento CHARTEVENT_MOUSE_MOVE no manipulador de eventos do item(CStandardChart) ?

Se for o primeiro caso, então a rolagem do gráfico é cronometrada, assim como a rolagem do calendário. Ou seja, a geração do evento de mudança de data do calendário(ON_CHANGE_DATE) é cronometrada em um intervalo de 16 ms.

Se for o segundo, o deslocamento é calculado e nem sempre é igual a 1 barra. Portanto, parece que a rolagem manual pelo evento CHARTEVENT_MOUSE_MOVE é suave.

 
Anatoli Kazharski:

Se for o segundo, o deslocamento é calculado e nem sempre é igual a 1 barra. Portanto, parece que a rolagem manual pelo evento CHARTEVENT_MOUSE_MOVE é suave.

Entendi, obrigado!

 
Obrigado pelo artigo. Estava esperando ansiosamente por ele. Não fiquei desapontado :)
 

Anatoly, diga-me qual é a causa do erro

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

Tudo funcionava bem antes dessa atualização. Agora, ao criar a tabela CTable, esse erro aparece.

Por favor, diga-me onde está o erro - já imprimi todas as linhas - a interface é criada, mas depois de algum tempo ela tropeça e .... erro.

Arquivo com um exemplo no arquivo.

Arquivos anexados:
TestTable.zip  734 kb
 

Encontrei.

Pegue seu exemplo de MQL4\Experts\Article07\TestLibrary02\TestLibrary02.mq4.

Do seu exemplo acima:

Faça com que o número de colunas e o número de colunas visíveis sejam os mesmos , compile, execute e receba um erro.

//+------------------------------------------------------------------+
//|| Cria uma tabela|
//+------------------------------------------------------------------+
bool CProgram::CreateTable(void)
  {
//#definir COLUMNS1_TOTAL (100)
//#definir ROWS1_TOTAL (1000)
#define COLUMNS1_TOTAL (6)
#define ROWS1_TOTAL    (1000)
//--- Salvar o ponteiro no formulário
   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 colunas e linhas visíveis
   int visible_columns_total =6;
   int visible_rows_total    =15;
//--- Definir propriedades antes da criação
   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);
//--- Criar um controle
   if(!m_table.CreateTable(m_chart_id,m_subwin,x,y))
      return(false);
//--- Vamos preencher a tabela:
// A primeira célula está vazia
   m_table.SetValue(0,0,"-");
//--- Títulos para colunas
   for(int c=1; c<COLUMNS1_TOTAL; c++)
     {
      for(int r=0; r<1; r++)
         m_table.SetValue(c,r,"SYMBOL "+string(c));
     }
//--- Cabeçalhos para linhas, método de alinhamento de texto - à direita
   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);
        }
     }
//--- Formatação de dados e tabelas (cor de fundo e cor da célula)
   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);
        }
     }
//--- Atualize a tabela para mostrar as alterações
   m_table.UpdateTable();
//--- Adicione o objeto à matriz comum de grupos de objetos
   CWndContainer::AddToElementsArray(0,m_table);
   return(true);
  }
//+------------------------------------------------------------------+
Na verdade, se o número de linhas e o número de linhas visíveis forem iguais, você receberá o mesmo erro.