Discussão do artigo "Melhoramos o trabalho com Painéis, adicionando transparência, alterando a cor do plano de fundo e herdando da CAppDialog/CWndClient"

 

Novo artigo Melhoramos o trabalho com Painéis, adicionando transparência, alterando a cor do plano de fundo e herdando da CAppDialog/CWndClient foi publicado:

Continuamos a estudar o trabalho com a CAppDialog. Agora, aprenderemos a como definir a cor de fundo, de borda e de barra de título para o painel gráfico. Consideraremos passo a passo como adicionar transparência à janela do aplicativo ao movê-la no gráfico. Em seguida, analisaremos a criação de descendentes da CAppDialog ou da CWndClient e veremos novas sutilezas ao trabalhar com controles. Finalmente, olharemos de uma nova perspectiva os novos Projetos.

Primeiro, vou mostrar o que pode ser feito para o painel baseado na classe CAppDialog (este é um exemplo do código "Live panel.mq5").

Live panel

Esta animação mostra que, se você mover o painel, apenas permanece a borda externa. Durante o movimento, a borda externa muda de cor aleatoriamente. Concluído o movimento, o formulário se torna normal novamente, pois, na área de trabalho, aparece o sombreamento da tela de fundo.

Autor: Vladimir Karputov

 

Fórum sobre negociação, sistemas de negociação automatizados e teste de estratégias de negociação

Discussão do artigo "Como criar um painel gráfico de qualquer complexidade e como ele funciona"

Rashid Umarov, 2018.04.23 10:30 AM

O clique duplo são dois cliques com um intervalo de tempo muito pequeno entre eles. Portanto, ele pode ser tratado da mesma forma que um clique normal - você só precisa adicionar uma variável estática a OnChartEvent. Dê uma olhada no exemplo em https://www.mql5.com/pt/docs/constants/chartconstants/enum_chartevents e faça algo parecido com isto:

....

Vamos mostrar, por exemplo, como adicionar o tratamento de clique duplo ao painel. Vamos fazer edições na classe CMyWndClient



1. Substituir o método virtual OnDblClick, que vem do ancestral CWnd.

class CMyWndClient : public CWndClient
  {
private:
   CButton           m_button1;                       // o objeto botão
   CButton           m_button2;                       // o objeto botão
   //--- tamanho da rolagem
   int               m_scroll_size;                   // scroll_size
   //--- armazenar o proprietário
   CAppDialog        m_owner;                         // proprietário
   //--- ocultar o invisível
   bool              m_hide_invisble;
   //---
   bool              AddButton1(void);
   bool              AddButton2(void);
protected:
   //--- manipuladores dos eventos dos controles dependentes
   void              OnClickButton1(void);
   void              OnClickButton2(void);
   void              OnShowScrollH(void);
   virtual bool      OnScrollLineRight(void);
   virtual bool      OnScrollLineLeft(void);
   virtual bool      OnDblClick(void);
.....
//+------------------------------------------------------------------+
//|| Substituir o tratamento do evento OnDblClick
//+------------------------------------------------------------------+
bool CMyWndClient::OnDblClick(void)
  {
   Print(__FUNCTION__);
   return ColorBackground(GetRandomColor());
  }

2. Adicionar o processamento desse evento

//+------------------------------------------------------------------+
//| Tratamento de eventos|
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CMyWndClient)
ON_EVENT(ON_CLICK,m_button1,OnClickButton1)
ON_EVENT(ON_CLICK,m_button2,OnClickButton2)
ON_EVENT(ON_DBL_CLICK,this,OnDblClick)
ON_EVENT(ON_SHOW,m_scroll_h,OnShowScrollH)
EVENT_MAP_END(CWndClient)

3. No arquivo de aplicativo MyWndClient.mq5, adicione linhas para capturar o evento DoubleClick

//+------------------------------------------------------------------+
//| Função de evento de gráfico especializado|
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // ID do evento 
                  const long& lparam,   // parâmetro de evento do tipo longo
                  const double& dparam, // parâmetro de evento do tipo double
                  const string& sparam) // parâmetro de evento do tipo string
  {
//--- hora do último clique do mouse
   static uint last_click=0;
//--- clicar com o botão esquerdo do mouse no gráfico
   if(id==CHARTEVENT_OBJECT_CLICK)   
     {
      uint click_time=GetTickCount();
      //Print("click_time=",click_time);
      //Print("Coordenadas do clique do mouse no gráfico: x = ",lparam," y = ",dparam);
      if(click_time-last_click<dbl_click_time)
        {
         PrintFormat("DoubleClick! time=%d msec",click_time-last_click);
         // enviar o evento ON_DBL_CLICK para a área do cliente - deixar que ele o manipule 
         EventChartCustom(CONTROLS_SELF_MESSAGE,ON_DBL_CLICK,ClientArea.Id(),dparam,ClientArea.Name());       
        }
      last_click=click_time;
      //---
     }
   AppWindow.ChartEvent(id,lparam,dparam,sparam);
  }

Adicione o tempo entre os cliques em milissegundos ao parâmetro externo do aplicativo - se for menor que o tempo especificado, o evento DoubleClick será gerado.

//+------------------------------------------------------------------+
//|MyWndClient.mq5
//| Copyright 2018, MetaQuotes Software Corp.
//| https://www.mql5.com
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.001"
#property description "Aplicativo MyWndClient baseado na classe CMyWndClient"
#property description "Adicionados botões para definir a cor do plano de fundo e do cabeçalho"
#include "MyWndClient.mqh"
#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
//--- parâmetro de entrada
input bool InpTwoButtonsVisible=false; // largura do painel
input bool HideInvisble=false;         // ocultar o invisível
input uint dbl_click_time=500;         // período entre cliques em mseg

Os arquivos estão anexados. Você pode visualizá-los individualmente ou extrair o arquivo para a pasta MQL5/Experts.

Arquivos anexados:
 

O vídeo mostra que o evento de clique duplo só é acionado no painel. Fora do painel, o evento não é capturado.

Arquivos anexados:
 
Gostaria de saber se é possível tornar o painel opaco para o mouse. Ao arrastar e até mesmo editar no campo Editar, os objetos no gráfico ficam grudados, parando de arrastar.
 
Photic:
Gostaria de saber se é possível tornar o painel opaco para o mouse. Ao arrastar e até mesmo editar no campo Editar, os objetos no gráfico ficam grudados, parando de arrastar.

E mais. Com muita frequência, as paradas e as retiradas ficam presas dessa forma.

Você pode tentar resolver isso alterando a visualização para virtual - se as linhas não estiverem selecionadas para edição, o movimento do painel não as prenderá.

E também... seria legal saber como emitir informações atuais (por exemplo, o lucro na compra ou venda aberta ou qualquer informação atual em mudança) na própria janela do painel?

Talvez alguém tenha feito algo semelhante. MT4.

 
Vyacheslav Nekipelov:

***

E mais uma coisa... seria legal saber como fazer a saída das informações atuais (por exemplo, lucro na compra ou venda aberta ou qualquer mudança nas informações atuais) na própria janela do painel?

Talvez alguém tenha feito algo semelhante. MT4.

Você pode enviar qualquer coisa para o painel - só precisa escrever novos métodos responsáveis pela saída.

Mas isso não é interessante para um terminal antigo.

Aqui está um exemplo de um painel que exibe informações sobre posições: https: //www.mql5.com/ru/code/16931.
 
Vladimir Karputov:
Aqui está um exemplo de um painel que exibe informações de posição: https: //www.mql5.com/ru/code/16931

Muito obrigado) Terei que dar uma olhada nesse tópico em algum momento.

 
Muito boa matéria!
 

Obrigado, Vladimir, por este artigo e pelo anterior. Aprendi alguns pontos novos e úteis para mim.

Você não conseguiu ver por que o cabeçalho é colorido junto com os botões de fechar pela primeira vez, mas depois de minimizar/descolar as alterações de cor não afetam mais os controles?


 
Vasiliy Pushkaryov:

Obrigado, Vladimir, por este artigo e pelo anterior. Aprendi alguns pontos novos e úteis para mim.

Você não conseguiu ver por que o cabeçalho é colorido junto com os botões de fechar pela primeira vez, mas depois de minimizar/descolar as alterações de cor não afetam mais os controles?


Descobri o motivo. Observe a largura do cabeçalho após a primeira execução e após minimizar/desmodelar:

Largura do cabeçalho após a primeira execução

Fig. 1: Largura do cabeçalho após o primeiro lançamento


Largura do cabeçalho depois de recolhido/desdobrado

Figura 2: Largura do cabeçalho após minimizar/desdobrar


 
Vladimir Karputov:

Descobri a causa. Observe a largura do cabeçalho após a primeira execução e após a minimização/não modificação:


Ótimo, obrigado. Adicionei uma linha ao código e, ao clicar no botão, o cabeçalho começou a ficar completamente colorido.

//+------------------------------------------------------------------+
//| Manipulador de eventos|
//+------------------------------------------------------------------+
void CLivePaneButtonClicks::OnClickButton2(void)
  {
   string prefix=Name();
   int total=ExtDialog.ControlsTotal();
   for(int i=0;i<total;i++)
     {
      CWnd*obj=ExtDialog.Control(i);
      string name=obj.Name();
      //---
      if(name==prefix+"Caption")
        {
         CEdit *edit=(CEdit*) obj;
         color clr=(color)GETRGB(XRGB(rand()%255,rand()%255,rand()%255));
         edit.ColorBackground(clr);
         edit.Width(336);
         ChartRedraw();
         return;
        }
     }
  }

Agora você pode simplesmente substituir esse ponto nas funções

virtual void Minimize(void);
virtual void Maximize(void);

E tudo ficará bem.

Mas, com sua permissão, vou lembrá-lo algumas vezes sobre esse recurso nas ramificações com novas compilações. Talvez eles o corrijam.