Você está perdendo oportunidades de negociação:
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Registro
Login
Você concorda com a política do site e com os termos de uso
Se você não tem uma conta, por favor registre-se
Anatoly, diga-me qual é a causa do erro
Tudo funcionava bem antes dessa atualização. Agora, ao criar a tabela CTable, esse erro aparece.
Por favor, diga-me onde está o erro - já imprimi todas as linhas - a interface é criada, mas depois de algum tempo ela tropeça e .... erro.
Arquivo com um exemplo no arquivo.
Esqueci de fazer uma correção, pois ela foi feita anteriormente na classe CCanvasTable.
Na classe CTable, você precisa substituir as versões atuais dos métodos CreateScrollV() e CreateScrollH() pelos métodos mostrados na listagem abaixo:
//|| Cria uma barra de rolagem vertical
//+------------------------------------------------------------------+
bool CTable::CreateScrollV(void)
{
//--- Salvar o ponteiro do formulário
m_scrollv.WindowPointer(m_wnd);
//--- Coordenadas
int x=(m_anchor_right_window_side)? m_x-m_x_size+m_scrollv.ScrollWidth() : CElement::X2()-m_scrollv.ScrollWidth();
int y=CElement::Y();
//--- Definir dimensões
m_scrollv.Id(CElement::Id());
m_scrollv.IsDropdown(CElement::IsDropdown());
m_scrollv.XSize(m_scrollv.ScrollWidth());
m_scrollv.YSize((m_columns_total>m_visible_columns_total)? m_y_size-m_scrollv.ScrollWidth()+1 : m_y_size);
m_scrollv.AnchorRightWindowSide(m_anchor_right_window_side);
m_scrollv.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Criando uma barra de rolagem
if(!m_scrollv.CreateScroll(m_chart_id,m_subwin,x,y,m_rows_total,m_visible_rows_total))
return(false);
//--- Ocultar se não for necessário agora
if(m_rows_total<=m_visible_rows_total)
m_scrollv.Hide();
//---
return(true);
}
//+------------------------------------------------------------------+
//|| Cria uma barra de rolagem horizontal
//+------------------------------------------------------------------+
bool CTable::CreateScrollH(void)
{
//--- Salvar o ponteiro do formulário
m_scrollh.WindowPointer(m_wnd);
//--- Coordenadas
int x=CElement::X();
int y=(m_anchor_bottom_window_side)? m_y-m_area.Y_Size()+m_scrollh.ScrollWidth() : CElement::Y2()-m_scrollh.ScrollWidth();
//--- Definir dimensões
m_scrollh.Id(CElement::Id());
m_scrollh.IsDropdown(CElement::IsDropdown());
m_scrollh.XSize((m_rows_total>m_visible_rows_total)? m_area.XSize()-m_scrollh.ScrollWidth()+1 : m_area.XSize());
m_scrollh.YSize(m_scrollh.ScrollWidth());
m_scrollh.AnchorRightWindowSide(m_anchor_right_window_side);
m_scrollh.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Criando uma barra de rolagem
if(!m_scrollh.CreateScroll(m_chart_id,m_subwin,x,y,m_columns_total,m_visible_columns_total))
return(false);
//--- Ocultar se não for necessário agora
if(m_columns_total<=m_visible_columns_total)
m_scrollh.Hide();
//---
return(true);
}
//---
Mudanças semelhantes precisam ser feitas na classe CLabelsTable. As correções estarão na próxima atualização.
Esqueci de fazer uma correção, pois ela foi feita anteriormente na classe CCanvasTable.
Na classe CTable, você precisa substituir as versões atuais dos métodos CreateScrollV() e CreateScrollH() pelos métodos mostrados na listagem abaixo:
...
//---
Mudanças semelhantes precisam ser feitas na classe CLabelsTable. As correções estarão na próxima atualização.
Esqueci de fazer uma correção, pois ela foi feita anteriormente na classe CCanvasTable.
Na classe CTable, você precisa substituir as versões atuais dos métodos CreateScrollV() e CreateScrollH() pelos métodos mostrados na listagem abaixo:
//|| Cria uma barra de rolagem vertical
//+------------------------------------------------------------------+
bool CTable::CreateScrollV(void)
{
//--- Salvar o ponteiro do formulário
m_scrollv.WindowPointer(m_wnd);
//--- Coordenadas
int x=(m_anchor_right_window_side)? m_x-m_x_size+m_scrollv.ScrollWidth() : CElement::X2()-m_scrollv.ScrollWidth();
int y=CElement::Y();
//--- Definir dimensões
m_scrollv.Id(CElement::Id());
m_scrollv.IsDropdown(CElement::IsDropdown());
m_scrollv.XSize(m_scrollv.ScrollWidth());
m_scrollv.YSize((m_columns_total>m_visible_columns_total)? m_y_size-m_scrollv.ScrollWidth()+1 : m_y_size);
m_scrollv.AnchorRightWindowSide(m_anchor_right_window_side);
m_scrollv.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Criando uma barra de rolagem
if(!m_scrollv.CreateScroll(m_chart_id,m_subwin,x,y,m_rows_total,m_visible_rows_total))
return(false);
//--- Ocultar se não for necessário agora
if(m_rows_total<=m_visible_rows_total)
m_scrollv.Hide();
//---
return(true);
}
//+------------------------------------------------------------------+
//|| Cria uma barra de rolagem horizontal
//+------------------------------------------------------------------+
bool CTable::CreateScrollH(void)
{
//--- Salvar o ponteiro do formulário
m_scrollh.WindowPointer(m_wnd);
//--- Coordenadas
int x=CElement::X();
int y=(m_anchor_bottom_window_side)? m_y-m_area.Y_Size()+m_scrollh.ScrollWidth() : CElement::Y2()-m_scrollh.ScrollWidth();
//--- Definir dimensões
m_scrollh.Id(CElement::Id());
m_scrollh.IsDropdown(CElement::IsDropdown());
m_scrollh.XSize((m_rows_total>m_visible_rows_total)? m_area.XSize()-m_scrollh.ScrollWidth()+1 : m_area.XSize());
m_scrollh.YSize(m_scrollh.ScrollWidth());
m_scrollh.AnchorRightWindowSide(m_anchor_right_window_side);
m_scrollh.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Criando uma barra de rolagem
if(!m_scrollh.CreateScroll(m_chart_id,m_subwin,x,y,m_columns_total,m_visible_columns_total))
return(false);
//--- Ocultar se não for necessário agora
if(m_columns_total<=m_visible_columns_total)
m_scrollh.Hide();
//---
return(true);
}
//---
Mudanças semelhantes precisam ser feitas na classe CLabelsTable. As correções estarão na próxima atualização.
Anatoly, as alterações foram feitas. Pegue o exemplo de MQL5\Indicators\Article07\ChartWindow02\ChartWindow02.mq5, corrija a tabela em Program.mqh para que o número de linhas coincida com o número visível de linhas, ou o número de colunas coincida com o número visível de colunas, ou ambos. Por exemplo:
//|| Cria uma tabela|
//+------------------------------------------------------------------+
bool CProgram::CreateTable(void)
{
#define COLUMNS1_TOTAL (6)
#define ROWS1_TOTAL (15)
//--- Salvar o ponteiro no formulário
m_table.WindowPointer(m_window1);
//--- Coordenadas
int x=m_window1.X()+TABLE1_GAP_X;
int y=m_window1.Y()+TABLE1_GAP_Y;
//--- Número de colunas e linhas visíveis
int visible_columns_total =6;
int visible_rows_total =15;
//--- Definir propriedades antes da criação
m_table.XSize(600);
m_table.RowYSize(20);
m_table.FixFirstRow(true);
m_table.FixFirstColumn(true);
m_table.LightsHover(true);
m_table.SelectableRow(true);
m_table.TextAlign(ALIGN_CENTER);
m_table.HeadersColor(C'255,244,213');
m_table.HeadersTextColor(clrBlack);
m_table.CellColorHover(clrGold);
m_table.TableSize(COLUMNS1_TOTAL,ROWS1_TOTAL);
m_table.VisibleTableSize(visible_columns_total,visible_rows_total);
//--- Criar um controle
if(!m_table.CreateTable(m_chart_id,m_subwin,x,y))
return(false);
//--- Vamos preencher a tabela:
// A primeira célula está vazia
m_table.SetValue(0,0,"-");
//--- Títulos para colunas
for(int c=1; c<COLUMNS1_TOTAL; c++)
{
for(int r=0; r<1; r++)
m_table.SetValue(c,r,"SYMBOL "+string(c));
}
//--- Cabeçalhos para linhas, método de alinhamento de texto - à direita
for(int c=0; c<1; c++)
{
for(int r=1; r<ROWS1_TOTAL; r++)
{
m_table.SetValue(c,r,"PARAMETER "+string(r));
m_table.TextAlign(c,r,ALIGN_RIGHT);
}
}
//--- Formatação de dados e tabelas (cor de fundo e cor da célula)
for(int c=1; c<COLUMNS1_TOTAL; c++)
{
for(int r=1; r<ROWS1_TOTAL; r++)
{
m_table.SetValue(c,r,string(c)+":"+string(r));
m_table.TextColor(c,r,(c%2==0)? clrRed : clrRoyalBlue);
m_table.CellColor(c,r,(r%2==0)? clrWhiteSmoke : clrWhite);
}
}
//--- Atualize a tabela para mostrar as alterações
m_table.UpdateTable();
//--- Adicione o objeto à matriz comum de grupos de objetos
CWndContainer::AddToElementsArray(0,m_table);
return(true);
}
//+------------------------------------------------------------------+
Compile, execute o exemplo, clique na linha mais baixa da tabela (tudo está bem) e, em seguida, clique nela novamente. No segundo clique, aparece um erro:
O que fazer e o que fazer?
Anatoly, as alterações foram feitas. Pegue o exemplo de MQL5\Indicators\Article07\ChartWindow02\ChartWindow02.mq5, corrija a tabela em Program.mqh para que o número de linhas coincida com o número visível de linhas, ou o número de colunas coincida com o número visível de colunas, ou ambos. Por exemplo, assim:
...
Compile, execute o exemplo, clique na linha mais baixa da tabela (tudo está bem) e, em seguida, clique nela novamente. Um erro aparece no segundo clique:
O que fazer e o que fazer?
Nas classes CScrollH e CScrollV , nos métodos ScrollBarControl(), você precisa adicionar uma verificação adicional da visibilidade do elemento, conforme mostrado na listagem abaixo:
//| Controle de rolagem|
//+------------------------------------------------------------------+
bool CScrollH::ScrollBarControl(const int x,const int y,const bool mouse_state)
{
//--- Sair se não houver ponteiro para o formulário
if(::CheckPointer(m_wnd)==POINTER_INVALID)
return(false);
//--- Sair se o formulário estiver bloqueado por outro elemento
if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
return(false);
//--- Sair se o item estiver oculto
if(!CElement::IsVisible())
return(false);
//--- Verificando o foco sobre o controle deslizante
m_thumb.MouseFocus(x>m_thumb.X() && x<m_thumb.X2() &&
y>m_thumb.Y() && y<m_thumb.Y2());
//--- Verificar e lembrar o estado do botão do mouse
CScroll::CheckMouseButtonState(mouse_state);
//--- Alterar a cor da barra de rolagem da lista
CScroll::ChangeObjectsColor();
//--- Se o controle for passado para a barra de rolagem, defina a posição do controle deslizante
if(CScroll::ScrollState())
{
//--- Movendo o controle deslizante
OnDragThumb(x);
//--- Altera o número da posição do controle deslizante
CalculateThumbPos();
return(true);
}
return(false);
}
//---
A correção estará disponível na próxima atualização da biblioteca.
Nas classes CScrollH e CScrollV , nos métodos ScrollBarControl(), precisamos adicionar uma verificação adicional da visibilidade do elemento, conforme mostrado na listagem abaixo:
...
A correção estará disponível na próxima atualização da biblioteca.
Obrigado. Fiz as seguintes alterações: no arquivo Scrolls.mqh, nas classes CScrollH e CScrollV, adicionei linhas:
//| Controle deslizante|
//+------------------------------------------------------------------+
bool CScrollV::ScrollBarControl(const int x,const int y,const bool mouse_state)
{
//--- Sair se não houver ponteiro para o formulário
if(::CheckPointer(m_wnd)==POINTER_INVALID)
return(false);
//--- Se o formulário não estiver bloqueado e os identificadores corresponderem
if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
return(false);
//--- Sair se o item estiver oculto
if(!CElement::IsVisible())
return(false);
//--- Verificando o foco sobre o controle deslizante
m_thumb.MouseFocus(x>m_thumb.X() && x<m_thumb.X2() &&
y>m_thumb.Y() && y<m_thumb.Y2());
//--- Verificar e lembrar o estado do botão do mouse
CScroll::CheckMouseButtonState(mouse_state);
//--- Alterar a cor do controle deslizante
CScroll::ChangeObjectsColor();
//--- Se o controle for passado para a barra de rolagem, defina a posição do controle deslizante
if(CScroll::ScrollState())
{
//--- Movendo o controle deslizante
OnDragThumb(y);
//--- Altera o número da posição do controle deslizante
CalculateThumbPos();
return(true);
}
//---
return(false);
}
//+------------------------------------------------------------------+
//| Controle de rolagem|
//+------------------------------------------------------------------+
bool CScrollH::ScrollBarControl(const int x,const int y,const bool mouse_state)
{
//--- Sair se não houver ponteiro para o formulário
if(::CheckPointer(m_wnd)==POINTER_INVALID)
return(false);
if(m_wnd.IsLocked() && m_wnd.IdActivatedElement()!=CElement::Id())
return(false);
//--- Sair se o item estiver oculto
if(!CElement::IsVisible())
return(false);
//--- Verificando o foco sobre o controle deslizante
m_thumb.MouseFocus(x>m_thumb.X() && x<m_thumb.X2() &&
y>m_thumb.Y() && y<m_thumb.Y2());
//--- Verificar e lembrar o estado do botão do mouse
CScroll::CheckMouseButtonState(mouse_state);
//--- Alterar a cor da barra de rolagem da lista
CScroll::ChangeObjectsColor();
//--- Se o controle for passado para a barra de rolagem, defina a posição do controle deslizante
if(CScroll::ScrollState())
{
//--- Movendo o controle deslizante
OnDragThumb(x);
//--- Altera o número da posição do controle deslizante
CalculateThumbPos();
return(true);
}
return(false);
}
//+------------------------------------------------------------------+
Compilei e executei o mesmo arquivo de teste de \MQL5\Indicators\Article07\ChartWindow02\ChartWindow02 .mq5, no qual alterei a função de criação de tabela em Program.mqh para que o número de todas as colunas e linhas coincidisse com o número de colunas e linhas visíveis:
//|| Cria uma tabela|
//+------------------------------------------------------------------+
bool CProgram::CreateTable(void)
{
#define COLUMNS1_TOTAL (6)
#define ROWS1_TOTAL (15)
//--- Salvar o ponteiro no formulário
m_table.WindowPointer(m_window1);
//--- Coordenadas
int x=m_window1.X()+TABLE1_GAP_X;
int y=m_window1.Y()+TABLE1_GAP_Y;
//--- Número de colunas e linhas visíveis
int visible_columns_total =6;
int visible_rows_total =15;
//--- Definir propriedades antes da criação
m_table.XSize(600);
m_table.RowYSize(20);
m_table.FixFirstRow(true);
m_table.FixFirstColumn(true);
m_table.LightsHover(true);
m_table.SelectableRow(true);
m_table.TextAlign(ALIGN_CENTER);
m_table.HeadersColor(C'255,244,213');
m_table.HeadersTextColor(clrBlack);
m_table.CellColorHover(clrGold);
m_table.TableSize(COLUMNS1_TOTAL,ROWS1_TOTAL);
m_table.VisibleTableSize(visible_columns_total,visible_rows_total);
//--- Criar um controle
if(!m_table.CreateTable(m_chart_id,m_subwin,x,y))
return(false);
//--- Vamos preencher a tabela:
// A primeira célula está vazia
m_table.SetValue(0,0,"-");
//--- Títulos para colunas
for(int c=1; c<COLUMNS1_TOTAL; c++)
{
for(int r=0; r<1; r++)
m_table.SetValue(c,r,"SYMBOL "+string(c));
}
//--- Cabeçalhos para linhas, o método de alinhamento de texto é alinhado à direita
for(int c=0; c<1; c++)
{
for(int r=1; r<ROWS1_TOTAL; r++)
{
m_table.SetValue(c,r,"PARAMETER "+string(r));
m_table.TextAlign(c,r,ALIGN_RIGHT);
}
}
//--- Formatação de dados e tabelas (cor de fundo e cor da célula)
for(int c=1; c<COLUMNS1_TOTAL; c++)
{
for(int r=1; r<ROWS1_TOTAL; r++)
{
m_table.SetValue(c,r,string(c)+":"+string(r));
m_table.TextColor(c,r,(c%2==0)? clrRed : clrRoyalBlue);
m_table.CellColor(c,r,(r%2==0)? clrWhiteSmoke : clrWhite);
}
}
//--- Atualize a tabela para mostrar as alterações
m_table.UpdateTable();
//--- Adicione o objeto à matriz comum de grupos de objetos
CWndContainer::AddToElementsArray(0,m_table);
return(true);
}
//+------------------------------------------------------------------+
Compilar e executar o ChartWindow02.ex5
Várias vezes clicamos na linha mais baixa da tabela e obtemos um voo fora da matriz:
...
Então nada mudou?Depois das alterações que fiz, ele não funciona mais. Talvez eu tenha feito outras alterações, mas não me lembro. Não tenho um histórico de pequenas edições.
Por via das dúvidas, tente substituir os métodos CScroll::Show() e CScroll::Hide() por estas versões, se forem diferentes:
//| Mostra o item de menu|
//+------------------------------------------------------------------+
void CScroll::Show(void)
{
//--- Sair se o número de itens da lista não for maior que o número da parte visível da lista
if(m_items_total<=m_visible_items_total)
return;
//---
m_area.Timeframes(OBJ_ALL_PERIODS);
m_bg.Timeframes(OBJ_ALL_PERIODS);
m_inc.Timeframes(OBJ_ALL_PERIODS);
m_dec.Timeframes(OBJ_ALL_PERIODS);
m_thumb.Timeframes(OBJ_ALL_PERIODS);
//--- Atualizar a posição dos objetos
Moving(m_wnd.X(),m_wnd.Y(),true);
//--- Status de visibilidade
CElement::IsVisible(true);
}
//+------------------------------------------------------------------+
//| Oculta o item de menu|
//+------------------------------------------------------------------+
void CScroll::Hide(void)
{
m_area.Timeframes(OBJ_NO_PERIODS);
m_bg.Timeframes(OBJ_NO_PERIODS);
m_inc.Timeframes(OBJ_NO_PERIODS);
m_dec.Timeframes(OBJ_NO_PERIODS);
m_thumb.Timeframes(OBJ_NO_PERIODS);
//--- Status de visibilidade
CElement::IsVisible(false);
}
//---
Se isso não ajudar, você terá que aguardar a próxima atualização.
Mas depois das alterações que fiz, ele não é mais reproduzido. Talvez eu tenha feito outras alterações, mas não me lembro. Não marco o histórico de pequenas edições.
Por via das dúvidas, tente substituir os métodos CScroll::Show() e CScroll::Hide() por estas versões, se forem diferentes:
//| Mostra o item de menu|
//+------------------------------------------------------------------+
void CScroll::Show(void)
{
//--- Sair se o número de itens da lista não for maior que o número da parte visível da lista
if(m_items_total<=m_visible_items_total)
return;
//---
m_area.Timeframes(OBJ_ALL_PERIODS);
m_bg.Timeframes(OBJ_ALL_PERIODS);
m_inc.Timeframes(OBJ_ALL_PERIODS);
m_dec.Timeframes(OBJ_ALL_PERIODS);
m_thumb.Timeframes(OBJ_ALL_PERIODS);
//--- Atualizar a posição dos objetos
Moving(m_wnd.X(),m_wnd.Y(),true);
//--- Status de visibilidade
CElement::IsVisible(true);
}
//+------------------------------------------------------------------+
//| Oculta o item de menu|
//+------------------------------------------------------------------+
void CScroll::Hide(void)
{
m_area.Timeframes(OBJ_NO_PERIODS);
m_bg.Timeframes(OBJ_NO_PERIODS);
m_inc.Timeframes(OBJ_NO_PERIODS);
m_dec.Timeframes(OBJ_NO_PERIODS);
m_thumb.Timeframes(OBJ_NO_PERIODS);
//--- Status de visibilidade
CElement::IsVisible(false);
}
//---
Se isso não ajudar, você terá que aguardar a próxima atualização.
Obrigado, parece ter ajudado. Estavam faltando linhas sobre o status de visibilidade em Show():
CElement::IsVisible(true);
: e Hide():
CElement::IsVisible(false);
Obrigado, parece que funcionou. Estavam faltando linhas sobre o status de visibilidade em Show():
CElement::IsVisible(true);
e Hide():
CElement::IsVisible(false);
É necessária mais uma correção. A visibilidade deve ser definida antes de atualizar a posição do elemento. Assim:
//--- Status de visibilidade
CElement::IsVisible(true);
//--- Atualizar a posição dos objetos
Moving(m_wnd.X(),m_wnd.Y(),true);
...
A interatividade dos elementos da interface implementada por meio de um cronômetro é uma solução estranha. - Por que ela deveria ser implementada por meio de (ou com) um cronômetro? - É claro que isso consumirá muitos recursos.
Você não precisa de um timer para controlar os estados dos controles.
1. Registre as coordenadas atuais de todos os elementos na matriz (mapa). Faça ajustes nas coordenadas de localização de todos os objetos do formulário à medida que você move a janela.
2. Crie uma função para localizar elementos por coordenadas (localizador). A função percorrerá as coordenadas do elemento atual registrado e encontrará o elemento que está agora sob o cursor.
3. Chame o localizador a partir do evento "CHARTEVENT_MOUSE_MOVE" (no evento de movimento do cursor).
4. Passe o nome do objeto retornado pelo localizador para a função de interatividade, onde a função ObjectSetInteger() será aplicada ao objeto, o que o forçará a mudar de cor.
Como você pode ver, não há cronômetro nesse esquema, portanto, não há consumo desnecessário de recursos.
A interatividade dos elementos da interface implementada por meio de um cronômetro é uma solução estranha. - Por que ela deveria ser implementada por meio de (ou com) um cronômetro? - É claro que isso consumirá muitos recursos.
...
Como você pode ver, não há nenhum timer nesse esquema, portanto, não há consumo desnecessário de recursos.
Você está errado. Já respondi com detalhes suficientes nos comentários acima por que foi feito dessa forma.
Ele não consome muitos recursos agora (agora também no Windows 10 ). Você leu o artigo (e os comentários também)?
//---
P.S. A propósito, o consumo de recursos da CPU em diferentes terminais (MT4/MT5) e versões do sistema operacional (Windows) é muito diferente em condições iguais. No Windows 7, o terminal MetaTrader 4 se mostrou significativamente melhor do que o MetaTrader 5. Infelizmente, não posso lhe dar os números agora, pois já mudei completamente para o Windows 10.
Quanto à otimização, ainda não esgotei todas as opções. Ainda há algo a ser otimizado e um entendimento de como.