Discussão do artigo "Interfaces gráficas X: Seleção de texto na caixa de texto multilinha (build 13)" - página 7

 
Anatoli Kazharski:

As coordenadas relativas são definidas quando os elementos são criados em uma classe personalizada:

//---

Qual é a tarefa?

colocar duas tabelas horizontalmente, x_gap,y_gap altera o local da rolagem horizontal e é isso ((.

PS. então, parece ter se deslocado, mas por algum motivo duas tabelas estão deslocadas ))

e no método:

CWndContainer::AddToElementsArray(0, m_table_pair.GetTbl());

se houver duas tabelas, o primeiro parâmetro é sempre 0 ou é um número de série de objetos idênticos?

Por algum motivo, a primeira tabela se move persistentemente sob a segunda tabela.

 
Konstantin:

...

PS. então, parece ter se deslocado, mas por algum motivo duas tabelas se deslocaram ))

e no método:

CWndContainer::AddToElementsArray(0, m_table_pair.GetTbl());

se houver duas tabelas, o primeiro parâmetro é sempre 0 ou é um número de série de objetos idênticos?

O primeiro parâmetro é o número do formulário ao qual o item está anexado. Talvez você adicione uma e a mesma tabela à lista comum de elementos.
 
Anatoli Kazharski:
O primeiro parâmetro é o número do formulário ao qual o elemento está anexado. Talvez você esteja adicionando a mesma tabela à lista comum de itens.


O que você quer dizer com a lista comum? Onde ela está separada?

Aqui está o método de criação na classe de formulário:

/*!
 \brief Create object
 \param const string a_name - nome do programa
 \param const uint a_pause - pausa para atualização da linha de status
 \return true se for bem-sucedido, caso contrário false
*/
bool CMainForm::Create(const string a_name,const uint a_pause) {
   m_counter500.SetParameters(16, a_pause);
   m_counter16.SetParameters(16, 16);

   if(!CreateForm(m_form, a_name))
      return false;

   if(!CreateStatusBar(m_status_bar, m_form, 1, STATUS_SIZE_HEIGHT))
      return false;

   if(!m_table_sign.Create(m_form, m_chart_id, m_subwin, 1, 20))
      return false;

   if(!m_table_pair.Create(m_form, m_chart_id, m_subwin, 450, 20))
      return false;
   //--- adicionar o objeto de tabela à matriz comum de grupos de objetos
   CWndContainer::AddToElementsArray(0, m_table_sign.GetTbl());
   CWndContainer::AddToElementsArray(0, m_table_pair.GetTbl());

   m_chart.Redraw();
//---
   return true;
}

O método GetTbl retorna um ponteiro para CCanvasTable m_table

 
Konstantin:

...

Esse é o resultado que você deseja?

//---

Anexei um exemplo no arquivo:

Arquivos anexados:
 
Konstantin:

Aqui está o método create na classe do formulário:

O método GetTbl retorna um ponteiro para CCanvasTable m_table

//--- Criar um controle
   if(!m_canvas_table2.CreateTable(m_chart_id,m_subwin,x_gap,y_gap))
      return(false);
//--- Adicione o objeto à matriz comum de grupos de objetos
   CWndContainer::AddToElementsArray(0,m_canvas_table2);
 
Anatoli Kazharski:

Você quer um resultado como esse?

//---

Anexei um exemplo no arquivo:


Eu fiz assim:

/*!
 \brief Create object
 \param const string a_name - nome do programa
 \param const uint a_pause - pausa para atualização da linha de status
 \return true se for bem-sucedido, caso contrário false
*/
bool CMainForm::Create(const string a_name,const uint a_pause) {
   m_counter500.SetParameters(16, a_pause);
   m_counter16.SetParameters(16, 16);

   if(!CreateForm(m_form, a_name))
      return false;

   if(!CreateStatusBar(m_status_bar, m_form, 1, STATUS_SIZE_HEIGHT))
      return false;

   if(!m_table_sign.Create(m_form, m_chart_id, m_subwin, 1, 20))
      return false;

   //--- adicionar o objeto de tabela à matriz comum de grupos de objetos
   CWndContainer::AddToElementsArray(0, m_table_sign.GetTbl());

   if(!m_table_pair.Create(m_form, m_chart_id, m_subwin, 450, 20))
      return false;
   //--- adicionar o objeto de tabela à matriz comum de grupos de objetos
   CWndContainer::AddToElementsArray(0, m_table_pair.GetTbl());

   m_chart.Redraw();
//---
   return true;
}

e tudo funcionou, acontece que imediatamente após a criação de um objeto, ele deve ser colocado em um contêiner e só então criar outro objeto ))


 
Anatoli Kazharski:

Não, tenho tabelas em outras classes, uso programação modular )), portanto, é mais conveniente gerenciar a funcionalidade - classe de formulário principal, classe de tabela 1, classe de tabela 2 etc. No final, todos os elementos são montados na classe de formulário principal como objetos prontos separados.
 
Konstantin:

Não, eu tenho tabelas em outras classes, uso programação modular )), portanto, é mais conveniente gerenciar a funcionalidade - classe de formulário principal, classe de tabela 1, classe de tabela 2 etc. No final, todos os elementos são coletados na classe de formulário principal como objetos prontos separados.
Concordo. Muitos usuários dessa biblioteca fazem isso, mas eu não consigo colocá-la em prática. )
 
Anatoli Kazharski:
Eu concordo. Muitos usuários dessa biblioteca fazem isso, mas eu simplesmente não consigo colocá-la em minhas mãos. )


A propósito, há um problema:

CWndEvents::CWndEvents(void) : m_chart_id(0),
                               m_subwin(0),
                               m_active_window_index(0),
                               m_indicator_shortname(""),
                               m_program_name(PROGRAM_NAME),
                               m_subwindow_handle(INVALID_HANDLE),
                               m_subwindow_shortname(""),
                               m_subwindows_total(1)

  {
//--- Iniciar o cronômetro
   if(!::MQLInfoInteger(MQL_TESTER))
      ::EventSetMillisecondTimer(TIMER_STEP_MSC);
//--- Obter o ID do gráfico atual
   m_chart.Attach();
//--- Ativar o rastreamento de eventos do mouse
   m_chart.EventMouseMove(true);
//--- Desativar a invocação da linha de comando para as teclas Espaço e Enter
   m_chart.SetInteger(CHART_QUICK_NAVIGATION,false);
//--- Determinar o número da subjanela
   DetermineSubwindow();
  }

A linha selecionada não permite trabalhar no testador. É melhor fazer uma escolha como esta:

enum ENUM_GRAPHICS {
   GRAPHICS_NO    = 0,  // não há necessidade de gráficos
   GRAPHICS_REAL  = 1,  // gráficos para negociação real
   GRAPHICS_TEST  = 2   // gráficos para testes
};

/*!
 Obtém uma indicação do programa em execução
*/
ENUM_GRAPHICS CCheck::GetGraphics(void) { return m_graphics; }
//-----------------------------------------------------------------------------+
/*!
 Sinal da exibição de gráficos
 \retorno do sinal da operação do programa da enumeração ENUM_GRAPHICS
*/
ENUM_GRAPHICS CCheck::CheckGraphicsDisplay(void) {
   if(MQLInfoInteger(MQL_OPTIMIZATION) || (MQLInfoInteger(MQL_TESTER) && !MQLInfoInteger(MQL_VISUAL_MODE)))
      m_graphics = GRAPHICS_NO;
   else if(!MQLInfoInteger(MQL_OPTIMIZATION) && !MQLInfoInteger(MQL_TESTER) && !MQLInfoInteger(MQL_VISUAL_MODE))
      m_graphics = GRAPHICS_REAL;
   else if(MQLInfoInteger(MQL_VISUAL_MODE))
      m_graphics = GRAPHICS_TEST;
//---
   return m_graphics;
}

e no programa fazer uma escolha como esta:

   //--- configuração para OnTimer()
   uint _pause = 0;
   if(in_param.graphics == GRAPHICS_REAL)
      _pause = 500;                       // 500 ms
   else if(in_param.graphics == GRAPHICS_TEST)
      _pause = 60000;                     // 1 minuto

   if(!main_form.Create(name_mts, _pause)) {
      ::Print(__FUNCTION__," > Falha ao criar uma GUI!");
      return INIT_FAILED;
   }

ou usar apenas sinalizadores para fazer uma seleção

 
Konstantin:

A propósito, há um problema:

A string destacada não permite trabalhar no testador.

Ainda não testei no testador, pois havia muitas restrições lá antes. Então, temporariamente, até agora.

Você já tentou testar a GUI no testador? Qual é o resultado? Os eventos funcionam? Todos os objetos gráficos são exibidos?