English Русский 中文 Español Deutsch 日本語
Interfaces Gráficas VI: Os Controles Deslizante e Deslizante Duplo (Capítulo 2)

Interfaces Gráficas VI: Os Controles Deslizante e Deslizante Duplo (Capítulo 2)

MetaTrader 5Exemplos | 30 setembro 2016, 12:31
925 0
Anatoli Kazharski
Anatoli Kazharski

Conteúdo

 

Introdução

O primeiro artigo Interfaces gráficas I: Preparação da Estrutura da Biblioteca (Capítulo 1) explica em detalhes a finalidade desta biblioteca. Você irã encontrar uma lista de artigos com os links no final de cada capítulo. Lá, você também pode encontrar e baixar a versão completa da biblioteca, no estágio de desenvolvimento atual. Os arquivos devem estar localizados nas mesmas pastas que o arquivo baixado.

No artigo anterior, nós enriquecemos a nossa biblioteca com quatro controles que são frequentemente usados ​​nas interfaces gráficas: caixa de seleção, campo de edição, campo de edição com caixa de seleção e a lista combinada com a caixa de seleção. O segundo capítulo da sexta parte será dedicado aos controles deslizante e deslizante duplo.


O Controle Deslizante

O Controle deslizante é um tipo do controle campo de edição que contém um intervalo limitado por um valor mínimo e máximo. Ao contrário do controle campo de edição que nós discutimos em detalhes no artigo anterior, o controle deslizante não possui botões para alterar o valor no campo de entrada. Para esse propósito, existe uma linha ao longo da qual o cursor pode ser deslocado. Tal elemento de interface é adequado para os casos em que é necessário apenas um valor aproximado dentro de um certo intervalo, não sendo necessário seu valor preciso. No entanto, ainda há a possibilidade de introduzir um valor preciso.

Este elemento será composto por seis objetos gráficos. Eles são:

  1. Fundo
  2. Título (rótulo de texto)
  3. Campo de entrada
  4. Linha do controle deslizante.
  5. Corrediça do controle deslizante
  6. Indicador do controle deslizante

 

Fig. 1. Partes integrantes do controle deslizante.


Vamos estudar a classe desse controle em detalhes.

 


Desenvolvimento de uma Classe para a Criação do Controle Deslizante

Crie o arquivo Slider.mqh e inclua-o no arquivo WndContainer.mqh:

//+------------------------------------------------------------------+
//|                                                 WndContainer.mqh |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Slider.mqh"

No arquivo Slider.mqh crie a classe CSlider com o conjunto padrão de métodos que devem estar presentes em cada controle da biblioteca em desenvolvimento. Ao lado dos arquivos de inclusão Element.mqh e Window.mqh, inclua o arquivo SeparateLine.mqh com a classe CSeparateLine para a criação de uma linha de separação. A classe CSeparateLine já foi discutida no artigo Interfaces Gráficas II: Os Elementos Linha de Separação e o Menu de Contexto (Capítulo 2)e, portanto, não vamos considerá-la novamente. A única coisa que eu gostaria de lembrá-lo é que se a altura definida for maior do que dois pixels, haverá um espaço vazio entre as duas linhas desenhadas. Visualmente, ela se parece como um buraco que é adequado para a criação de uma linha do controle deslizante (fenda ou ranhura), onde a corrediça do controle deslizante estará se movendo.

//+------------------------------------------------------------------+
//|                                                       Slider.mqh |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Element.mqh"
#include "Window.mqh"
#include "SeparateLine.mqh"
//+------------------------------------------------------------------+
//| Classe para criar o controle deslizante com o campo de edição    |
//+------------------------------------------------------------------+
class CSlider : public CElement
  {
private:
   //--- Ponteiro para o formulário ao qual o elemento está anexado
   CWindow          *m_wnd;
public:
                     CSlider(void);
                    ~CSlider(void);
   //---
public:
   //--- Armazena o ponteiro do formulário
   void              WindowPointer(CWindow &object)                 { m_wnd=::GetPointer(object);         }
   //---
public:
   //--- Manipulador de eventos do gráfico
   virtual void      OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
   //--- Timer
   virtual void      OnEventTimer(void);
   //--- Move o elemento
   virtual void      Moving(const int x,const int y);
   //--- (1) Exibe, (2) oculta, (3) reseta, (4) remove
   virtual void      Show(void);
   virtual void      Hide(void);
   virtual void      Reset(void);
   virtual void      Delete(void);
   //--- (1) Definir (2), resetar as prioridades para o clique esquerdo do mouse
   virtual void      SetZorders(void);
   virtual void      ResetZorders(void);
   //--- Reseta a cor
   virtual void      ResetColors(void);
  };

A biblioteca do usuário deve ter a possibilidade de definir as propriedades de todos os objetos que o controle deslizante será composto. Estas propriedades são listadas abaixo.

  • Cor de fundo do elemento
  • Texto para descrever o controle deslizante
  • Cores do rótulo de texto em diferentes estados
  • Valor atual do campo de entrada
  • Tamanho do campo de entrada
  • Cores do campo de entrada em diferentes estados
  • Cores do texto do campo de entrada em diferentes estados
  • Cores do quadro do campo de entrada em diferentes estados
  • Tamanho da fenda ao longo do eixo Y (altura)
  • Cores das linhas da fenda
  • Cores do indicador do controle deslizante em diferentes estados
  • Tamanho da corrediça do controle deslizante
  • Cores da corrediça do controle deslizante
  • Prioridades do clique do botão esquerdo do mouse

Abaixo está o código dos campos e métodos da classe das propriedades dos objetos listados acima: 

class CSlider : public CElement
  {
private:
   //--- Cor de fundo do elemento
   color             m_area_color;
   //--- Texto para descrever o controle deslizante
   string            m_label_text;
   //--- Cores do rótulo de texto em diferentes estados
   color             m_label_color;
   color             m_label_color_hover;
   color             m_label_color_locked;
   color             m_label_color_array[];
   //--- Tamanho do campo de entrada
   int               m_edit_x_size;
   int               m_edit_y_size;
   //--- Cores do campo de entrada em diferentes estados
   color             m_edit_color;
   color             m_edit_color_locked;
   //--- Cores do texto do campo de entrada em diferentes estados
   color             m_edit_text_color;
   color             m_edit_text_color_locked;
   //--- Cores da estrutura do campo de entrada em diferentes estados
   color             m_edit_border_color;
   color             m_edit_border_color_hover;
   color             m_edit_border_color_locked;
   color             m_edit_border_color_array[];
   //--- Tamanho da fenda
   int               m_slot_y_size;
   //--- Cores da fenda
   color             m_slot_line_dark_color;
   color             m_slot_line_light_color;
   //--- Cores do indicador em diferentes estados
   color             m_slot_indicator_color;
   color             m_slot_indicator_color_locked;
   //--- Tamanho da corrediça do controle deslizante
   int               m_thumb_x_size;
   int               m_thumb_y_size;
   //--- Cores da corrediça do controle deslizante
   color             m_thumb_color;
   color             m_thumb_color_hover;
   color             m_thumb_color_locked;
   color             m_thumb_color_pressed;
   //--- Prioridades do clique do botão esquerdo do mouse
   int               m_zorder;
   int               m_area_zorder;
   int               m_edit_zorder;
   //---
public:
   //--- (1) cor de fundo, (2) cores do rótulo de texto
   void              AreaColor(const color clr)                     { m_area_color=clr;                   }
   void              LabelColor(const color clr)                    { m_label_color=clr;                  }
   void              LabelColorHover(const color clr)               { m_label_color_hover=clr;            }
   void              LabelColorLocked(const color clr)              { m_label_color_locked=clr;           }
   //--- Tamanho do (1) campo de entrada e (2) a fenda
   void              EditXSize(const int x_size)                    { m_edit_x_size=x_size;               }
   void              EditYSize(const int y_size)                    { m_edit_y_size=y_size;               }
   void              SlotYSize(const int y_size)                    { m_slot_y_size=y_size;               }
   //--- Cores do campo de entrada em diferentes estados
   void              EditColor(const color clr)                     { m_edit_color=clr;                   }
   void              EditColorLocked(const color clr)               { m_edit_color_locked=clr;            }
   //--- Cores do texto do campo de entrada em diferentes estados
   void              EditTextColor(const color clr)                 { m_edit_text_color=clr;              }
   void              EditTextColorLocked(const color clr)           { m_edit_text_color_locked=clr;       }
   //--- Cores da estrutura do campo de entrada em diferentes estados
   void              EditBorderColor(const color clr)               { m_edit_border_color=clr;            }
   void              EditBorderColorHover(const color clr)          { m_edit_border_color_hover=clr;      }
   void              EditBorderColorLocked(const color clr)         { m_edit_border_color_locked=clr;     }
   //--- Linha de separação na cor (1) escura e (2) clara
   void              SlotLineDarkColor(const color clr)             { m_slot_line_dark_color=clr;         }
   void              SlotLineLightColor(const color clr)            { m_slot_line_light_color=clr;        }
   //--- Cores do indicador deslizante em diferentes estados
   void              SlotIndicatorColor(const color clr)            { m_slot_indicator_color=clr;         }
   void              SlotIndicatorColorLocked(const color clr)      { m_slot_indicator_color_locked=clr;  }
   //--- Tamanho da corrediça do controle deslizante
   void              ThumbXSize(const int x_size)                   { m_thumb_x_size=x_size;              }
   void              ThumbYSize(const int y_size)                   { m_thumb_y_size=y_size;              }
   //--- Cores da corrediça do controle deslizante
   void              ThumbColor(const color clr)                    { m_thumb_color=clr;                  }
   void              ThumbColorHover(const color clr)               { m_thumb_color_hover=clr;            }
   void              ThumbColorLocked(const color clr)              { m_thumb_color_locked=clr;           }
   void              ThumbColorPressed(const color clr)             { m_thumb_color_pressed=clr;          }
  };

As propriedades da lista anterior se relacionam principalmente com a cor e o tamanho dos objetos do controle. As propriedades relacionadas com o alcance e o campo de entrada do cursor será mostrado em um grupo separado. Estas propriedades são: 

  • Valor mínimo
  • Valor máximo
  • Passo da variação dos valores no campo de entrada
  • Modo de alinhamento de texto
  • Número de casas decimais
class CSlider : public CElement
  {
private:
   //--- (1) Valor mínimo (2) e máximo, (3) passo para alterar o valor
   double            m_min_value;
   double            m_max_value;
   double            m_step_value;
   //--- Número de casas decimais
   int               m_digits;
   //--- Modo de alinhamento de texto
   ENUM_ALIGN_MODE   m_align_mode;
   //---
public:
   //--- Valor mínimo
   double            MinValue(void)                           const { return(m_min_value);                }
   void              MinValue(const double value)                   { m_min_value=value;                  }
   //--- Valor máximo
   double            MaxValue(void)                           const { return(m_max_value);                }
   void              MaxValue(const double value)                   { m_max_value=value;                  }
   //--- Passo de alteração do valor
   double            StepValue(void)                          const { return(m_step_value);               }
   void              StepValue(const double value)                  { m_step_value=(value<=0)? 1 : value; }
   //--- (1) Número de casas decimais, (2) o modo de alinhamento do texto
   void              SetDigits(const int digits)                    { m_digits=::fabs(digits);            }
   void              AlignMode(ENUM_ALIGN_MODE mode)                { m_align_mode=mode;                  }
  };

Para obter o valor atual, bem como para ajustar e definir o novo valor no campo de entrada, nós vamos usar os métodos CSlider::GetValue(), CSlider::SetValue() e o CSlider::ChangeValue():

class CSlider : public CElement
  {
private:
   //--- Valor atual do campo de entrada
   double            m_edit_value;
   //---
public:
   //--- Retorna e define o valor do campo de entrada
   double            GetValue(void)                           const { return(m_edit_value);               }
   bool              SetValue(const double value);
   //--- Valor atual do campo de entrada
   void              ChangeValue(const double value);
  };
//+------------------------------------------------------------------+
//| Define o valor atual                                             |
//+------------------------------------------------------------------+
bool CSlider::SetValue(const double value)
  {
//--- Para o ajuste
   double corrected_value=0.0;
//--- Ajustar considerando o passo
   corrected_value=::MathRound(value/m_step_value)*m_step_value;
//--- Verifica a mínima/máxima
   if(corrected_value<=m_min_value)
      corrected_value=m_min_value;
   if(corrected_value>=m_max_value)
      corrected_value=m_max_value;
//--- Se o valor tiver sido alterado
   if(m_edit_value!=corrected_value)
     {
      m_edit_value=corrected_value;
      return(true);
     }
//--- Valor inalterado
   return(false);
  }
//+------------------------------------------------------------------+
//| Valor atual do campo de entrada                                  |
//+------------------------------------------------------------------+
void CSlider::ChangeValue(const double value)
  {
//--- Verifica, ajusta e armazena o novo valor
   SetValue(value);
//--- Define o novo valor no campo de entrada
   m_edit.Description(::DoubleToString(GetValue(),m_digits));
  }

Quando a corrediça do controle deslizante se move, o valor no campo de entrada deve ser calculado em relação a coordenada X. Se o valor for inserido manualmente, então a coordenada X da corrediça do controle deslizante deve ser calculada em relação ao novo valor no campo de entrada. Em outras palavras, a possibilidade da transformação inversa deve ser permitida quando o elemento for desenvolvido. 

Para o cálculo correto, nós precisaremos de campos auxiliares (variáveis) da classe que será utilizada no cálculo. Estas variáveis ​​deverão ser calculadas (inicializadas) apenas uma vez, imediatamente após o elemento ter sido criado. Abaixo está a descrição dessas variáveis.

  • Número de pixels na área de trabalho (m_pixels_total).
  • Número de passos no intervalo de valores da área de trabalho (m_value_steps_total).
  • Passo em relação à largura da área de trabalho (m_position_step).

Vamos escrever um método para calcular esses valores e chamá-lo de CSlider::CalculateCoefficients():

class CSlider : public CElement
  {
private:
   //--- Número de pixels na área de trabalho
   int               m_pixels_total;
   //--- Número de passos na área de trabalho
   int               m_value_steps_total;
   //--- Passo da largura transformada da área de trabalho
   double            m_position_step;
   //---
private:
   //--- Cálculo dos valores (passos e coeficientes)
   bool              CalculateCoefficients(void);
  };
//+------------------------------------------------------------------+
//| Cálculo dos valores (passos e coeficientes)                      |
//+------------------------------------------------------------------+
bool CSlider::CalculateCoefficients(void)
  {
//--- Sai se a largura do elemento for menor do que a largura da corrediça do controle deslizante
   if(CElement::XSize()<m_thumb_x_size)
      return(false);
//--- Número de pixels na área de trabalho
   m_pixels_total=CElement::XSize()-m_thumb_x_size;
//--- Número de passos no valor do intervalo da área de trabalho
   m_value_steps_total=int((m_max_value-m_min_value)/m_step_value);
//--- Passo em relação à largura da área de trabalho
   m_position_step=m_step_value*(double(m_value_steps_total)/double(m_pixels_total));
   return(true);
  }

Agora, os valores das variáveis ​​listadas acima podem ser utilizadas para o cálculo da coordenada X da corrediça do controle deslizante em relação ao valor no campo de entrada e vice-versa. Para isso, nós vamos escrever dois métodos distintos, o CSlider::CalculateThumbX() e o CSlider::CalculateThumbPos().

No início do método CSlider::CalculateThumbX(), nós iremos calcular os valores da variável local auxiliar (neg_range) para ajuste no caso do valor do limite mínimo ser negativo. Então, nós vamos calcular a coordenada X para a corrediça do controle deslizante. Depois disso, no caso da linha do controle deslizante exceder, o valor é ajustado. No final do método, é definido um novo valor da coordenada X para a corrediça do controle deslizante e a margem da borda do formulário que o elemento está anexado é calculada de novo.

No início do método CSlider::CalculateThumbPos(), nós obtemos a posição da corrediça do controle deslizante na faixa de valores. Em seguida, é realizado um ajuste se o valor do limite mínimo for negativo e o valor da variável m_current_pos_x estiver correta. Então, se a área de trabalho foi excedida, é feito uma alteração no valor.

class CSlider : public CElement
  {
private:
   //--- Posição atual da corrediça do controle deslizante: (1) valor, (2) a coordenada X
   double            m_current_pos;
   double            m_current_pos_x;
   //---
private:
   //--- Cálculo da coordenada X da corrediça do controle deslizante
   void              CalculateThumbX(void);
   //--- Altera a posição atual da corrediça do controle deslizante em relação ao valor atual
   void              CalculateThumbPos(void);
  };
//+------------------------------------------------------------------+
//| Cálculo da coordenada X do deslizado do cursor                   |
//+------------------------------------------------------------------+
void CSlider::CalculateThumbX(void)
  {
//--- Ajuste considerando que o valor mínimo pode ser negativo
   double neg_range=(m_min_value<0)? ::fabs(m_min_value/m_position_step) : 0;
//--- Calcula a coordenada X para a corrediça do controle deslizante
   m_current_pos_x=m_area.X()+(m_edit_value/m_position_step)+neg_range;
//--- Se a área de trabalho exceder pelo lado esquerdo
   if(m_current_pos_x<m_area.X())
      m_current_pos_x=m_area.X();
//--- Se a área de trabalho exceder pelo lado direito
   if(m_current_pos_x+m_thumb.XSize()>m_area.X2())
      m_current_pos_x=m_area.X2()-m_thumb.XSize();
//--- Armazena e define a nova coordenada X
   m_thumb.X(int(m_current_pos_x));
   m_thumb.X_Distance(int(m_current_pos_x));
   m_thumb.XGap(m_thumb.X()-m_wnd.X());
  }
//+------------------------------------------------------------------+
//| Cálculo da posição da corrediça do controle deslizante na faixa de valores   |
//+------------------------------------------------------------------+
void CSlider::CalculateThumbPos(void)
  {
//--- Obtém o número da posição da corrediça do controle deslizante
   m_current_pos=(m_thumb.X()-m_area.X())*m_position_step;
//--- Ajuste considerando que o valor mínimo pode ser negativo
   if(m_min_value<0 && m_current_pos_x!=WRONG_VALUE)
      m_current_pos+=int(m_min_value);
//--- Verifica se a área de trabalho excedeu pela direita/esquerda
   if(m_thumb.X2()>=m_area.X2())
      m_current_pos=int(m_max_value);
   if(m_thumb.X()<=m_area.X())
      m_current_pos=int(m_min_value);
  }

Quando os deslizador do cursor está se movendo, a largura do indicador do controle deslizante deve ser calculado e atualizado. O lado direito do indicador do controle deslizante deve ser vinculado a corrediça do controle deslizante Para isso, vamos escrever o método CSlider::UpdateIndicator():

class CSlider : public CElement
  {
private:
   //--- Atualiza o indicador do controle deslizante
   void              UpdateIndicator(void);
  };
//+------------------------------------------------------------------+
//| Atualiza o indicador do controle deslizante                      |
//+------------------------------------------------------------------+
void CSlider::UpdateIndicator(void)
  {
//--- Calcula o tamanho
   int x_size=m_thumb.X()-m_indicator.X();
//--- Ajuste no caso dos valores não serem permitidos
   if(x_size<=0)
      x_size=1;
//--- Define um novo tamanho
   m_indicator.X_Size(x_size);
  }

Para criar o controle deslizante nós precisaremos de seis métodos privados e um público.

class CSlider : public CElement
  {
public:
   //--- Métodos para criar o controle
   bool              CreateSlider(const long chart_id,const int subwin,const string text,const int x,const int y);
   //---
private:
   bool              CreateArea(void);
   bool              CreateLabel(void);
   bool              CreateEdit(void);
   bool              CreateSlot(void);
   bool              CreateIndicator(void);
   bool              CreateThumb(void);
  };

Nós vamos discutir apenas o código do método CSlider::CreateThumb(), porque este é o lugar onde é chamado todos os métodos de cálculos considerados anteriormente. Outros métodos não possuem nada que nós já não estudamos nos artigos anteriores desta série.

//+------------------------------------------------------------------+
//| Cria a corrediça do controle deslizante                          |
//+------------------------------------------------------------------+
bool CSlider::CreateThumb(void)
  {
//--- Elaborando o nome do objeto
   string name=CElement::ProgramName()+"_slider_thumb_"+(string)CElement::Id();
//--- Coordenadas
   int x=CElement::X();
   int y=m_slot.Y()-((m_thumb_y_size-m_slot_y_size)/2);
//--- Define o objeto
   if(!m_thumb.Create(m_chart_id,name,m_subwin,x,y,m_thumb_x_size,m_thumb_y_size))
      return(false);
//--- Define as propriedades
   m_thumb.Color(m_thumb_color);
   m_thumb.BackColor(m_thumb_color);
   m_thumb.BorderType(BORDER_FLAT);
   m_thumb.Corner(m_corner);
   m_thumb.Selectable(false);
   m_thumb.Z_Order(m_zorder);
   m_thumb.Tooltip("\n");
//--- Armazenar o tamanho (no objecto)
   m_thumb.XSize(m_thumb.X_Size());
   m_thumb.YSize(m_thumb.Y_Size());
//--- Armazena as coordenadas
   m_thumb.X(x);
   m_thumb.Y(y);
//--- Margens da borda
   m_thumb.XGap(x-m_wnd.X());
   m_thumb.YGap(y-m_wnd.Y());
//--- Calcula os valores das variáveis ​​auxiliares
   CalculateCoefficients();
//--- Calcula as coordenadas X da corrediça do controle deslizante em relação ao valor atual no campo de entrada
   CalculateThumbX();
//--- Cálculo da posição da corrediça do controle deslizante na faixa do valor
   CalculateThumbPos();
//--- Atualiza o indicador do controle deslizante
   UpdateIndicator();
//--- Armazena o ponteiro de objeto
   CElement::AddToArray(m_thumb);
   return(true);
  }

Os métodos de mover a corrediça do controle deslizante são idênticos aos métodos com nomes semelhantes nas classes CScroll e CScrollH, que foram discutidos em detalhe no artigo Interfaces Gráficas V: A Barra de Rolagem Vertical e Horizontal (Capítulo 1). É por isso que nós não vamos considerar o seu código aqui. Nós só vamos declará-los no corpo da classe CSlider

class CSlider : public CElement
  {
private:
   //--- Estado do botão do mouse (pressionado/liberado)
   ENUM_THUMB_MOUSE_STATE m_clamping_area_mouse;
   //--- Para identificar o modo do movimento da corrediça do controle deslizante
   bool              m_slider_thumb_state;
   //--- Variáveis ​​relacionadas com o movimento da corrediça do controle deslizante
   int               m_slider_size_fixing;
   int               m_slider_point_fixing;
   //---
private:
   //--- Processo do movimento deslizante do cursor
   void              OnDragThumb(const int x);
   //--- Atualização da localização da corrediça do controle deslizante
   void              UpdateThumb(const int new_x_point);
   //--- Verifica o estado do botão do mouse
   void              CheckMouseButtonState(void);
   //--- Zerando as variáveis relacionadas com o movimento deslizante do cursor
   void              ZeroThumbVariables(void);
  };

Para lidar com os valores inseridos no campo de entrada, crie o método CSlider::OnEndEdit() que será chamado no manipulador de eventos CSlider::OnEvent(). 

No início do método CSlider::OnEndEdit(), há uma verificação com o nome do objeto se o valor foi inserido no campo deste cursor. Em seguida, obtenha o valor atual do campo de entrada. Então, siga uma verificação obrigatória para a entrada com valores não permitidos, ajuste, o cálculo da coordenada X da corrediça do controle deslizante e a posição na faixa do valor. Depois disso, o indicador do controle deslizante é atualizado. No final deste método, uma mensagem deve ser enviada com (1) o identificador de evento personalizado ON_END_EDIT, (2) o identificador do elemento, (3) o índice do elemento e (4) a descrição contida no rótulo de texto. 

class CSlider : public CElement
  {
private:
   //--- Lidando com a inserção do valor no campo de entrada
   bool              OnEndEdit(const string object_name);
  };
//+------------------------------------------------------------------+
//| Lidando com a inserção do valor no campo de entrada              |
//+------------------------------------------------------------------+
bool CSlider::OnEndEdit(const string object_name)
  {
//--- Sai, se o nome do objeto for diferente
   if(object_name!=m_edit.Name())
      return(false);
//--- Obter o valor inserido
   double entered_value=::StringToDouble(m_edit.Description());
//--- Verifica, ajusta e armazena o novo valor
   ChangeValue(entered_value);
//--- Calcula a coordenada X da corrediça do controle deslizante
   CalculateThumbX();
//--- Calcula a posição no intervalo de valores
   CalculateThumbPos();
//--- Atualiza o indicador do controle deslizante
   UpdateIndicator();
//--- Envia uma mensagem sobre ele
   ::EventChartCustom(m_chart_id,ON_END_EDIT,CElement::Id(),CElement::Index(),m_label.Description());
   return(true);
  }

A mesma mensagem personalizada deve ser enviada após a corrediça do controle deslizante parar de se mover para alterar o valor do campo de entrada. O método CSlider::ZeroThumbVariables() serve muito bem para este objetivo. Isso é chamado no método CSlider::CheckMouseButtonState(), onde a área do clique do botão esquerdo do mouse é monitorada. A chamada do método CSlider::ZeroThumbVariables() já implica que o botão esquerdo do mouse já foi liberado. Se ele é pressionado para baixo sobre a área da corrediça do controle deslizante, significa que o movimento dele foi finalizado e uma mensagem deverá ser enviada dizendo que o valor no campo de entrada foi alterado.

//+------------------------------------------------------------------+
//| Zerando as variáveis ​​relacionadas ao movimento da barra de rolagem |
//+------------------------------------------------------------------+
void CSlider::ZeroThumbVariables(void)
  {
//--- Se você está aqui, isso significa que o botão esquerdo do mouse foi liberado.
//    Se o botão esquerdo do mouse foi pressionado sobre o segundo controle deslizante...
   if(m_clamping_area_mouse==THUMB_PRESSED_INSIDE)
     {
      //--- ...envia uma mensagem que a alteração do valor no campo de entrada com a corrediça do controle deslizante foi concluída
      ::EventChartCustom(m_chart_id,ON_END_EDIT,CElement::Id(),CElement::Index(),m_label.Description());
     }
//---
   m_slider_size_fixing  =0;
   m_clamping_area_mouse =THUMB_NOT_PRESSED;
//--- Se o identificador do elemento coincide com o identificador de ativação,
//    desbloqueia o formulário e redefine o identificador do elemento ativado
   if(CElement::Id()==m_wnd.IdActivatedElement())
     {
      m_wnd.IsLocked(false);
      m_wnd.IdActivatedElement(WRONG_VALUE);
     }
  }

O código completo do manipulador de evento CSlider::OnEvent(), neste caso, ficará da seguinte forma:

//+------------------------------------------------------------------+
//| Manipulador de eventos do gráfico                                |
//+------------------------------------------------------------------+
void CSlider::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Manipulação do evento do movimento do cursor
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      //--- Sai se o elemento está oculto     
      if(!CElement::IsVisible())
         return;
      //--- Coordenadas e o estado do botão esquerdo do mouse
      int x=(int)lparam;
      int y=(int)dparam;
      m_mouse_state=(bool)int(sparam);
      //--- Verificando o foco sobre os elementos
      CElement::MouseFocus(x>X() && x<X2() && y>Y() && y<Y2());
      m_thumb.MouseFocus(x>m_thumb.X() && x<m_thumb.X2() && 
                         y>m_thumb.Y() && y<m_thumb.Y2());
      //--- Sai, se o elemento está bloqueado
      if(!m_slider_state)
         return;
      //--- Verifica e armazena o estado do botão do mouse
      CheckMouseButtonState();
      //--- Altera a cor da corrediça do controle deslizante
      ChangeThumbColor();
      //--- Se a gestão foi passada para a linha do controle deslizante, identifica a sua localização
      if(m_clamping_area_mouse==THUMB_PRESSED_INSIDE)
        {
         //--- Movendo a corrediça do controle deslizante
         OnDragThumb(x);
         //--- Cálculo da posição da corrediça do controle deslizante na faixa do valor
         CalculateThumbPos();
         //--- Define o novo valor no campo de entrada
         ChangeValue(m_current_pos);
         //--- Atualiza o indicador do controle deslizante
         UpdateIndicator();
         return;
        }
     }
//--- Lidando com a alteração do valor no evento campo de entrada
   if(id==CHARTEVENT_OBJECT_ENDEDIT)
     {
      //--- Manipula o valor de entrada
      if(OnEndEdit(sparam))
         return;
     }
  }

Nós implementamos os métodos para a criação e gerenciamento do controle deslizante. Vamos testá-lo no programa em MQL que nós utilizamos nos artigos anteriores. 

 


Teste do Controle Deslizante

No artigo anterior, na aplicação de teste, nós criamos quatro caixas de seleção que gerenciavam a disponibilidade de outros elementos. Nós vamos adicionar o controle deslizante e a quinta caixa de seleção para gerir a sua disponibilidade na interface gráfica. Para isso, na classe personalizada CProgram, declare as instâncias da classe CCheckBox e CSlider, bem como os métodos com margens a partir da borda do formulário que estes controles serão vinculados.

//+------------------------------------------------------------------+
//| Classe para a criação de um aplicativo                           |
//+------------------------------------------------------------------+
class CProgram : public CWndEvents
  {
private:
   //--- Caixas de seleção
   CCheckBox         m_checkbox5;
   //--- Controles deslizantes
   CSlider           m_slider1;
   //---
private:
   //--- Caixas de seleção
#define CHECKBOX5_GAP_X       (7)
#define CHECKBOX5_GAP_Y       (200)
   bool              CreateCheckBox5(const string text);
   //--- Controles deslizantes
#define SLIDER1_GAP_X         (32)
#define SLIDER1_GAP_Y         (225)
   bool              CreateSlider1(const string text);
  };


Nós consideramos o código dos métodos para a criação das caixas de seleção no artigo anterior, é por isso que nós estamos avançando com o método para a criação do elemento CProgram::CreateSlider1(). Usando os métodos CSlider::MinValue() e CSlider::MaxValue(), defina um intervalo no valor de -1 até 1. Defina o passo até a casa decimal (0.00000001). A disponibilidade irá depender do estado atual da quinta caixa de seleção.

//+------------------------------------------------------------------+
//| Cria o controle deslizante 1                                     |
//+------------------------------------------------------------------+
bool CProgram::CreateSlider1(const string text)
  {
//--- Armazena o ponteiro da janela
   m_slider1.WindowPointer(m_window1);
//--- Coordenadas
   int x=m_window1.X()+SLIDER1_GAP_X;
   int y=m_window1.Y()+SLIDER1_GAP_Y;
//--- Valor
   double v=(m_slider1.GetValue()==WRONG_VALUE) ? 0.84615385 : m_slider1.GetValue();
//--- Define as propriedades antes da criação
   m_slider1.XSize(264);
   m_slider1.YSize(40);
   m_slider1.EditXSize(87);
   m_slider1.MaxValue(1);
   m_slider1.StepValue(0.00000001);
   m_slider1.MinValue(-1);
   m_slider1.SetDigits(8);
   m_slider1.SetValue(v);
   m_slider1.AreaColor(clrWhiteSmoke);
   m_slider1.LabelColor(clrBlack);
   m_slider1.LabelColorLocked(clrSilver);
   m_slider1.EditColorLocked(clrWhiteSmoke);
   m_slider1.EditBorderColor(clrSilver);
   m_slider1.EditBorderColorLocked(clrSilver);
   m_slider1.EditTextColorLocked(clrSilver);
   m_slider1.SlotLineDarkColor(clrSilver);
   m_slider1.SlotLineLightColor(clrWhite);
   m_slider1.SlotYSize(4);
   m_slider1.ThumbColorLocked(clrLightGray);
   m_slider1.ThumbColorPressed(clrSilver);
   m_slider1.SlotIndicatorColor(C'85,170,255');
   m_slider1.SlotIndicatorColorLocked(clrLightGray);
//--- Cria o controle
   if(!m_slider1.CreateSlider(m_chart_id,m_subwin,text,x,y))
      return(false);
//--- A disponibilidade irá depender do estado atual da quinta caixa de seleção
   m_slider1.SliderState(m_checkbox5.CheckButtonState());
//--- Adiciona o objeto ao array comum dos grupos de objetos
   CWndContainer::AddToElementsArray(0,m_slider1);
   return(true);
  }

Os novos métodos para a criação dos elementos devem ser chamados no método principal para a criação da interface gráfica. Abaixo está o código de uma versão resumida deste método:

//+------------------------------------------------------------------+
//| Cria o painel de negociação                                      |
//+------------------------------------------------------------------+
bool CProgram::CreateTradePanel(void)
  {
//--- Criação do formulário 1 para os controles
//--- Criação dos controles:
//    Menu principal
//--- Menus de contexto
//--- Criando a barra de status
//--- Caixas de seleção
   if(!CreateCheckBox5("Checkbox 5"))
      return(false);
//--- Controles deslizantes
   if(!CreateSlider1("Slider 1:"))
      return(false);
//--- Redesenha o gráfico
   m_chart.Redraw();
   return(true);
  }

Nós vamos controlar a mudança do estado da quinta caixa de seleção para controlar a disponibilidade do controle deslizante no manipulador de eventos CProgram::OnEvent() do aplicativo. O evento com o identificador personalizado ON_END_EDIT irá indicar quando o valor no campo de entrada irá mudar.

//+------------------------------------------------------------------+
//| Manipulador de eventos                                           |
//+------------------------------------------------------------------+
void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- O evento clique no rótulo de texto
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_LABEL)
     {
      ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam);
      //--- Se a quinta caixa de seleção foi clicada
      if(lparam==m_checkbox5.Id())
        {
         //--- Define o estado do primeiro controle deslizante
         m_slider1.SliderState(m_checkbox5.CheckButtonState());
        }
     }
//--- o fim do evento de introdução do valor no campo de entrada
   if(id==CHARTEVENT_CUSTOM+ON_END_EDIT)
     {
      ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam);
     }
  }

Agora, o programa pode ser compilado e carregado ao gráfico. Tente interagir com os controles da interface gráfica da aplicação. Se tudo foi feito corretamente, você verá um resultado como na imagem abaixo:

 Fig. 2. Testando o controle deslizante.

Fig. 2. Testando o controle deslizante. 

 


O Controle Deslizante Duplo

A diferença entre um controle deslizante duplo e um simples é que o primeiro permite a seleção na faixa de valor definida pelo usuário. Por esse motivo, existem duas corrediças na linha do controle deslizante. A corrediça esquerda do controle deslizante pode ser movido a partir do lado esquerdo da linha do controle deslizante para a corrediça direita do controle deslizante. A corrediça direita do controle deslizante da direita pode ser movida a partir do lado direito da linha do controle deslizante para a corrediça esquerda do controle deslizante. O controle deslizante duplo também tem dois campos de entrada que refletem o valor em relação à posição de suas corrediças linha do controle deslizante. Os valores podem ser inseridos manualmente nestes campos de entrada. Isso vai mudar a posição das corrediças do controle deslizante.

Este controle será composto por oito objetos gráficos primitivos. Eles são:

  1. Fundo.
  2. Título (rótulo de texto)
  3. Campo de entrada esquerdo.
  4. Campo de entrada direito.
  5. Linha do controle deslizante.
  6. Corrediça esquerda do controle deslizante
  7. Corrediça direita do controle deslizante
  8. Indicador do controle deslizante


Fig. 3. Partes integrantes do controle deslizante duplo.


Vamos dar uma olhada na classe do controle deslizante duplo e notar as diferenças do controle deslizante simples.

 


Desenvolvimento de uma Classe para a Criação do Controle Deslizante Duplo

Inclua o arquivo DualSlider.mqh com a classe do controle CDualSlider no arquivo WndContainer.mqh:

//+------------------------------------------------------------------+
//|                                                 WndContainer.mqh |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include "DualSlider.mqh"

Em termos das propriedades do controle, a classe CDualSlider é idêntica a classe CSlider. A única diferença aqui é que os campos de entrada da esquerda e direita e as corrediças do controle deslizante exigem campos e métodos distintos. As diferenças entre estes dois métodos são insignificantes e é por isso que nós não vamos discutir o seu código aqui. Você pode encontrá-lo nos arquivos anexados neste artigo.

class CDualSlider : public CElement
  {
private:
   //--- Valores atuais nos campos de entrada (esquerda e direita)
   double            m_left_edit_value;
   double            m_right_edit_value;
   //--- Posição atual das corrediças do controle deslizante (esquerda e direita)
   double            m_left_current_pos;
   double            m_left_current_pos_x;
   double            m_right_current_pos;
   double            m_right_current_pos_x;
   //--- Estado do botão do mouse (pressionado/solto) para os corrediças do controle deslizante (esquerda e direita)
   ENUM_THUMB_MOUSE_STATE m_clamping_mouse_left_thumb;
   ENUM_THUMB_MOUSE_STATE m_clamping_mouse_right_thumb;
   //---
public:
   //--- Retorna e define o valor dos campos de entrada (esquerda e direita)
   double            GetLeftValue(void)                       const { return(m_left_edit_value);          }
   double            GetRightValue(void)                      const { return(m_right_edit_value);         }
   bool              SetLeftValue(double value);
   bool              SetRightValue(double value);
   //--- Altera os valores nos campos de entrada (esquerda e direita)
   void              ChangeLeftValue(const double value);
   void              ChangeRightValue(const double value);
   //---
private:
   //--- Processo de mover as corrediças do controle deslizante (esquerda e direita)
   void              OnDragLeftThumb(const int x);
   void              OnDragRightThumb(const int x);
   //--- Atualiza a posição das corrediças do controle deslizante (esquerda e direita)
   void              UpdateLeftThumb(const int new_x_point);
   void              UpdateRightThumb(const int new_x_point);
   //--- Verifica o estado do botão esquerdo do mouse sobre o segundo controle deslizante
   void              CheckMouseOnLeftThumb(void);
   void              CheckMouseOnRightThumb(void);
   //--- Calcula a coordenada X dos controles deslizantes (esquerda e direita)
   void              CalculateLeftThumbX(void);
   void              CalculateRightThumbX(void);
   //--- Altera a posição da corrediça esquerda do controle deslizante em relação ao valor (esquerda e direita)
   void              CalculateLeftThumbPos(void);
   void              CalculateRightThumbPos(void);
  };

Aqui, nós iremos apresentar apenas o código dos métodos onde foi considerado os dois campos de entrada e as corrediças do controle deslizante. Abaixo encontra-se a estrutura do método CDualSlider::OnEndEdit():

class CDualSlider : public CElement
  {
private:
   //--- Lidando com a inserção do valor no campo de entrada
   bool              OnEndEdit(const string object_name);
  };
//+------------------------------------------------------------------+
//| Fim da entrada dos valores                                       |
//+------------------------------------------------------------------+
bool CDualSlider::OnEndEdit(const string object_name)
  {
//--- Se o valor é inserido no campo de entrada esquerdo
   if(object_name==m_left_edit.Name())
     {
      //--- Obter o valor inserido
      double entered_value=::StringToDouble(m_left_edit.Description());
      //--- Verifica, ajusta e armazena o novo valor
      ChangeLeftValue(entered_value);
      //--- Calcula a coordenada X da corrediça do controle deslizante
      CalculateLeftThumbX();
      //--- Atualização da localização da corrediça do controle deslizante
      UpdateLeftThumb(m_left_thumb.X());
      //--- Calcula a posição no intervalo de valores
      CalculateLeftThumbPos();
      //--- Verifica, ajusta e armazena o novo valor
      ChangeLeftValue(m_left_current_pos);
      //--- Atualiza o indicador do controle deslizante
      UpdateIndicator();
      //--- Envia uma mensagem sobre ele
      ::EventChartCustom(m_chart_id,ON_END_EDIT,CElement::Id(),CElement::Index(),m_label.Description());
      return(true);
     }
//--- Se o valor é inserido no campo de entrada à direita
   if(object_name==m_right_edit.Name())
     {
      //--- Obter o valor inserido
      double entered_value=::StringToDouble(m_right_edit.Description());
      //--- Verifica, ajusta e armazena o novo valor
      ChangeRightValue(entered_value);
      //--- Calcula a coordenada X da corrediça do controle deslizante
      CalculateRightThumbX();
      //--- Atualização da localização da corrediça do controle deslizante
      UpdateRightThumb(m_right_thumb.X());
      //--- Calcula a posição no intervalo de valores
      CalculateRightThumbPos();
      //--- Verifica, ajusta e armazena o novo valor
      ChangeRightValue(m_right_current_pos);
      //--- Atualiza o indicador do controle deslizante
      UpdateIndicator();
      //--- Envia uma mensagem sobre ele
      ::EventChartCustom(m_chart_id,ON_END_EDIT,CElement::Id(),CElement::Index(),m_label.Description());
      return(true);
     }
//---
   return(false);
  }

O mesmo aplica-se ao movimento das corrediças esquerda e direita do controle deslizante. O manipulador de evento CDualSlider::OnEvent() contém as verificações e blocos de código separados para cada um deles: 

//+------------------------------------------------------------------+
//| Manipulador de eventos do gráfico                                |
//+------------------------------------------------------------------+
void CDualSlider::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- Manipulação do evento do movimento do cursor
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      //--- Sai se o elemento está oculto   
      if(!CElement::IsVisible())
         return;
      //--- Coordenadas e o estado do botão esquerdo do mouse
      int x=(int)lparam;
      int y=(int)dparam;
      m_mouse_state=(bool)int(sparam);
      //--- Verificando o foco sobre os elementos
      CElement::MouseFocus(x>X() && x<X2() && y>Y() && y<Y2());
      m_left_thumb.MouseFocus(x>m_left_thumb.X() && x<m_left_thumb.X2() && 
                              y>m_left_thumb.Y() && y<m_left_thumb.Y2());
      m_right_thumb.MouseFocus(x>m_right_thumb.X() && x<m_right_thumb.X2() && 
                               y>m_right_thumb.Y() && y<m_right_thumb.Y2());
      //--- Sai, se o elemento está bloqueado
      if(!m_slider_state)
         return;
      //--- Verifica e armazena o estado do botão do mouse
      CheckMouseOnLeftThumb();
      CheckMouseOnRightThumb();
      //--- Altera a cor da corrediça do controle deslizante
      ChangeThumbColor();
      //--- Se a gestão foi passada para a linha do controle deslizante (corrediça esquerda do controle deslizante)
      if(m_clamping_mouse_left_thumb==THUMB_PRESSED_INSIDE)
        {
         //--- Movendo a corrediça do controle deslizante
         OnDragLeftThumb(x);
         //--- Cálculo da posição da corrediça do controle deslizante na faixa do valor
         CalculateLeftThumbPos();
         //--- Define o novo valor no campo de entrada
         ChangeLeftValue(m_left_current_pos);
         //--- Atualiza o indicador do controle deslizante
         UpdateIndicator();
         return;
        }
      //--- Se a gestão foi passada para a barra de rolagem (corrediça direita do controle deslizante)
      if(m_clamping_mouse_right_thumb==THUMB_PRESSED_INSIDE)
        {
         //--- Movendo a corrediça do controle deslizante
         OnDragRightThumb(x);
         //--- Cálculo da posição da corrediça do controle deslizante na faixa do valor
         CalculateRightThumbPos();
         //--- Define o novo valor no campo de entrada
         ChangeRightValue(m_right_current_pos);
         //--- Atualiza o indicador do controle deslizante
         UpdateIndicator();
         return;
        }
     }
  }

Você pode baixar os arquivos anexados neste artigo e estudar mais a fundo o código da classe CDualSlider. 

 


Teste do Controle Deslizante Duplo

Adicione o controle deslizante duplo na interface gráfica da aplicação de teste. Declare uma instância da classe CDualSlider e um método com as margens da borda do formulário na classe personalizada CProgram do aplicativo:

//+------------------------------------------------------------------+
//| Classe para a criação de um aplicativo                           |
//+------------------------------------------------------------------+
class CProgram : public CWndEvents
  {
private:
   //--- Controles deslizantes
   CDualSlider       m_dual_slider1;
   //---
private:
   //--- Controles deslizantes
#define DUALSLIDER1_GAP_X     (32)
#define DUALSLIDER1_GAP_Y     (275)
   bool              CreateDualSlider1(const string text);
  };

O código a seguir mostra o código do método CProgram::CreateDualSlider1(). Defina o intervalo do valor de -2000 até 1000. A disponibilidade deste controle dependerá do estado atual da quinta caixa de seleção semelhante ao controle deslizante simples que foi criado no início deste artigo.

//+------------------------------------------------------------------+
//| Cria o controle deslizante duplo 1                               |
//+------------------------------------------------------------------+
bool CProgram::CreateDualSlider1(const string text)
  {
//--- Armazena o ponteiro da janela
   m_dual_slider1.WindowPointer(m_window1);
//--- Coordenadas
   int x=m_window1.X()+DUALSLIDER1_GAP_X;
   int y=m_window1.Y()+DUALSLIDER1_GAP_Y;
//--- Valores
   double v1=(m_dual_slider1.GetLeftValue()==WRONG_VALUE) ? 0 : m_dual_slider1.GetLeftValue();
   double v2=(m_dual_slider1.GetRightValue()==WRONG_VALUE) ? 500 : m_dual_slider1.GetRightValue();
//--- Define as propriedades antes da criação
   m_dual_slider1.XSize(264);
   m_dual_slider1.YSize(40);
   m_dual_slider1.EditXSize(87);
   m_dual_slider1.MaxValue(1000);
   m_dual_slider1.StepValue(1);
   m_dual_slider1.MinValue(-2000);
   m_dual_slider1.SetDigits(0);
   m_dual_slider1.SetLeftValue(v1);
   m_dual_slider1.SetRightValue(v2);
   m_dual_slider1.AreaColor(clrWhiteSmoke);
   m_dual_slider1.LabelColor(clrBlack);
   m_dual_slider1.LabelColorLocked(clrSilver);
   m_dual_slider1.EditColorLocked(clrWhiteSmoke);
   m_dual_slider1.EditBorderColor(clrSilver);
   m_dual_slider1.EditBorderColorLocked(clrSilver);
   m_dual_slider1.EditTextColorLocked(clrSilver);
   m_dual_slider1.SlotLineDarkColor(clrSilver);
   m_dual_slider1.SlotLineLightColor(clrWhite);
   m_dual_slider1.SlotYSize(4);
   m_dual_slider1.ThumbColorLocked(clrLightGray);
   m_dual_slider1.ThumbColorPressed(clrSilver);
   m_dual_slider1.SlotIndicatorColor(C'85,170,255');
   m_dual_slider1.SlotIndicatorColorLocked(clrLightGray);
//--- Cria o controle
   if(!m_dual_slider1.CreateSlider(m_chart_id,m_subwin,text,x,y))
      return(false);
//--- A disponibilidade irá depender do estado atual da quinta caixa de seleção
   m_dual_slider1.SliderState(m_checkbox5.CheckButtonState());
//--- Adiciona o objeto ao array comum dos grupos de objetos
   CWndContainer::AddToElementsArray(0,m_dual_slider1);
   return(true);
  }

Não se esqueça de colocar a chamada do método do novo controle no método principal para a criação da interface gráfica da maneira que é demonstrado na versão resumida do código abaixo. 

//+------------------------------------------------------------------+
//| Cria o painel de negociação                                      |
//+------------------------------------------------------------------+
bool CProgram::CreateTradePanel(void)
  {
//--- Criação do formulário 1 para os controles
//--- Criação dos controles:
//    Menu principal
//--- Menus de contexto
//--- Criando a barra de status
//--- Caixas de seleção
//--- Controles deslizantes
   if(!CreateDualSlider1("Dual Slider 1:"))
      return(false);
//--- Redesenha o gráfico
   m_chart.Redraw();
   return(true);
  }

Agora, o estado atual da quinta caixa de seleção irá definir dois controles - o controle deslizante simples e o deslizante duplo.

//+------------------------------------------------------------------+
//| Manipulador de eventos                                           |
//+------------------------------------------------------------------+
void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
//--- O evento clique no rótulo de texto
   if(id==CHARTEVENT_CUSTOM+ON_CLICK_LABEL)
     {
      ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam);
      //--- Se a quinta caixa de seleção foi clicada
      if(lparam==m_checkbox5.Id())
        {
         //--- Define o estado dos controles deslizantes
         m_slider1.SliderState(m_checkbox5.CheckButtonState());
         m_dual_slider1.SliderState(m_checkbox5.CheckButtonState());
        }
     }
//--- o fim do evento de introdução do valor no campo de entrada
   if(id==CHARTEVENT_CUSTOM+ON_END_EDIT)
     {
      ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam);
     }
  }


Agora, compile o programa e carregue-o ao gráfico. A imagem abaixo ilustra o resultado:

 Fig. 4. O controle duplo deslizante.

Fig. 4. O controle duplo deslizante.

 


Conclusão

Na sexta parte da série, nós consideramos seis controles:

  • Caixa de seleção (checkbox).
  • O controle campo de edição.
  • O campo de edição com a caixa de seleção.
  • Lista combinada com a caixa de seleção
  • Controle deslizante
  • Controle duplo deslizante.

A esquemática da biblioteca para a criação das interfaces gráficas no atual estágio de desenvolvimento é parecido com a imagem abaixo:

 Fig. 5. Estrutura da biblioteca no atual estágio de desenvolvimento.

Fig. 5. Estrutura da biblioteca no atual estágio de desenvolvimento.


Na próxima parte da série, vamos enriquecer a nossa biblioteca com as tabelas e guias.

Você pode baixar o material da parte VI e testar o seu funcionamento. Se você tiver dúvidas sobre a utilização do material a partir desses arquivos, você poderá consultar a descrição detalhada do desenvolvimento da biblioteca em um dos artigos da lista abaixo ou fazer sua pergunta nos comentários deste artigo.

Lista de artigos (capítulos) da sexta parte:


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

Arquivos anexados |
Expert Advisor multiplataforma: Ordens Expert Advisor multiplataforma: Ordens
MetaTrader 4 e MetaTrader 5 usam regras diferentes para o processamento de pedidos de negociação. Este artigo discute a possibilidade de utilizar o objeto de classe que representa a transação para processamento pelo servidor, graças a isso o Expert Advisor poderá trabalhar com elas independentemente da versão da plataforma de negociação e o modo usado.
Expert Advisor multiplataforma: reutilização de componentes a partir da Biblioteca padrão MQL5 Expert Advisor multiplataforma: reutilização de componentes a partir da Biblioteca padrão MQL5
Na biblioteca padrão MQL5, existem alguns componentes que podem ser úteis em versões de EAs MQL4 multiplataforma. Este artigo descreve um método para a criação de alguns componentes da biblioteca padrão MQL5 compatíveis com o compilador MQL4.
Estudando a Classe CCanvas. Anti-aliasing e Sombras Estudando a Classe CCanvas. Anti-aliasing e Sombras
Um algoritmo anti-aliasing da classe CCanvas é a base para todas as construções onde o antisserrilhamento está sendo usado. O artigo contém informações sobre como este algoritmo opera e fornece exemplos relevantes de visualização. Ele também abrange as sombras desenhadas dos objetos gráficos e tem um algoritmo detalhadamente desenvolvido para desenhar sombras nas canvas. A análise numérica da biblioteca ALGLIB é usada para os cálculos.
Expert Advisor multiplataforma: Introdução Expert Advisor multiplataforma: Introdução
Este artigo descreve um método que permite desenvolver rápida e facilmente um Expert Advisor multiplataforma. O método proposto combina as características, comuns para ambas as versões, numa classe e desenvolve a implementação para funções incompatíveis nas classes herdadas.