photo
+ Responder ao Tópico
Resultados de 1 a 2 de 2

Thread: Tipos personalizados

  1. #1 Fechar a publicação
    Banned
    Data de afiliação
    Aug 2018
    Postagens
    342
    Obrigado
    91
    Agradecimentos 525 Tempos em 242 Postagens

    Tipos personalizados

    Tipos personalizados
    A palavra-chave typedef em linguagem C++ permite criar tipos personalizados de dados, basta definir o nome do tipo de dados para um tipo de dados existente. Ao fazer isto, não é criado um novo tipo de dados, mas sim é definido um novo nome para o tipo existente. Graças ao uso de tipos personalizados, você pode tornar o programa mais flexível, basta suficiente alterar as instruções typedef usando os macros de substituição (#define). Usar os tipos personalizados também pode melhorar a legibilidade do código, uma vez que, para os tipos de dados padrão, você pode usar seus próprios nomes descritivos com ajuda de typedef. Formato geral para escrever instruções a fim de criar um tipo personalizado:

    typedef tipo novo_nome;

    Aqui o elemento tipo representa qualquer tipo de dados válido, enquanto o elemento novo_nome é o nome novo para este tipo. É importante notar que o novo nome é definido apenas como um complemento para o nome existente do tipo e não para substituí-lo. Na linguagem MQL5, você pode criar um ponteiro para a função, usando typedef.

    Ponteiro para a função
    Ponteiro para a função geralmente é determinado pelo formato de registro

    typedef tipo_de_resultado_de_função (*Nome_de_tipo_de_função)(lista_de_tipos_de_par metros_de_entrada);

    onde, após a palavra typedef, é definida a assinatura da função, isto é, o número e tipo de parâmetros de entrada, bem como o tipo de resultado a ser retornado pela função. Aqui está uma explicação de como criar e usar um ponteiro para uma função:

    // --- declaramos o ponteiro para uma função que aceita dois parâmetros do tipo int
    typedef int (*TFunc)(int,int);
    //--- TFunc é o tipo, e nós podemos declarar o ponteiro-variável para a função
    TFunc func_ptr; // ponteiro para a função
    //--- declaramos as funções que correspondem à descrição TFunc
    int sub(int x,int y) { return(x-y); } // / subtração de um número a partir de outro
    int add(int x,int y) { return(x+y); } // adição de dois números
    int neg(int x) { return(~x); } // inversão de bits na variável
    //--- você pode armazenas o endereço da função na variável func_ptr, para chamá-la no futuro
    func_ptr=sub;
    Print(func_ptr(10,5));
    func_ptr=add;
    Print(func_ptr(10,5));
    func_ptr=neg; // erro: neg não tem o tipo int (int,int)
    Print(func_ptr(10)); // erro: deve haver dois parâmetros

    Neste exemplo, à variável func_ptr podem ser atribuídas as funções sub e add, uma vez que cada uma delas tem dois parâmetros de entrada do tipo int, conforme especificado na definição do ponteiro para a função TFunc. Aqui à função neg não pode ser atribuído o ponteiro func_ptr, uma vez que sua assinatura é diferente.

    Organização dos modelos de eventos na interface personalizada
    Usando os ponteiros para a função você pode facilmente construir a manipulação de eventos ao criar a interface personalizada. Mostraremos um exemplo a partir da seção CButton sobre como criar botões e adicionar neles uma função para processamento do carregamento do botão. Em primeiro lugar, definimos o ponteiro para a função TAction, ela será chamada pressionando um botão, e criaremos três funções em conformidade com a descrição TAction.

    //--- criamos o tipo personalizado de função
    typedef int(*TAction)(string,int);
    //+------------------------------------------------------------------+
    //| Abre o arquivo |
    //+------------------------------------------------------------------+
    int Open(string name,int id)
    {
    PrintFormat("Função chamada %s (name=%s id=%d)",__FUNCTION__,name,id);
    return(1);
    }
    //+------------------------------------------------------------------+
    //| Salva o arquivo |
    //+------------------------------------------------------------------+
    int Save(string name,int id)
    {
    PrintFormat("Função chamada %s (name=%s id=%d)",__FUNCTION__,name,id);
    return(2);
    }
    //+------------------------------------------------------------------+
    //| Fecha o arquivo |
    //+------------------------------------------------------------------+
    int Close(string name,int id)
    {
    PrintFormat("Função chamada %s (name=%s id=%d)",__FUNCTION__,name,id);
    return(3);
    }


    Logo realizamos a classe MyButton a partir do CButton, em que adicionamos o membro TAction que, por sua vez, é o ponteiro para a função.

    //+------------------------------------------------------------------+
    //| Criamos nossa classe de botão com a função de manipulador de eventos |
    //+------------------------------------------------------------------+
    class MyButton: public CButton
    {
    private:
    TAction m_action; // manipulador de eventos para o gráfico
    public:
    MyButton(void){}
    ~MyButton(void){}
    //--- construtor com indicação do texto do botão e ponteiro para a função a fim de manipular eventos
    MyButton(string text, TAction act)
    {
    Text(text);
    m_action=act;
    }
    //--- definição de função que será chamada a partir do manipulador de eventos OnEvent()
    void SetAction(TAction act){m_action=act;}
    //--- manipulador padrão de eventos de gráfico
    virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) override
    {
    if(m_action!=NULL & lparam==Id())
    {
    //--- chamamos o manipulador próprio m_action()
    m_action(sparam,(int)lparam);
    return(true);
    }
    else
    //--- retornamos o resultado da chamada do manipulador a partir da classe mão CButton
    return(CButton::OnEvent(id,lparam,dparam,sparam));
    }
    };

    Em seguida, criamos a classe derivada CControlsDialog a partir da CAppDialog, à qual adicionamos a matriz m_buttons para armazenas os botões do tipo MyButton, bem como os métodos AddButton(MyButton &button) e CreateButtons().

    //+------------------------------------------------------------------+
    //| Classe CControlsDialog |
    //| Designação: painel gráfico para controle do aplicativo |
    //+------------------------------------------------------------------+
    class CControlsDialog : public CAppDialog
    {
    private:
    CArrayObj m_buttons; // matriz de botões
    public:
    CControlsDialog(void){};
    ~CControlsDialog(void){};
    //--- create
    virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2) override;
    //--- adição de botão
    bool AddButton(MyButton &button){return(m_buttons.Add(GetPointer(button))) ;m_buttons.Sort();};
    protected:
    //--- criação de botões
    bool CreateButtons(void);
    };
    //+------------------------------------------------------------------+
    //| Criação do objeto CControlsDialog no gráfico |
    //+------------------------------------------------------------------+
    bool CControlsDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
    {
    if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2, y2))
    return(false);
    return(CreateButtons());
    //---
    }
    //+------------------------------------------------------------------+
    //| defines |
    //+------------------------------------------------------------------+
    //--- indents and gaps
    #define INDENT_LEFT (11) // indent from left (with allowance for border width)
    #define INDENT_TOP (11) // indent from top (with allowance for border width)
    #define CONTROLS_GAP_X (5) // gap by X coordinate
    #define CONTROLS_GAP_Y (5) // gap by Y coordinate
    //--- for buttons
    #define BUTTON_WIDTH (100) // size by X coordinate
    #define BUTTON_HEIGHT (20) // size by Y coordinate
    //--- for the indication area
    #define EDIT_HEIGHT (20) // size by Y coordinate
    //+------------------------------------------------------------------+
    //| Criação e adição de botões para o painel CControlsDialog |
    //+------------------------------------------------------------------+
    bool CControlsDialog::CreateButtons(void)
    {
    //--- cálculo de coordenadas de botões
    int x1=INDENT_LEFT;
    int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
    int x2;
    int y2=y1+BUTTON_HEIGHT;
    //--- adicionamos os objetos dos botões juntamente com os ponteiros para as funções
    AddButton(new MyButton("Open",Open));
    AddButton(new MyButton("Save",Save));
    AddButton(new MyButton("Close",Close));
    //--- criamos os botões graficamente
    for(int i=0;i<m_buttons.Total();i++)
    {
    MyButton *b=(MyButton*)m_buttons.At(i);
    x1=INDENT_LEFT+i*(BUTTON_WIDTH+CONTROLS_GAP_X);
    x2=x1+BUTTON_WIDTH;
    if(!b.Create(m_chart_id,m_name+"bt"+b.Text(),m_sub win,x1,y1,x2,y2))
    {
    PrintFormat("Failed to create button %s %d",b.Text(),i);
    return(false);
    }
    //--- adicionamos cada botão no recipiente CControlsDialog
    if(!Add(b))
    return(false);
    }
    //--- succeed
    return(true);
    }

    Agora podemos escrever o programa usando o painel de controle CControlsDialog, no qual são criados 3 botões "Open", "Save" e "Close". Ao pressionar o botão, é chamada a função correspondente que está escrita como um ponteiro para a função TAction.

    //--- declaramos o objeto no nível global para criá-lo automaticamente ao inciar o programa
    CControlsDialog MyDialog;
    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    //--- agora criamos o objeto no gráfico
    if(!MyDialog.Create(0,"Controls",0,40,40,380,344))
    return(INIT_FAILED);
    //--- executamos o aplicativo
    MyDialog.Run();
    //--- inicialização bem-sucedida do aplicativo
    return(INIT_SUCCEEDED);
    }
    //+------------------------------------------------------------------+
    //| Expert deinitialization function |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
    //--- destroy dialog
    MyDialog.Destroy(reason);
    }
    //+------------------------------------------------------------------+
    //| Expert chart event function |
    //+------------------------------------------------------------------+
    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
    {
    //--- para os eventos do gráfico, chamamos o manipulador a partir da classe mãe (neste caso, CAppDialog)
    MyDialog.ChartEvent(id,lparam,dparam,sparam);
    }

    A aparência do aplicativo em execução e os resultados dos botões pressionados são mostrados na imagem.

    Name:  panel_buttons (1).png
Views: 114
Size:  12.9 KB

    Though trading on financial markets involves high risk, it can still generate extra income in case you apply the right approach. By choosing a reliable broker such as InstaForex you get access to the international financial markets and open your way towards financial independence. You can sign up here.


  2. The Following User Says Thank You to forumforex For This Useful Post:

    Não registrado (1 )

  3. #2 Fechar a publicação
    Banned
    Data de afiliação
    Aug 2018
    Postagens
    342
    Obrigado
    91
    Agradecimentos 525 Tempos em 242 Postagens
    Código-fonte completo do programa

    //+------------------------------------------------------------------+
    //| Panel_Buttons.mq5 |
    //| Copyright 2017, MetaQuotes Software Corp. |
    //| https://www.mql5.com |
    //+------------------------------------------------------------------+

    #property copyright "Copyright 2017, MetaQuotes Software Corp."
    #property link "https://www.mql5.com"
    #property version "1.00"
    #property description "Painel com vários botões CButton"
    #include <Controls\Dialog.mqh>
    #include <Controls\Button.mqh>
    //+------------------------------------------------------------------+
    //| defines |
    //+------------------------------------------------------------------+
    //--- indents and gaps
    #define INDENT_LEFT (11) // indent from left (with allowance for border width)
    #define INDENT_TOP (11) // indent from top (with allowance for border width)
    #define CONTROLS_GAP_X (5) // gap by X coordinate
    #define CONTROLS_GAP_Y (5) // gap by Y coordinate
    //--- for buttons
    #define BUTTON_WIDTH (100) // size by X coordinate
    #define BUTTON_HEIGHT (20) // size by Y coordinate
    //--- for the indication area
    #define EDIT_HEIGHT (20) // size by Y coordinate

    //--- criamos o tipo personalizado de função
    typedef int(*TAction)(string,int);
    //+------------------------------------------------------------------+
    //| Abre o arquivo |
    //+------------------------------------------------------------------+
    int Open(string name,int id)
    {
    PrintFormat("Função chamada %s (name=%s id=%d)",__FUNCTION__,name,id);
    return(1);
    }
    //+------------------------------------------------------------------+
    //| Salva o arquivo |
    //+------------------------------------------------------------------+
    int Save(string name,int id)
    {
    PrintFormat("Função chamada %s (name=%s id=%d)",__FUNCTION__,name,id);
    return(2);
    }
    //+------------------------------------------------------------------+
    //| Fecha o arquivo |
    //+------------------------------------------------------------------+
    int Close(string name,int id)
    {
    PrintFormat("Função chamada %s (name=%s id=%d)",__FUNCTION__,name,id);
    return(3);
    }
    //+------------------------------------------------------------------+
    //| Criamos nossa classe de botão com a função de manipulador de eventos |
    //+------------------------------------------------------------------+
    class MyButton: public CButton
    {
    private:
    TAction m_action; // manipulador de eventos para o gráfico
    public:
    MyButton(void){}
    ~MyButton(void){}
    //--- construtor com indicação do texto do botão e ponteiro para a função a fim de manipular eventos
    MyButton(string text,TAction act)
    {
    Text(text);
    m_action=act;
    }
    //--- definição de função que será chamada a partir do manipulador de eventos OnEvent()
    void SetAction(TAction act){m_action=act;}
    //--- manipulador padrão de eventos de gráfico
    virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) override
    {
    if(m_action!=NULL & lparam==Id())
    {
    //--- chamamos o manipulador próprio
    m_action(sparam,(int)lparam);
    return(true);
    }
    else
    //--- retornamos o resultado da chamada do manipulador a partir da classe mão CButton
    return(CButton::OnEvent(id,lparam,dparam,sparam));
    }
    };
    //+------------------------------------------------------------------+
    //| Classe CControlsDialog |
    //| Designação: painel gráfico para controle do aplicativo |
    //+------------------------------------------------------------------+
    class CControlsDialog : public CAppDialog
    {
    private:
    CArrayObj m_buttons; // matriz de botões
    public:
    CControlsDialog(void){};
    ~CControlsDialog(void){};
    //--- create
    virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2) override;
    //--- adição de botão
    bool AddButton(MyButton &button){return(m_buttons.Add(GetPointer(button))) ;m_buttons.Sort();};
    protected:
    //--- criação de botões
    bool CreateButtons(void);
    };
    //+------------------------------------------------------------------+
    //| Criação do objeto CControlsDialog no gráfico |
    //+------------------------------------------------------------------+
    bool CControlsDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
    {
    if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2, y2))
    return(false);
    return(CreateButtons());
    //---
    }
    //+------------------------------------------------------------------+
    //| Criação e adição de botões para o painel CControlsDialog |
    //+------------------------------------------------------------------+
    bool CControlsDialog::CreateButtons(void)
    {
    //--- cálculo de coordenadas de botões
    int x1=INDENT_LEFT;
    int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
    int x2;
    int y2=y1+BUTTON_HEIGHT;
    //--- adicionamos os objetos dos botões juntamente com os ponteiros para as funções
    AddButton(new MyButton("Open",Open));
    AddButton(new MyButton("Save",Save));
    AddButton(new MyButton("Close",Close));
    //--- criamos os botões graficamente
    for(int i=0;i<m_buttons.Total();i++)
    {
    MyButton *b=(MyButton*)m_buttons.At(i);
    x1=INDENT_LEFT+i*(BUTTON_WIDTH+CONTROLS_GAP_X);
    x2=x1+BUTTON_WIDTH;
    if(!b.Create(m_chart_id,m_name+"bt"+b.Text(),m_sub win,x1,y1,x2,y2))
    {
    PrintFormat("Failed to create button %s %d",b.Text(),i);
    return(false);
    }
    //--- adicionamos cada botão no recipiente CControlsDialog
    if(!Add(b))
    return(false);
    }
    //--- succeed
    return(true);
    }
    //--- declaramos o objeto no nível global para criá-lo automaticamente ao inciar o programa
    CControlsDialog MyDialog;
    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    //--- agora criamos o objeto no gráfico
    if(!MyDialog.Create(0,"Controls",0,40,40,380,344))
    return(INIT_FAILED);
    //--- executamos o aplicativo
    MyDialog.Run();
    //--- inicialização bem-sucedida do aplicativo
    return(INIT_SUCCEEDED);
    }
    //+------------------------------------------------------------------+
    //| Expert deinitialization function |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
    //--- destroy dialog
    MyDialog.Destroy(reason);
    }
    //+------------------------------------------------------------------+
    //| Expert chart event function |
    //+------------------------------------------------------------------+
    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
    {
    //--- para os eventos do gráfico, chamamos o manipulador a partir da classe mãe (neste caso, CAppDialog)
    MyDialog.ChartEvent(id,lparam,dparam,sparam); }

    Though trading on financial markets involves high risk, it can still generate extra income in case you apply the right approach. By choosing a reliable broker such as InstaForex you get access to the international financial markets and open your way towards financial independence. You can sign up here.


  4. The Following User Says Thank You to forumforex For This Useful Post:

    Não registrado (1 )

+ Responder ao Tópico

Permissões de postagens

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts