English Русский 中文 Español Deutsch 日本語 한국어 Français Italiano Türkçe
Crie seus próprios painéis gráficos no MQL5

Crie seus próprios painéis gráficos no MQL5

MetaTrader 5Exemplos | 21 janeiro 2014, 13:26
7 452 0
MetaQuotes
MetaQuotes

Introdução

Há um novo conjunto de classes disponíveis na Biblioteca Padrão. Essas classes são projetadas para o desenvolvimento independente de diálogos de controle e painéis de exibição em programas MQL5.

O novo conjunto de classes permite que todos criem componentes de interface personalizados usando o modelo ativado por eventos como o modelo subjacente. Tudo é baseado em objetos gráficos incorporados e eventos do Terminal.

As classes desenvolvidas podem ser usadas das seguintes formas:
  1. Exibir painel em uma subjanela do gráfico separada.
  2. Painel de controle para um Consultor Especialista;
  3. Painel de controle de exibição personalizada.

Este artigo irá demonstrar como é fácil criar seus próprios painéis de exibição em um gráfico sub-janela separado usando as classes da Biblioteca Padrão.


O que a Biblioteca Padrão tem a oferecer?

A biblioteca padrão fornece ao desenvolvedor os seguintes controles prontos para uso:

1. Controles simples:

Controle Aplicação Implementação com base no objeto incorporado Arquivo da Biblioteca Padrão

Botão com texto

Garantir a interação entre o mouse e o programa MQL

"Botão"

Botão com imagem

Garantir a interação entre o mouse e o programa MQL

"Rótulo gráfico"

Editar

Entrada ou exibição de informações de texto (no modo "Apenas leitura")

"Editar"

Legenda

Exibição de informações de texto auxiliar

"Rótulo do texto"

Painel

Controle auxiliar (agrupamento visual de controles)

"Rótulo em retângulo"

Imagem

Controle decorativo

"Rótulo gráfico"



2. Controles complexos:


Controle Aplicação Implementação com base nos controles Arquivo da Biblioteca Padrão

Lista

Visualização de uma lista

"Retângulo", "Botão com imagem" e "Editar"

Campo com uma lista suspensa

Seleção a partir de uma lista suspensa

"Editar", "Botão com imagem" e "Listar"

Campo incremento/redução

Enumeração de valores

"Editar"e "Botão com imagem"

Botão de rádio

Interruptor "Botão com imagem" e "Legenda"
Grupo de botão de rádio Edição de campos do tipo enum "Retângulo" e "Botão de rádio"

Caixa de opção

Opção de seleção

"Botão com imagem" e "Legenda"

Grupo de caixa de opção

Edição de um conjunto de sinalizadores

"Retângulo" e "caixa de opção"
Diálogo Formulário de diálogo "Retângulo", "Botão com imagem" e "Editar"



Criando um Painel de Visualização

Vamos primeiro definir os termos. O painel de exibição é um termo que se usa para descrever uma janela separada de exibição personalizada que não tem buffer de desenho. Tal painel simplesmente exibe a informação necessária usando os objetos gráficos embutidos no Terminal. A informação pode ser exibida:

  • numericamente,
  • como texto,
  • como cor,
  • etc.

Vamos ter uma visão detalhada de todos os passos necessários e criar um painel gráfico da seguinte forma:



A fim de criar um painel de visualização, vamos precisar de dois arquivos:

  1. O arquivo incluído contendo a descrição da classe painel.
  2. O arquivo de código fonte indicador

Modelos destes arquivos podem ser obtidos usando o MQL5 Wizard. No diretório de indicadores (MQL5\Indicators), crie uma pasta separada MyIndicators e uma subpasta MyPanel. O processo de criação de pastas não será tratado aqui, pois ele é bem descrito em Ajuda.


Descrição de classe

A pasta de trabalho já foi criada. Vamos agora encontrá-la na janela "Navegador" e clicar na mesma com o botão direito do mouse. Selecione a opção "Novo arquivo" no menu exibido. Selecione a opção "Nova classe" nas opções apresentadas pelo MQL5 Wizard e clique em "Próximo >". Complete o diálogo de descrição da classe como mostrado abaixo:

Criação de nova classe em MQL Wizard

Clique em "Finalizar". Como resultado, temos o seguinte código:

//+------------------------------------------------------------------+
//|                                                  PanelDialog.mqh |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CPanelDialog : public CAppDialog
  {
private:

public:
                     CPanelDialog();
                    ~CPanelDialog();
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CPanelDialog::CPanelDialog()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CPanelDialog::~CPanelDialog()
  {
  }
//+------------------------------------------------------------------+


Adicione o arquivo incluído da Biblioteca Padrão com a descrição da classe base CAppDialog e comentários. 

//+------------------------------------------------------------------+
//|                                                  PanelDialog.mqh |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
//+------------------------------------------------------------------+
//| CPanelDialog class                                               |
//| Function: main application dialog                                |
//+------------------------------------------------------------------+
class CPanelDialog : public CAppDialog
  {
private:

public:
                     CPanelDialog(void);
                    ~CPanelDialog(void);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CPanelDialog::CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CPanelDialog::~CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+

Agora, temos a descrição da classe que nos permitirá usar uma caixa de diálogo em seu indicador. Nosso diálogo está atualmente vazio, mas iremos adicionar controles à ele um pouco mais tarde. No momento, vamos avançar para o indicador.


O código-fonte indicador

O indicador também será criado usando o MQL5 Wizard. Nossas ações serão semelhantes às exigidas quando se escreve a descrição de classe. Há apenas uma diferença - nós selecionamos "Indicador personalizado" nas opções dadas pelo MQL5 Wizard. A fim de criar um indicador, três diálogos devem ser concluídos.

O primeiro requer especificação do nome do indicador:

Criação de novo indicador em MQL Wizard


No segundo diálogo, marque "OnChartEvent" (obrigatório) e "OnTimer":

Definindo processadores de eventos para o indicador personalizado em MQL Wizard



Marque "Indicador em janela separada" (obrigatório) no terceiro diálogo:

Definindo propriedades de desenho do indicador em MQL Wizard


E clique "Finalizar". O código produzido é como segue:

//+------------------------------------------------------------------+
//|                                               PanelIndicator.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
              const int prev_calculated,
              const int begin,
              const double &price[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                const long &lparam,
                const double &dparam,
                const string &sparam)
  {
//---
   
  }
//+------------------------------------------------------------------+


Nosso modelo pode agora ser completado adicionando:

  • descrições ausentes de propriedades do indicador;
  • incluir arquivo contendo a descrição de classe do nosso diálogo;
  • uma variável global - o objeto de classe do nosso diálogo;
  • código para criar o diálogo, iniciar o aplicativo e criar o cronômetro para o corpo da função OnInit ();
  • Função OnDeinit () contém um código que destrói o diálogo e mata o cronômetro;
  • Função OnChartEvent(...) para o código de chamada do processador de eventos;
  • comentários.

Temos o indicador pronto para uso:

//+------------------------------------------------------------------+
//|                                               PanelIndicator.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_plots               0
#property indicator_buffers             0
#property indicator_minimum             0.0
#property indicator_maximum             0.0
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "PanelDialog.mqh"
//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
CPanelDialog ExtDialog;
//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- creating the application dialog
   if(!ExtDialog.Create(0,"Panel Indicator",0,0,0,0,130))
     return(-1);
//--- starting the application
   if(!ExtDialog.Run())
     return(-2);
//--- creating the timer
   EventSetTimer(1);
//--- success
   return(0);
  }
//+------------------------------------------------------------------+
//| Deinitialization                                                 |
//+------------------------------------------------------------------+
int OnDeinit()
  {
//--- destroying the dialog
   ExtDialog.Destroy();
//--- killing the timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Iteration                                                        |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
              const int prev_calculated,
              const int begin,
              const double &price[])
  {  
//--- returning the prev_calculated value for the next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer event handler                                              |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
  }
//+------------------------------------------------------------------+
//| Chart event handler                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                const long &lparam,
                const double &dparam,
                const string &sparam)
  {
//--- handling the event
   ExtDialog.ChartEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+


O indicador no formulário acima não mostra nada ainda. Quando compilado e retirado do Navegador no gráfico, ele será exibido como um diálogo vazio em uma janela separada.

Apesar de o diálogo estar vazio, nosso indicador já adquiriu certas características:

  • a altura sub janela foi ajustada para a altura de diálogo pelo indicador durante a criação;
  • a largura da janela é sempre igual à largura do gráfico;
  • o indicador pode minimizar e maximizar sua própria subjanela.

Deixe-o Exibir

Para que o nosso painel inicie a exibição de qualquer informação, devemos decidir sobre as respostas a três perguntas:

  1. Que tipo de informação queremos exibir?
  2. Quais elementos adicionais de exibição e/ou controles são necessários ser posicionados em nosso diálogo?
  3. Como esses controles/elementos adicionais irão interagir?

Outro fator importante é que o nosso diálogo deve ser visualmente atraente e fácil de usar. Isso não afeta a funcionalidade do diálogo, mas mostra que nos preocupamos com os usuários do futuro programa MQL5.

Passo 1. Que tipo de informação queremos exibir?

Uma vez que o artigo serve como uma ferramenta de aprendizagem, não vamos perder tempo com a usabilidade do indicador. A cor irá ser apresentada como uma função de três parâmetros. Não iremos complicar demais os parâmetros - estes serão níveis "vermelhos", "verdes" e "azuis".

Os valores do parâmetro serão definidos da seguinte forma:

  • O valor do nível "vermelho" será definido na faixa de 0 a 255 mudando de forma aleatória a cada evento Calcular;
  • O valor do nível "verde" será definido na faixa de 0 a 255, mudando de forma aleatória a cada evento Cronômetro;
  • O valor do nível "azul" será definido na faixa de 0 a 255 e vai ser alterado manualmente por meio de um controle especial.

Aliás, os valores destes níveis serão também apresentados no nosso indicador.


Passo 2. Quais controles adicionais serão exigidos?

  1. Cor será exibida usando o controle do "Painel".
  2. Os níveis "vermelho" e "verde" serão exibidos usando o controle "Editar" no modo "Somente Leitura".
  3. O nível "azul" será gerenciado pelo controle "Editar Giro". O mesmo controle vai ajudar a exibir o valor do nível.
  4. Tanto os controles "Editar" e "Editar Giro" serão reforçados com legendas explicativas, por meio do controle "Legenda".

Adicione os arquivos de inclusão a partir da Biblioteca Padrão, bem como os controles necessários e as variáveis que armazenam os valores de parâmetro para a descrição da classe tendo fornecido comentários.

Teremos:

//+------------------------------------------------------------------+
//|                                                  PanelDialog.mqh |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\Panel.mqh>
#include <Controls\Edit.mqh>
#include <Controls\Label.mqh>
#include <Controls\SpinEdit.mqh>
//+------------------------------------------------------------------+
//| CPanelDialog class                                               |
//| Function: main application dialog                                |
//+------------------------------------------------------------------+
class CPanelDialog : public CAppDialog
  {
private:
   //--- additional controls
   CPanel            m_color;                         // object for displaying color
   CLabel            m_label_red;                     // "red" level caption object
   CEdit             m_field_red;                     // "red" value display object
   CLabel            m_label_green;                   // "green" level caption object
   CEdit             m_field_green;                   // "green" value display object
   CLabel            m_label_blue;                    // "blue" level caption object
   CSpinEdit         m_edit_blue;                     // "blue" value control object
   //--- parameter values
   int               m_red;                           // "red" value
   int               m_green;                         // "green" value
   int               m_blue;                          // "blue" value

public:
                     CPanelDialog(void);
                    ~CPanelDialog(void);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CPanelDialog::CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CPanelDialog::~CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+


Passo 3. Como esses controles de diálogo adicionais irão interagir?
O princípio de interação entre os controles de diálogo será muito simples - O diálogo deve exibir mudanças em qualquer parâmetro (níveis "vermelho", "verde" e "azul")". A implementação de algoritmos de interação será abordada mais tarde, pois agora é hora de começar a criar o diálogo.


Algumas palavras sobre apelo visual.

Antes de avançarmos para a criação do diálogo, vamos ter uma introspecção rápida em apelo visual. Ou melhor dizendo, um arranjo fácil de usar e (possível) futuro rearranjo de controles de diálogo. Constantes nomeadas (#define) servem melhor esse propósito.

Existem algumas vantagens oferecidas pelas constantes nomeadas predefinidas:

  • certos valores numéricos usados​em casos específicos não tem que ser lembrados. Os nomes constantemente selecionados com precisão irão proporcionar um acesso rápido a eles através da "Listar nomes de forma automática";
  • quando os valores constantes são adicionalmente modificados, numerosas inclusões de valores numéricos não têm de ser procuradas e substituídas. É suficiente para mudar apenas a descrição constante.

Sugere-se a utilização das seguintes constantes:

//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
//--- indents and spacing
#define INDENT_LEFT                         (11)      // left indent (including the border width)
#define INDENT_TOP                          (11)      // top indent (including the border width)
#define INDENT_RIGHT                        (11)      // right indent (including the border width)
#define INDENT_BOTTOM                       (11)      // bottom indent (including the border width)
#define CONTROLS_GAP_X                      (10)      // spacing along the X-axis
#define CONTROLS_GAP_Y                      (10)      // spacing along the Y-axis
//--- for labels
#define LABEL_WIDTH                         (50)      // size along the X-axis
//--- for edits
#define EDIT_WIDTH                          (50)      // size along the Y-axis
#define EDIT_HEIGHT                         (20)      // size along the Y-axis
//--- for base colors (RGB)
#define BASE_COLOR_MIN                      (0)       // minimum value of the color component
#define BASE_COLOR_MAX                      (255)     // maximum value of the color component


Preenchendo o Painel de Exibição

Nós anteriormente criamos a classe painel de exibição; agora, a fim de alcançar a funcionalidade necessária, precisamos fazer o seguinte:

1. Redefinir o Criar (...) método da classe precursora Originalmente, o nosso método aparece como segue:

//+------------------------------------------------------------------+
//| Creation                                                         |
//+------------------------------------------------------------------+
bool CPanelDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//--- calling the method of the parent class
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))  return(false);
//--- additional controls shall be created here

//--- success
   return(true);
  }


2. Criar controles adicionais.

Uma divagação lírica leve. Códigos para a criação de todos os controles adicionais podem evidentemente ser inseridos diretamente no Criar (...) corpo do método, mas desta forma corremos o risco de obter uma grande "massa" ilegível.

Vamos, portanto, dividir o processo de criação em partes independentes representadas por métodos:

  • bool CreateColor(void) - criação do painel de cores,
  • bool CreateRed(void) - criando o elemento de exibição "Vermelho" com legenda explicativa,
  • bool CreateGreen(void) - criando o elemento de exibição "Verde" com legenda explicativa,
  • bool CreateBlue(void) - criando o controle "Azul" com legenda explicativa.

Estes métodos são chamados sequencialmente a partir do método Criar (...):

//+------------------------------------------------------------------+
//| Creation                                                         |
//+------------------------------------------------------------------+
bool CPanelDialog::Create(const long chart,const string name,const int subwin,
                             const int x1,const int y1,const int x2,const int y2)
  {
//--- calling the parent class method
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2)) return(false);

//--- creating additional elements
   if(!CreateColor()) return(false);
   if(!CreateRed())   return(false);
   if(!CreateGreen()) return(false);
   if(!CreateBlue())  return(false);
//--- success
   return(true);
  }


Criação de Controles

Nós não iremos rever a criação de cada controle adicional, mas teremos um olhar detalhado sobre o método bool CreateBlue(void).

Trata-se da seguinte forma:

//+------------------------------------------------------------------+
//| Creating the "Blue" control with explanatory caption             |
//+------------------------------------------------------------------+
bool CPanelDialog::CreateBlue(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+2*(EDIT_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+EDIT_WIDTH;
   int y2=y1+EDIT_HEIGHT;
//--- creating the caption
   if(!m_label_blue.Create(m_chart_id,m_name+"LabelBlue",m_subwin,x1,y1+1,x2,y2)) return(false);
   if(!m_label_blue.Text("Blue")) return(false);
   if(!Add(m_label_blue)) return(false);
//--- adjusting coordinates
   x1+=LABEL_WIDTH+CONTROLS_GAP_X;
   x2=x1+EDIT_WIDTH;
//--- creating the control
   if(!m_edit_blue.Create(m_chart_id,m_name+"Blue",m_subwin,x1,y1,x2,y2)) return(false);
   if(!Add(m_edit_blue)) return(false);
   m_edit_blue.MinValue(BASE_COLOR_MIN);
   m_edit_blue.MaxValue(BASE_COLOR_MAX);
   m_edit_blue.Value(m_blue);
//--- success
   return(true);
  }

Existem duas nuanças:

  1. O controle é criado com as coordenadas relativas, ou seja, o deslocamento é definido em relação ao canto superior esquerdo do recipiente (elemento complexo) para que o controle seja adicionado após a criação.
  2. Após a criação, é necessário adicionar o controle para um recipiente usando o método Adicionar(...). No nosso caso, o diálogo serve como recipiente.


Alterando os Parâmetros

Adicione o método nulo SetColor (nulo) para mudar a cor do painel de cor;

A fim de poder alterar os níveis de parâmetros (as cores de base) exteriormente, nós vamos adicionar três métodos comuns:

  • void SetRed(const int value) - altera o nível "vermelho" e mostra a mudança no indicador,
  • void SetGreen(const int value) - altera o nível "verde" e mostra a mudança no indicador,
  • void SetBlue(const int value) - altera o nível "azul" e mostra a mudança no indicador.

A frase "mostra a mudança no indicador" significa que o novo valor do nível de cor de base é mostrado na forma numérica no painel de controle correspondente e o painel de cor muda sua cor.

Abaixo, encontra-se um código de um dos métodos para servir como exemplo:

//+------------------------------------------------------------------+
//| Setting the "Red" value                                          |
//+------------------------------------------------------------------+
void CPanelDialog::SetRed(const int value)
  {
//--- checking
   if(value<0 || value>255) return;
//--- saving
   m_red=value;
//--- setting
   m_field_red.Text(IntegerToString(value));
//--- setting the panel color
   SetColor();
  }

Conforme combinado anteriormente:

  • O valor do nível "vermelho" mudará de forma aleatória em cada evento Calcular;
  • O valor do nível "verde" mudará de forma aleatória em cada evento cronômetro;

Vamos adicionar o código correspondente no indicador original:

//+------------------------------------------------------------------+
//|                                               PanelIndicator.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_plots               0
#property indicator_buffers             0
#property indicator_minimum             0.0
#property indicator_maximum             0.0
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "PanelDialog.mqh"
//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
CPanelDialog ExtDialog;
//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- creating the application dialog
   if(!ExtDialog.Create(0,"Panel Indicator",0,0,0,0,130))
      return(-1);
//--- starting the application
   if(!ExtDialog.Run())
      return(-2);
//--- creating the timer
   EventSetTimer(1);
//--- success
   return(0);
  }
//+------------------------------------------------------------------+
//| Deinitialization                                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroying the dialog
   ExtDialog.Destroy();
//--- killing the timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Iteration                                                        |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//--- changing the dialog property
   ExtDialog.SetRed(MathRand()%256);
//--- returning the prev_calculated value for the next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer event handler                                              |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- changing the dialog property
   ExtDialog.SetGreen(MathRand()%256);
  }
//+------------------------------------------------------------------+
//| Chart event handler                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- handling the event
   ExtDialog.ChartEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+


Manuseio de Eventos

Toda a interação entre o diálogo e o Terminal, bem como a interação entre os controles de diálogo são baseados no mecanismo de evento. Nós não vamos revisar suas funções mas simplesmente usá-las.

Os eventos podem ser convencionalmente divididos em dois grupos:

  • Eventos internos que são manipulados ignorando a fila de eventos do Terminal;
  • Eventos externos que são manipulados através da fila de eventos do Terminal.

Nós vamos lidar com ambos os tipos de eventos.

Entre os eventos internos, apenas os eventos de redimensionamento do diálogo necessitam ser manipulados. Para esta finalidade, recarregue o método da classe precursora OnResize (). Nosso método será simples porque não há nenhuma alteração na altura de diálogo; se a largura do diálogo muda, só temos que modificar a largura do painel de cores:

//+------------------------------------------------------------------+
//| Resize handler                                                   |
//+------------------------------------------------------------------+
bool CPanelDialog::OnResize(void)
  {
//--- calling the parent class method
   if(!CAppDialog::OnResize()) return(false);
//--- changing the color panel width
   m_color.Width(ClientAreaWidth()-(INDENT_RIGHT+LABEL_WIDTH+CONTROLS_GAP_X+EDIT_WIDTH+CONTROLS_GAP_X+INDENT_LEFT));
//--- success
   return(true);
  }

A lista de eventos externos também será limitada a um artigo - o evento de alterar o nível "azul". Os requisitos para o manipulador de eventos externos são mínimos: o manipulador deve ser o método de classe sem parâmetros do tipo nulo.

Vamos descrever o manipulador deste evento:

//+------------------------------------------------------------------+
//| Handler of the event of changing the "blue" level                |
//+------------------------------------------------------------------+
void CPanelDialog::OnChangeBlue(void)
  {
//--- saving
   m_blue=m_edit_blue.Value();
//--- setting the panel color
   SetColor();
  }

Como pode ser visto, não há nada difícil nele.

A fim de nosso diálogo lidar com eventos externos, o método da classe parente deve ser recarregado:

virtual bool  OnEvent(const int id,const long &lparam,
                       const double &dparam,const string &sparam);

E agora um pouco de mistério. Se você já abriu arquivo PanelDialog.mqh no Editor, você vai ver que não há corpo do método OnEvent (...).

Não se confunda - o negócio é que, para a descrição de manuseio com eventos externos, um conjunto de macros foi criado (veja o arquivo na Biblioteca Padrão).

Nosso manipulador de eventos é o seguinte:

//+------------------------------------------------------------------+
//| Handling events                                                  |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CPanelDialog)
   ON_EVENT(ON_CHANGE,m_edit_blue,OnChangeBlue)
EVENT_MAP_END(CAppDialog)

Este pseudocódigo que pode não ser claro à primeira vista, faz o seguinte:

  • Quando o evento ON_CHANGE é recebido a partir do controle m_edit_blue, o método OnChangeBlue é chamado e o manuseio do evento é concluído (retorno verdadeiro);
  • Ao receber qualquer outro modo, o controle é transferido para o método de classe original.

Conclusão

Este artigo tem proporcionado a revisão do processo de criação de um painel de exibição usando as classes da Biblioteca Padrão.

É improvável que você vai usar o indicador conforme criado, contudo ele não é sobrecarregado com informações desnecessárias e conseguimos cobrir quase todas as peculiaridades do processo ao criá-lo.

Exemplos de fornecimento padrão mais complexos podem ser encontrados nos seguintes diretórios de seu Terminal:

  • Experts\Examples\Controls\
  • Indicators\Examples\Panels\ChartPanel\
  • Indicators\Examples\Panels\SimplePanel\

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/345

Arquivos anexados |
paneldialog.mqh (13.04 KB)
panelindicator.mq5 (3.38 KB)
Os Fundamentos da programação orientada a objetos Os Fundamentos da programação orientada a objetos
Você não precisa saber o que são polimorfismo, encapsulação, etc. tudo sobre o uso da programação orientada a objeto (OOP)... você pode simplesmente usar estes recursos. Este artigo cobre o básico de OOP com exemplos práticos.
Controles gráficos personalizados. Parte 3. Formas Controles gráficos personalizados. Parte 3. Formas
Este é o último dos três artigos dedicados a controles gráficos. Ele cobre a criação do principal componente da interface gráfica - a forma - e seu uso em combinação com outros controles. Além das classes de forma, as classes CFrame, CButton, CLabel foram adicionadas à biblioteca de controle.
Abordagem orientada a objetos para construção de painéis de múltiplos períodos de tempo e múltiplas moedas Abordagem orientada a objetos para construção de painéis de múltiplos períodos de tempo e múltiplas moedas
Este artigo descreve como a programação orientada a objetos pode ser usada para criar painéis de múltiplos períodos de tempo múltiplas moedas para o MetaTrader 5. O principal objetivo é construir um painel universal, que pode ser utilizado para exibição de diversos tipos diferentes de dados, tal como preços, variação de preços, valores de indicador ou condições personalizadas de compra/venda, sem a necessidade de modificar o código do painel em si.
Controles gráficos personalizados. Parte 2. Biblioteca de controles Controles gráficos personalizados. Parte 2. Biblioteca de controles
O segundo artigo da série "Controles gráficos personalizados" apresenta uma biblioteca para manusear os principais problemas que surgem da interação entre um programa (Expert Advisor, script, indicador) e um usuário. A biblioteca contém um grande número de classes (CInputBox, CSpinInputBox, CCheckBox, CRadioGroup, CVSсrollBar, CHSсrollBar, CList, CListMS, CComBox, CHMenu, CVMenu, CHProgress, CDialer, CDialerInputBox, CTable) e exemplos de seu uso.