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
    343
    Obrigado
    91
    Agradecimentos 207 Tempos em 139 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: 113
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. #2 Fechar a publicação
    Banned
    Data de afiliação
    Aug 2018
    Postagens
    343
    Obrigado
    91
    Agradecimentos 207 Tempos em 139 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.


+ 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