Discussão do artigo "Deixando o gráfico mais interessante — Adicionando uma tela de fundo"

 

Novo artigo Deixando o gráfico mais interessante — Adicionando uma tela de fundo foi publicado:

Muitas estações de trabalho contém alguma imagem representativa e que mostra algo sobre o usuário, estas imagens deixam o ambiente de trabalho mais bonito e animador,. Aprenda como deixar o gráfico mais interessante colocando um papel de parede nele.

Muitas estações de trabalho contém alguma imagem representativa e que mostra algo sobre o usuário, estas imagens deixam o ambiente de trabalho mais bonito e animador, as pessoas sempre procuram escolher as melhores e mais bonitas imagens para colocar como papel de parede, mas quando abrimos a plataforma de negociação, a coisa se torna chata e sem graça, onde tudo que temos são representações gráficas de dados numéricos.

 


Você pode ficar olhando uma foto por longos períodos sem se cansar, mas ficar alguns minutos olhando um gráfico numérico é muito cansativo, então vamos deixar as coisas mais interessantes, de forma que possamos olhar e analisar o gráfico enquanto a imagem no fundo nos motiva e nos remete a algo de bom ....

Autor: Daniel Jose

 
Muito bom seu artigo Daniel, para os agentes de Investimento colocarem nos escritórios então fica top. O MT5 tem suas limitações, claro, mas é possível fazer bastante coisa na parte gráfica que acaba meia sub utilizada.
 
Muito bom
 
O utilitário está funcionando perfeitamente, mas alguns indicadores usando o OnChartEvent deixam de funcionar e podem ser clicados quando eu aplico este EA para fundo
 
Arpit Tailang # : O utilitário funciona perfeitamente, além de alguns sinalizadores que a OnChartEvent usa para funcionar e se tornar desinstalável quando eu aplico esta EA em segundo plano

De hecho, aconteceu algo envolvendo as atualizações do MT5, que transformam o Wallpaper em algo diferente do esperado e mostrado no artigo, já que o correto que ele seja exibido no FUNDO GRÁFICO, pois na classe C_WallPaper você encontrará a seguinte linha:

ObjectSetInteger ( Terminal.Get_ID(), szName, OBJPROP_BACK , true ); 

Isso informa que o objeto terá que ficar no fundo, mais estranhamente, ele está vindo para a frente, por conta disto o OBJETO que recebe ou BitMap começa a receber os cliques, uma solução seria aumentar o Status de todos os objetos, ou tentar baixar o status do Bitmap, no caso esta segunda seria mais simples, isto seria conseguido alterando valor da propriedade OBJPROP_ZORDER no objeto que recebe o Wallpaper, Tentei as duas soluções, mas não consegui estabilizar a coisa toda de forma a corrigir o problema, portanto, e INFELIZMENTE, o papel de parede deve ser descartado por hora ... Se você prestar atenção, verá que a imagem do bitmap estará sendo plotada no corpo das velas, indicando que o objeto bitmap está em primeiro plano, mais uma vez este não é o comportamento esperado por causa da linha de código acima, por causa disto acontece de receber todo e qualquer evento de clique ... 🙁

 
A possibilidade de utilizar na função que apresento nesse código
//+------------------------------------------------------------------+
//|                                                   SelectFile.mqh |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
#include <Controls\Edit.mqh>
#include <Controls\ListView.mqh>
#include <Controls\CheckGroup.mqh>
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
#define  INDENT_LEFT             (4)             // indent from left
#define  INDENT_TOP              (4)             // indent from top
#define  INDENT_RIGHT            (4)             // indent from right
#define  BUTTON_WIDTH            (60)     // size by X coordinate
#define  BUTTON_HEIGHT   (20)       // size by Y coordinate
#define  EDIT_HEIGHT             (20)       // size by Y coordinate
#define  COMMON_WIDTH            (90)       // size by X coordinate
//+------------------------------------------------------------------+
//| Class CSelectFile                                                |
//+------------------------------------------------------------------+
class CSelectFile : public CDialog
  {
   CEdit             m_filename;
   CButton           m_button_ok;
   CButton           m_button_cancel;
   CListView         m_filelist;
   CCheckGroup       m_common;
   string            m_instance_id,
                     m_files[],
                     m_folders[],
                     m_prevfolder,
                     m_cfolder,
                     m_fullname;
   int               m_numberfiles,
                     m_numberfolders,
                     m_totalfiles,
                     m_fileflag,
                     m_pressbutton;
protected:
   CChart            m_chart;
public:
                     CSelectFile(void);
                    ~CSelectFile(void);
   virtual bool      Create(const long chart,const string name,const int x1,const int y1,const int x2,const int y2);
   int               ChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
   string            Filename(){ m_pressbutton=0; return(m_fullname);}
   int               FileFlag(){ return(m_fileflag);}
protected:
   void              OnClickButtonOK(void);
   void              OnClickButtonCancel(void);
   virtual void      OnClickButtonClose(void);
   void              OnChangeList(void);
   void              OnCheckCommon(void);
   void              SetFolder(string m_fol="");
  };
//+------------------------------------------------------------------+
CSelectFile::CSelectFile(void)
  {
   m_instance_id=IntegerToString(rand(),5,'0');
   m_fileflag=0;
   m_pressbutton=0;
   m_fullname="";
   m_cfolder="";
   m_prevfolder="";
   m_numberfiles=0;
   m_numberfolders=0;
  }
//+------------------------------------------------------------------+
CSelectFile::~CSelectFile(void)
  {
   ArrayFree(m_folders);
   ArrayFree(m_files);
   m_chart.Detach();
   CDialog::Destroy();
  }
//+------------------------------------------------------------------+
bool CSelectFile::Create(const long chart,const string name,const int x1,const int y1,const int x2,const int y2)
  {
   if(x2-x1<280 || y2-y1<200) return(false);
   m_chart_id=chart;
   m_name=name;
   m_subwin=0;
//--- initialize chart object
   m_chart.Attach(chart);
//--- specify object and mouse events
   if(!m_chart.EventObjectCreate() || !m_chart.EventObjectDelete() || !m_chart.EventMouseMove())
     {
      Print("CSelectFile: object events specify error");
      m_chart.Detach();
      return(false);
     }
//--- call method of the parent class
   if(!CDialog::Create(m_chart.ChartId(),m_instance_id,m_subwin,x1,y1,x2,y2))
     {
      Print("CSelectFile: expert dialog create error");
      m_chart.Detach();
      return(false);
     }
   Caption(name);
//--- create dependent controls
//--- create list of files
   int _x1=INDENT_LEFT;
   int _y1=INDENT_TOP;
   int _x2=ClientAreaWidth()-INDENT_RIGHT;
   int _y2=_y1+(ClientAreaHeight()-INDENT_TOP*5-EDIT_HEIGHT*2);
   if(!m_filelist.Create(m_chart_id,m_name+"FileList",m_subwin,_x1,_y1,_x2,_y2)) return(false);
   if(!Add(m_filelist)) return(false);
   m_prevfolder="";
   m_cfolder="";
   SetFolder(m_cfolder);
//--- create field of filename
   _x1=INDENT_LEFT;
   _y1=INDENT_TOP+_y2;
   _x2=ClientAreaWidth()-INDENT_RIGHT;
   _y2=_y1+EDIT_HEIGHT+INDENT_TOP;
   if(!m_filename.Create(m_chart_id,m_name+"Filename",m_subwin,_x1,_y1,_x2,_y2)) return(false);
   if(!Add(m_filename)) return(false);
//--- create common check
   _x1=INDENT_LEFT;
   _y1=INDENT_TOP+_y2;
   _x2=_x1+COMMON_WIDTH;
   _y2=_y1+EDIT_HEIGHT;
   if(!m_common.Create(m_chart_id,m_name+"Common",m_subwin,_x1,_y1,_x2,_y2)) return(false);
   if(!Add(m_common)) return(false);
   if(!m_common.AddItem("Common",1)) return(false);
//--- create button Cancel
   _x1=ClientAreaWidth()-INDENT_RIGHT-BUTTON_WIDTH;
   _x2=_x1+BUTTON_WIDTH;
   _y2=_y1+BUTTON_HEIGHT;
   if(!m_button_cancel.Create(m_chart_id,m_name+"Cancel",m_subwin,_x1,_y1,_x2,_y2)) return(false);
   if(!m_button_cancel.Text("Cancel")) return(false);
   if(!Add(m_button_cancel)) return(false);
//--- create button OK
   _x1=_x1-INDENT_RIGHT-BUTTON_WIDTH;
   _x2=_x1+BUTTON_WIDTH;
   if(!m_button_ok.Create(m_chart_id,m_name+"OK",m_subwin,_x1,_y1,_x2,_y2)) return(false);
   if(!m_button_ok.Text("OK")) return(false);
   if(!Add(m_button_ok)) return(false);
//----
   m_pressbutton=0;
   m_fullname="";
   m_chart.Redraw();
//----
   if(Id(m_subwin*CONTROLS_MAXIMUM_ID)>CONTROLS_MAXIMUM_ID)
     {
      Print("CSelectFile: too many objects");
      return(false);
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
int CSelectFile::ChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
   if(id==(ON_CLICK+CHARTEVENT_CUSTOM) && lparam==m_button_ok.Id()) OnClickButtonOK();
   else if(id==(ON_CLICK+CHARTEVENT_CUSTOM) && lparam==m_button_cancel.Id()) OnClickButtonCancel();
   else if(id==(ON_CHANGE+CHARTEVENT_CUSTOM) && lparam==m_filelist.Id()) OnChangeList();
   else if(id==(ON_CHANGE+CHARTEVENT_CUSTOM) && lparam==m_common.Id()) OnCheckCommon();
   else if(!CDialog::OnEvent(id,lparam,dparam,sparam)) return(0);
   m_chart.Redraw();
   return(m_pressbutton);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CSelectFile::OnClickButtonOK(void)
  {
   m_fullname=m_filename.Text();
   StringTrimLeft(m_fullname);
   StringTrimRight(m_fullname);
   if(StringLen(m_fullname)>0)
     {
      m_fullname=m_cfolder+m_fullname;
      m_pressbutton=1;
     }
  }
//+------------------------------------------------------------------+
void CSelectFile::OnClickButtonCancel(void)
  {
   m_pressbutton=-1;
   m_fullname="";
  }
//+------------------------------------------------------------------+
void CSelectFile::OnClickButtonClose(void)
  {
   OnClickButtonCancel();
  }
//+------------------------------------------------------------------+
void CSelectFile::OnChangeList(void)
  {
   int i=(int)m_filelist.Value();
   if(i<0) return;
   else if(i==0)
     {
      string s;
      if(m_cfolder==m_prevfolder || s==m_prevfolder)
        {
         m_cfolder="";
         m_prevfolder=m_cfolder;
         SetFolder(m_cfolder);
        }
      else
        {
         s="\\"+m_prevfolder;
         StringReplace(m_cfolder,s,"\\");
         m_prevfolder=m_cfolder;
         if(m_cfolder=="\\") m_cfolder="";
         SetFolder(m_cfolder+"\\");
        }
      m_filename.Text("");
     }
   else if(i<m_numberfolders)
     {
      m_prevfolder=m_folders[i];
      m_cfolder+=m_prevfolder;
      SetFolder(m_cfolder+"\\");
      m_filename.Text("");
     }
   else m_filename.Text(m_filelist.Select());
  }
//+------------------------------------------------------------------+
void CSelectFile::OnCheckCommon(void)
  {
   m_fileflag=m_common.Value()>0?FILE_COMMON:0;
   if(m_fileflag==0)
     {
      m_prevfolder="";
      m_cfolder="";
      SetFolder(m_cfolder);
      m_filename.Text("");
     }
   else
     {
      m_prevfolder="";
      m_cfolder="";
      SetFolder(m_cfolder);
      m_filename.Text("");
     }
  }
//+------------------------------------------------------------------+
void CSelectFile::SetFolder(string fol="")
  {
   string fl,ff,fld=fol;
   StringReplace(fld,"\\\\","\\");
   int i;
   m_filelist.Select(0);
   m_filelist.ItemsClear();
   ArrayResize(m_folders,1);
   ArrayResize(m_files,1);
   if(fld=="Files\\") fl=""; else fl=fld;
   //---folders
   long  hfind=FileFindFirst(fl+"*",ff,m_fileflag);
   if(hfind==INVALID_HANDLE)
     {//empty folder
      m_numberfiles=0;
      m_numberfolders=1;
      m_folders[0]="Files\\"+fld;
      m_filelist.ItemAdd(m_folders[0]);
      m_totalfiles=0;
     }
   else
     {
      m_numberfiles=0;
      m_numberfolders=0;
      do
        {
         if(StringFind(ff,"\\")>1) m_numberfolders++;
         m_numberfiles++;
        }
      while(FileFindNext(hfind,ff));
      FileFindClose(hfind);
      ArrayResize(m_folders,m_numberfolders+1);
      hfind=FileFindFirst(fl+"*",ff,m_fileflag);
      if(hfind==INVALID_HANDLE) return;
      m_numberfolders=1;
      do
        {
         if(StringFind(ff,"\\")>1){ m_folders[m_numberfolders]=ff; m_numberfolders++;}
        }
      while(FileFindNext(hfind,ff));
      FileFindClose(hfind);
      if(fld=="")
        {
         m_folders[0]="Files\\";
         ff="";
        }
      else
        {
         m_folders[0]=fld;
         ff="Files\\";
        }
      m_filelist.ItemAdd(ff+m_folders[0]);
      int nn=m_numberfolders;
      for(i=1; i<nn; i++) m_filelist.ItemAdd(m_folders[i]);
      //---files
      hfind=FileFindFirst(fl+"*.*",ff,m_fileflag);
      m_numberfiles=0;
      do
        {
         if(StringFind(ff,"\\")<0) m_numberfiles++;
        }
      while(FileFindNext(hfind,ff));
      FileFindClose(hfind);
      if(m_numberfiles>0)
        {
         ArrayResize(m_files,m_numberfiles);
         m_numberfiles=0;
         hfind=FileFindFirst(fl+"*.*",ff,m_fileflag);
         if(hfind!=INVALID_HANDLE)
           {
            do
              {
               if(StringFind(ff,"\\")<0) { m_files[m_numberfiles]=ff; m_numberfiles++;}
              }
            while(FileFindNext(hfind,ff));
            FileFindClose(hfind);
           }
         for(i=0; i<m_numberfiles; i++) m_filelist.ItemAdd(m_files[i]);
        }
      m_totalfiles=m_numberfiles+m_numberfolders+1;
     }
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                              Test_SelectFile.mq5 |
//+------------------------------------------------------------------+
#include <class_SelectFile.mqh>
//+------------------------------------------------------------------+
CSelectFile *SelectFile=NULL;
//+------------------------------------------------------------------+
int OnInit()
  {
   SelectFile=new CSelectFile();
   if(!SelectFile.Create(0,"Select a file",20,20,350,300)) return(-1);
   return(0);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(SelectFile!=NULL) delete SelectFile;
  }
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // event ID  
                  const long& lparam,   // event parameter of the long type
                  const double& dparam, // event parameter of the double type
                  const string& sparam) // event parameter of the string type
  {
   if(SelectFile!=NULL)
     {
      int key=SelectFile.ChartEvent(id,lparam,dparam,sparam);
      if(key>0)
        {//press button OK
         string file=SelectFile.Filename();
         int flag=SelectFile.FileFlag();
         delete SelectFile;
         SelectFile=NULL;
         Print("The selected file - ",flag==FILE_COMMON?"[Common]":"",file);
         int handle=FileOpen(file,flag);
         if(handle>0)
           {
            Print(file," - open");
            FileClose(handle);
           }
         else Print(file," - failed to open");
        }
      else if(key<0)
        {//press button Cancel
         delete SelectFile;
         SelectFile=NULL;
         Print("No file selected");
        }
     }
   if(SelectFile==NULL)
     {
      Print("The program is completed");
      ExpertRemove();
     }
  }
//+------------------------------------------------------------------+
tipo mudar a imagem no gráfico utilizando essa funcao. Queria saber se e possível, se não der e for complexo eu evito quebra meus neurônios kkkkkk.
 
Daniel Jose #:

De hecho, aconteceu algo envolvendo as atualizações do MT5, que transformam o Wallpaper em algo diferente do esperado e mostrado no artigo, já que o correto que ele seja exibido no FUNDO GRÁFICO, pois na classe C_WallPaper você encontrará a seguinte linha:

Isso informa que o objeto terá que ficar no fundo, mais estranhamente, ele está vindo para a frente, por conta disto o OBJETO que recebe ou BitMap começa a receber os cliques, uma solução seria aumentar o Status de todos os objetos, ou tentar baixar o status do Bitmap, no caso esta segunda seria mais simples, isto seria conseguido alterando valor da propriedade OBJPROP_ZORDER no objeto que recebe o Wallpaper, Tentei as duas soluções, mas não consegui estabilizar a coisa toda de forma a corrigir o problema, portanto, e INFELIZMENTE, o papel de parede deve ser descartado por hora ... Se você prestar atenção, verá que a imagem do bitmap estará sendo plotada no corpo das velas, indicando que o objeto bitmap está em primeiro plano, mais uma vez este não é o comportamento esperado por causa da linha de código acima, por causa disto acontece de receber todo e qualquer evento de clique ... 🙁


Daniel, 

Será que se colocar um temporizador e rodar uma função para desabilitar e habilitar o wallpaper novamente ou alguma coisa que "reafirme" a função colocando o wallpaper no fundo (back) ?
Um painel GUI que eu utilizo, tive que partir para esse solução. Alguns elementos gráficos precisam ser deletados e criados novamente para que fiquem no fundo ou na frente dependendo do tipo de objeto.

 

Daniel, parabéns pelo trabalho, uso MT4 há anos e com a limitação de ativos pelos provedores de liquidez e corretoras fui forçado a migrar para o MT5 e há tempos procurava algo para customizar com imagens meu template assim como uso no MT4 e tenho o Chart Wall para o MT4, segue link para download no MQL5: https://www.mql5.com/pt/market/product/2767?source=External%3Ahttps%3A%2F%2Fwww.google.com%2F

E vídeo no Youtube para auxiliar quem assim precisar: https://www.youtube.com/watch?v=AMNhI45EZ2o

Mais uma vez, parabéns pelo trabalho de fazer e deixar código aberto.

Sucesso.

COMO MUDAR A IMAGEM DE FUNDO NO MT4 | COLOQUE UM BACKGROUND NO SEU META TRADER 4
COMO MUDAR A IMAGEM DE FUNDO NO MT4 | COLOQUE UM BACKGROUND NO SEU META TRADER 4
  • 2021.06.02
  • www.youtube.com
Aprenda a deixar seu meta trader 4 personalizado, escolha a imagem que desejar e use como plano de fundo, simples e fácil. No vídeo mostro passo a passo como...
 

Olá! Daniel. Beleza? 

Desculpa por ressucitar o tópico... estou usando seu código no meu E.A e estou deparado com o seguinte erro:"arquivo não encontrato", já li o código várias vezes e não consigo encontrar o erro,  fiz todos os passos que vc deixou... E também usei os arquivos de imagens que deixou para download e deu o mesmo erro. Teria como me ajudar? Desde já agradeço! 

 
leandronetto011 #:

Olá! Daniel. Beleza? 

Desculpa por ressucitar o tópico... estou usando seu código no meu E.A e estou deparado com o seguinte erro:"arquivo não encontrato", já li o código várias vezes e não consigo encontrar o erro,  fiz todos os passos que vc deixou... E também usei os arquivos de imagens que deixou para download e deu o mesmo erro. Teria como me ajudar? Desde já agradeço! 

Não entendi 🤔🤔 ... você deve pegar e descompactar o arquivo na pasta MQL5. Para fazer isto de forma correta: Abra o MetaEditor. No canto direito você irá ver o navegador das pastas. Clique na RAIZ ( MQL5 ) com o botão direito, Selecione ABRIR PASTA. O Explorer será aberto na pasta MQL5. Nesta pasta você deverá descompactar o arquivo ZIP. Assim as imagens serão encontradas quando você for lançar o sistema no gráfico.