No entanto, parece-me que as alterações recentes relacionadas à especificação de coordenadas por deslocamento a partir da borda do formulário não são muito amigáveis para o usuário final. Se antes o usuário podia usar com segurança duas opções para especificar o local de um objeto na janela, agora uma delas se tornou mais complicada. As coisas desmoronaram assim em toda a tela.
Anteriormente, o usuário podia especificar a coordenada x,y do objeto como um deslocamento de qualquer borda da forma de janela. Para fazer isso, bastava especificar a coordenada inicial dessa janela mais/menos o deslocamento em pixels. Agora, o usuário é forçado a começar somente a partir da borda esquerda do formulário, reduzindo as possibilidades de especificar a coordenada exata ou o deslocamento da coordenada em pixels de qualquer borda do formulário ou objeto.
Se antes o usuário podia, sem questionar o tamanho do objeto a partir do qual calcula o deslocamento, colocar calmamente um novo objeto com um deslocamento do tamanho necessário de qualquer borda do objeto pai, agora ele será forçado a recalcular as coordenadas do novo objeto toda vez que alterar o tamanho do objeto a partir do qual o novo objeto é construído com um deslocamento. Exemplo: Botão1 - sua coordenada x está a 4 pixels de distância da borda esquerda da janela do formulário. Ela é definida da seguinte forma:x=m_window.X()+4; O tamanho do botão1 é de 43 pixels de largura. Sua borda direita pode ser obtida da seguinte forma: m_butt1.X2(); Botão2 - sua coordenada está a 2 pixels de distância da borda direita do botão1. Ele é definido da seguinte forma: x=m_butt1.X2()+2; O tamanho do botão2 é de 24 pixels de largura. Sua borda direita pode ser obtida da seguinte forma: m_butt2.X2(); Botão3 - sua coordenada está a 4 pixels de distância da borda direita do botão2. Ele é definido da seguinte forma: x=m_butt2.X2()+4; O tamanho do botão3 é de 18 pixels de largura. Sua borda direita pode ser obtida da seguinte forma: m_butt3.X2(); A barra de separação vertical está a 4 pixels da borda direita do botão3: x=m_butt3.X2()+4; Portanto, podemos alterar facilmente o tamanho de qualquer um dos três botões, e todos eles estarão localizados no deslocamento que definimos, e a barra de separação estará perfeitamente posicionada no deslocamento que precisamos do botão3.
Agora vamos ver o que temos de fazer ao criar a interface de acordo com as novas regras: Button1: x_gap1=4; Button2: x_gap2=4+m_butt1.XSize()+2; Button3: x_gap3=4+m_butt1.XSize()+2+m_butt2.XSize()+4; R-Strip: x_gap4=4+m_butt1.XSize()+2+m_butt2.XSize()+4+m_butt3.XSize()+4; Aqui é sugerido especificar a coordenada X2() em vez de especificar os tamanhos dos objetos, mas esse não é o caso - tudo desmorona de uma só vez (eu, por exemplo, quebrei a cabeça ao adivinhar que Y2() não aponta para o local correto da coordenada Y).
Vejamos: eu defini as coordenadas do menu com um recuo de 1 pixel na horizontal e com um recuo do tamanho do "cabeçalho" da janela principal. A altura do menu é de 18 pixels.
//--- Criando o menu da janela principal x=m_window_main.X()+1; y=m_window_main.Y()+m_window_main.CaptionHeight(); h=18;
O menu está em seu lugar:
Agora preciso colocar a tabela deslocada da borda inferior do menu. Se o CaptionHeight() da janela do formulário for de 18 pixels e a altura do menu também for de 18 pixels, o deslocamento vertical da tabela deverá ser de 36 pixels. Há duas opções: ou nos sentamos com uma calculadora e calculamos todos os deslocamentos necessários (e os recalculamos novamente no caso de ajustes subsequentes com alterações de tamanho) ou tentamos obtê-los. Escolhemos a segunda opção, é claro, e tentamos: para a tabela, o y_gap deve ser igual à altura do título da janela principal mais a altura do menu: m_window_main.CaptionHeight()+m_menu_main.YSize();
//--- Tabela de lista de caracteres x=2; y=m_window_main.CaptionHeight()+m_menu_main.YSize()+1; w=140;
Compilar, obter:
A guia está no lugar. Mas. O valor Y2() do menu, nesse caso, não deveria coincidir com o valor que calculamos? Afinal, é mais conveniente não coletar os tamanhos de todos os objetos que se seguem uns aos outros, mas apenas obter suas coordenadas, certo? Vamos tentar: altere o cálculo da coordenada para sua obtenção:
//--- Tabela de lista de caracteres x=2; //y=m_window_main.CaptionHeight()+m_menu_main.YSize()+1; y=m_menu_main.Y2()+1; w=140;
Compile, get:
Y2() não deveria retornar o mesmo Y2 que calculamos anteriormente? m_window_main.CaptionHeight()+m_menu_main.YSize()+1;
Agora não especificamos coordenadas com deslocamento a partir de qualquer borda da janela, mas apenas deslocamento, e apenas a partir do topo ou da esquerda. Bom. Remova da coordenada Y2() obtida a coordenada Y() da parte superior da janela do formulário para obter o valor do deslocamento a partir da parte superior da janela do formulário:
//--- Tabela de lista de caracteres x=2; //y=m_window_main.CaptionHeight()+m_menu_main.YSize()+1; y=m_menu_main.Y2()-m_window_main.Y()+1; w=140;
Compile e obtenha o que deseja:
Então, para vinte objetos que estão a dois pixels de distância um do outro, devemos sempre adicionar seus tamanhos mais o deslocamento um do outro para obter o deslocamento correto para o último objeto? Afinal, Y2() do décimo nono objeto (a partir do qual era possível construir o vigésimo objeto apenas adicionando um deslocamento de dois pontos) agora não nos dá um ponto de partida e não retorna o que é esperado.... e temos que somar os tamanhos de todos os objetos para obter o deslocamento necessário ou, para cada objeto antes de sua criação, temos que calcular seu deslocamento com base em sua coordenada Y2() e na coordenada Y() inicial da janela do formulário.
Não estou entendendo. Anatoly, por favor, me dê uma solução. O que estou fazendo de errado? Por que é assim? Por que você acha que agora está mais amigável? Se antes você podia simplesmente especificar o deslocamento de qualquer borda da janela do formulário, de qualquer objeto nessa janela ou até mesmo da borda do gráfico em geral para criar o objeto necessário, agora você tem que fazer uma dança de pandeiro para calcular suas coordenadas antes de criá-lo? É melhor e mais conveniente escrever mais código e cálculos diferentes?
Entendo que você é o autor e sabe o que é melhor. Mesmo assim, você permite que outras pessoas o utilizem. Eu (apenas minha opinião) acho que essa inovação acabou sendo a única decisão ruim de apresentá-la como uma atualização - ela se tornou pior. Ele não tinha mais os recursos fáceis de criação de interface que tinha antes.
Peço desculpas se o ofendi (antigamente, os mensageiros com más notícias tinham suas cabeças cortadas).
Responderei um pouco mais tarde, mas, antes disso, gostaria de esclarecer o que você quer dizer com essa frase em relação a mim. O que são "más notícias" e quem é um "mensageiro" nesse contexto? :)
Responderei um pouco mais tarde, mas, antes disso, gostaria de esclarecer o que você quis dizer com essa frase sobre mim. O que são "más notícias" e quem é um "mensageiro" nesse contexto? :)
:)
Chamei de "más notícias" minha atitude em relação à inovação de que não é mais possível usar qualquer coordenada arbitrária como ponto de referência da coordenada do objeto, mas apenas as bordas esquerda e superior do formulário (adicionei um recálculo das coordenadas no local - cálculos desnecessários).... E o mensageiro sou eu, é claro, já que não gostei e disse isso :)
A má notícia é que chamei minha atitude para a inovação de que agora não é possível tomar qualquer coordenada arbitrária como ponto de referência de coordenadas do objeto, mas apenas as bordas esquerda e superior do formulário (adicionei um recálculo de coordenadas em cálculos locais - desnecessários).... Bem, o mensageiro sou eu, é claro, já que não gostei e disse isso :)
Então, aí está. Muito bom. Porque eu achei que tinha entendido errado. )
Aqui está minha resposta:
Artyom Trishkin:
No entanto, acho que as alterações recentes relacionadas à especificação de coordenadas por deslocamento da borda do formulário não são muito amigáveis para o usuário final. Se antes o usuário podia usar com segurança duas opções para especificar o local do objeto na janela, agora uma delas se tornou mais complicada. Já aconteceu de as coisas desmoronarem e se dividirem por toda a tela dessa forma.
...
Agora vamos ver o que temos de fazer ao criar a interface de acordo com as novas regras:
Button1: x_gap1=4; Button2: x_gap2=4+m_butt1.XSize()+2; Button3: x_gap3=4+m_butt1.XSize()+2+m_butt2.XSize()+4; R Strip: x_gap4=4+m_butt1.XSize()+2+m_butt2.XSize()+4+m_butt3.XSize()+4;
...
Em vez de especificar os tamanhos dos objetos, você ficaria tentado a especificar a coordenada X2() deles, mas esse não é o caso - tudo desmorona de uma vez (eu, por exemplo, quebrei a cabeça até perceber que Y2() não aponta para o local correto da coordenada Y).
É muito simples. Anteriormente, você tinha que passar coordenadas absolutas para os métodos de criação de elementos. Elas tinham de ser calculadas em relação ao ponto mais à esquerda do formulário ao qual o elemento está anexado.
Aqui está um exemplo do que tivemos de fazer anteriormente:
//+------------------------------------------------------------------+ //|| Cria um botão| //+------------------------------------------------------------------+ bool CProgram::CreateSimpleButton(constintx_gap,constinty_gap,conststring button_text) { //--- Salvar o ponteiro no formulário m_simple_button.WindowPointer(m_window); //--- Coordenadas int x=m_window.X()+x_gap; int y=m_window.Y()+y_gap; //--- Definir propriedades antes da criação m_simple_button.ButtonXSize(100); //--- Criando um botão if(!m_simple_button.CreateSimpleButton(m_chart_id,m_subwin,button_text,x,y)) return(false); //--- Adicione um ponteiro ao elemento na base CWndContainer::AddToElementsArray(0,m_simple_button); return(true); }
//---
Agora você não precisa calcular nada, pois basta passar as coordenadas relativas.
Um exemplo do que precisa ser feito agora:
//+------------------------------------------------------------------+ //|| Cria um botão| //+------------------------------------------------------------------+ bool CProgram::CreateSimpleButton(constintx_gap,constinty_gap,conststring button_text) { //--- Passar o objeto do painel m_simple_button.WindowPointer(m_window); //--- Definir propriedades antes da criação m_simple_button.ButtonXSize(100); //--- Criando um botão if(!m_simple_button.CreateSimpleButton(m_chart_id,m_subwin,button_text,x_gap,y_gap)) return(false); //--- Adicione um ponteiro ao elemento na base CWndContainer::AddToElementsArray(0,m_simple_button); return(true); }
//---
Nos seus exemplos acima, você está calculando coordenadas absolutas. Decisão estúpida seguida de conclusões erradas colocadas apressadamente em público.
Os métodos CElement ::X(), CElement ::X2(), CElement ::Y() e CElement::Y2() retornam coordenadas absolutas das bordas do elemento. E foi fácil entender isso apenas com a saída desses valores para o registro do terminal, se houver alguma dúvida.
Abaixo está um exemplo de cálculo da indentação( coordenadarelativa ) em relação a algum elemento. Há dois botões. A coordenada X (relativa) do segundo botão é calculada em relação à borda direita do primeiro botão.
//+------------------------------------------------------------------+ //|| Cria a GUI do programa //+------------------------------------------------------------------+ bool CProgram::CreateGUI(void) { //--- Criando um painel if(!CreateWindow("EXPERT PANEL")) return(false); if(!CreateSimpleButton1(7,25,"BUTTON 1")) return(false); if(!CreateSimpleButton2(m_simple_button1.X2()-m_window.X()+5,25,"BUTTON 2")) return(false); //--- return(true); }
//---
Como resultado, o segundo botão será definido com um recuo de 5 pixels da borda direita do primeiro botão:
//---
Ao alterar a largura ou a coordenada X do primeiro botão, a posição do segundo botão será ajustada automaticamente.
Portanto, os cálculos desnecessários estão apenas em seu exemplo citado acima.
Tenho que colocar esse recálculo em minhas funções para não escrever esse recálculo em todos os lugares ao especificar as coordenadas de um objeto recém-criado, mas para continuar escrevendo como era antes - é mais claro ver a relação de um objeto com outro. É uma questão de gosto e preferências de cada um, é claro...
A propósito, o navegador de arquivos não funciona mesmo quando se especificam as coordenadas, como você disse. Mas talvez seja apenas eu. Vou procurar o motivo.
Anatoly, parece que você esqueceu de editar o FileNavigator.mqh no arquivo
//+------------------------------------------------------------------+ //| Cria uma lista em árvore| //+------------------------------------------------------------------+ #resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\folder_w10.bmp" #resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\text_file_w10.bmp" //--- bool CFileNavigator::CreateTreeView(void) { //--- Salvar o ponteiro da janela m_treeview.WindowPointer(m_wnd); //--- Definir propriedades m_treeview.Id(CElement::Id()); m_treeview.ResizeListAreaMode(true); m_treeview.TreeViewAreaWidth(m_treeview_area_width); m_treeview.ContentAreaWidth(m_content_area_width); m_treeview.AutoXResizeMode(CElement::AutoXResizeMode()); m_treeview.AutoXResizeRightOffset(CElement::AutoXResizeRightOffset()); m_treeview.AnchorRightWindowSide(m_anchor_right_window_side); m_treeview.AnchorBottomWindowSide(m_anchor_bottom_window_side); //--- Formam matrizes da lista de árvores int items_total=::ArraySize(m_g_item_text); for(int i=0; i<items_total; i++) { //--- Definir a imagem para o item (pasta/arquivo) string icon_path=(m_g_is_folder[i])? m_folder_icon : m_file_icon; //--- Se for uma pasta, exclua o último caractere ('\') da string if(m_g_is_folder[i]) m_g_item_text[i]=::StringSubstr(m_g_item_text[i],0,::StringLen(m_g_item_text[i])-1); //--- Adicionar um item à lista da árvore m_treeview.AddItem(i,m_g_prev_node_list_index[i],m_g_item_text[i],icon_path,m_g_item_index[i], m_g_node_level[i],m_g_prev_node_item_index[i],m_g_items_total[i],m_g_folders_total[i],false,m_g_is_folder[i]); } //--- Criar uma lista em árvore if(!m_treeview.CreateTreeView(m_chart_id,m_subwin,m_x-1,m_y+m_address_bar_y_size-1)) return(false); //--- Salvar as dimensões do navegador CElement::XSize(m_treeview.XSize()); CElement::YSize(m_treeview.YSize()+m_address_bar_y_size); return(true); } //+------------------------------------------------------------------+
É aqui que você precisa adicioná-lo:
//--- Criar uma lista em árvore if(!m_treeview.CreateTreeView(m_chart_id,m_subwin,m_x-m_wnd.X()-1,m_y-m_wnd.Y()+m_address_bar_y_size-1)) return(false);
Quero dizer, no site, no artigo - talvez haja um antigo pregado nas atualizações. Peguei o arquivo da atualização mais recente, baixado do site na parte inferior do artigo a partir do zip.
Para login e uso do site MQL5.com, você deve ativar o uso de cookies.
Ative esta opção no seu navegador, caso contrário você não poderá fazer login.
Você entrou na conta. A autenticação de dois fatores foi desativada. Configure-a novamente e escaneie um novo código QR ou continue com a autenticação de dois fatores desativada.
No entanto, parece-me que as alterações recentes relacionadas à especificação de coordenadas por deslocamento a partir da borda do formulário não são muito amigáveis para o usuário final. Se antes o usuário podia usar com segurança duas opções para especificar o local de um objeto na janela, agora uma delas se tornou mais complicada. As coisas desmoronaram assim em toda a tela.
Exemplo:
Botão1 - sua coordenada x está a 4 pixels de distância da borda esquerda da janela do formulário. Ela é definida da seguinte forma: x=m_window.X()+4; O tamanho do botão1 é de 43 pixels de largura. Sua borda direita pode ser obtida da seguinte forma: m_butt1.X2();
Botão2 - sua coordenada está a 2 pixels de distância da borda direita do botão1. Ele é definido da seguinte forma: x=m_butt1.X2()+2; O tamanho do botão2 é de 24 pixels de largura. Sua borda direita pode ser obtida da seguinte forma: m_butt2.X2();
Botão3 - sua coordenada está a 4 pixels de distância da borda direita do botão2. Ele é definido da seguinte forma: x=m_butt2.X2()+4; O tamanho do botão3 é de 18 pixels de largura. Sua borda direita pode ser obtida da seguinte forma: m_butt3.X2();
A barra de separação vertical está a 4 pixels da borda direita do botão3: x=m_butt3.X2()+4;
Portanto, podemos alterar facilmente o tamanho de qualquer um dos três botões, e todos eles estarão localizados no deslocamento que definimos, e a barra de separação estará perfeitamente posicionada no deslocamento que precisamos do botão3.
Button1: x_gap1=4;
Button2: x_gap2=4+m_butt1.XSize()+2;
Button3: x_gap3=4+m_butt1.XSize()+2+m_butt2.XSize()+4;
R-Strip: x_gap4=4+m_butt1.XSize()+2+m_butt2.XSize()+4+m_butt3.XSize()+4;
Aqui é sugerido especificar a coordenada X2() em vez de especificar os tamanhos dos objetos, mas esse não é o caso - tudo desmorona de uma só vez (eu, por exemplo, quebrei a cabeça ao adivinhar que Y2() não aponta para o local correto da coordenada Y).
Vejamos: eu defini as coordenadas do menu com um recuo de 1 pixel na horizontal e com um recuo do tamanho do "cabeçalho" da janela principal. A altura do menu é de 18 pixels.
x=m_window_main.X()+1;
y=m_window_main.Y()+m_window_main.CaptionHeight();
h=18;
O menu está em seu lugar:
Agora preciso colocar a tabela deslocada da borda inferior do menu. Se o CaptionHeight() da janela do formulário for de 18 pixels e a altura do menu também for de 18 pixels, o deslocamento vertical da tabela deverá ser de 36 pixels. Há duas opções: ou nos sentamos com uma calculadora e calculamos todos os deslocamentos necessários (e os recalculamos novamente no caso de ajustes subsequentes com alterações de tamanho) ou tentamos obtê-los. Escolhemos a segunda opção, é claro, e tentamos: para a tabela, o y_gap deve ser igual à altura do título da janela principal mais a altura do menu: m_window_main.CaptionHeight()+m_menu_main.YSize();
x=2;
y=m_window_main.CaptionHeight()+m_menu_main.YSize()+1;
w=140;
Compilar, obter:
A guia está no lugar. Mas. O valor Y2() do menu, nesse caso, não deveria coincidir com o valor que calculamos? Afinal, é mais conveniente não coletar os tamanhos de todos os objetos que se seguem uns aos outros, mas apenas obter suas coordenadas, certo? Vamos tentar: altere o cálculo da coordenada para sua obtenção:
x=2;
//y=m_window_main.CaptionHeight()+m_menu_main.YSize()+1;
y=m_menu_main.Y2()+1;
w=140;
Compile, get:
Y2() não deveria retornar o mesmo Y2 que calculamos anteriormente? m_window_main.CaptionHeight()+m_menu_main.YSize()+1;
Agora não especificamos coordenadas com deslocamento a partir de qualquer borda da janela, mas apenas deslocamento, e apenas a partir do topo ou da esquerda. Bom. Remova da coordenada Y2() obtida a coordenada Y() da parte superior da janela do formulário para obter o valor do deslocamento a partir da parte superior da janela do formulário:
x=2;
//y=m_window_main.CaptionHeight()+m_menu_main.YSize()+1;
y=m_menu_main.Y2()-m_window_main.Y()+1;
w=140;
Compile e obtenha o que deseja:
Então, para vinte objetos que estão a dois pixels de distância um do outro, devemos sempre adicionar seus tamanhos mais o deslocamento um do outro para obter o deslocamento correto para o último objeto? Afinal, Y2() do décimo nono objeto (a partir do qual era possível construir o vigésimo objeto apenas adicionando um deslocamento de dois pontos) agora não nos dá um ponto de partida e não retorna o que é esperado.... e temos que somar os tamanhos de todos os objetos para obter o deslocamento necessário ou, para cada objeto antes de sua criação, temos que calcular seu deslocamento com base em sua coordenada Y2() e na coordenada Y() inicial da janela do formulário.
Não estou entendendo. Anatoly, por favor, me dê uma solução. O que estou fazendo de errado? Por que é assim? Por que você acha que agora está mais amigável? Se antes você podia simplesmente especificar o deslocamento de qualquer borda da janela do formulário, de qualquer objeto nessa janela ou até mesmo da borda do gráfico em geral para criar o objeto necessário, agora você tem que fazer uma dança de pandeiro para calcular suas coordenadas antes de criá-lo? É melhor e mais conveniente escrever mais código e cálculos diferentes?
Entendo que você é o autor e sabe o que é melhor. Mesmo assim, você permite que outras pessoas o utilizem. Eu (apenas minha opinião) acho que essa inovação acabou sendo a única decisão ruim de apresentá-la como uma atualização - ela se tornou pior. Ele não tinha mais os recursos fáceis de criação de interface que tinha antes.
Peço desculpas se o ofendi (antigamente, os mensageiros com más notícias tinham suas cabeças cortadas).
...
Desculpe-me se o ofendi.
Responderei um pouco mais tarde, mas, antes disso, gostaria de esclarecer o que você quer dizer com essa frase em relação a mim. O que são "más notícias" e quem é um "mensageiro" nesse contexto? :)
Responderei um pouco mais tarde, mas, antes disso, gostaria de esclarecer o que você quis dizer com essa frase sobre mim. O que são "más notícias" e quem é um "mensageiro" nesse contexto? :)
:)
Chamei de "más notícias" minha atitude em relação à inovação de que não é mais possível usar qualquer coordenada arbitrária como ponto de referência da coordenada do objeto, mas apenas as bordas esquerda e superior do formulário (adicionei um recálculo das coordenadas no local - cálculos desnecessários).... E o mensageiro sou eu, é claro, já que não gostei e disse isso :)
:)
A má notícia é que chamei minha atitude para a inovação de que agora não é possível tomar qualquer coordenada arbitrária como ponto de referência de coordenadas do objeto, mas apenas as bordas esquerda e superior do formulário (adicionei um recálculo de coordenadas em cálculos locais - desnecessários).... Bem, o mensageiro sou eu, é claro, já que não gostei e disse isso :)
Então, aí está. Muito bom. Porque eu achei que tinha entendido errado. )
Aqui está minha resposta:
No entanto, acho que as alterações recentes relacionadas à especificação de coordenadas por deslocamento da borda do formulário não são muito amigáveis para o usuário final. Se antes o usuário podia usar com segurança duas opções para especificar o local do objeto na janela, agora uma delas se tornou mais complicada. Já aconteceu de as coisas desmoronarem e se dividirem por toda a tela dessa forma.
...
Agora vamos ver o que temos de fazer ao criar a interface de acordo com as novas regras:
Button1: x_gap1=4;
Button2: x_gap2=4+m_butt1.XSize()+2;
Button3: x_gap3=4+m_butt1.XSize()+2+m_butt2.XSize()+4;
R Strip: x_gap4=4+m_butt1.XSize()+2+m_butt2.XSize()+4+m_butt3.XSize()+4;
...
Em vez de especificar os tamanhos dos objetos, você ficaria tentado a especificar a coordenada X2() deles, mas esse não é o caso - tudo desmorona de uma vez (eu, por exemplo, quebrei a cabeça até perceber que Y2() não aponta para o local correto da coordenada Y).
É muito simples. Anteriormente, você tinha que passar coordenadas absolutas para os métodos de criação de elementos. Elas tinham de ser calculadas em relação ao ponto mais à esquerda do formulário ao qual o elemento está anexado.
Aqui está um exemplo do que tivemos de fazer anteriormente:
//|| Cria um botão|
//+------------------------------------------------------------------+
bool CProgram::CreateSimpleButton(const int x_gap,const int y_gap,const string button_text)
{
//--- Salvar o ponteiro no formulário
m_simple_button.WindowPointer(m_window);
//--- Coordenadas
int x=m_window.X()+x_gap;
int y=m_window.Y()+y_gap;
//--- Definir propriedades antes da criação
m_simple_button.ButtonXSize(100);
//--- Criando um botão
if(!m_simple_button.CreateSimpleButton(m_chart_id,m_subwin,button_text,x,y))
return(false);
//--- Adicione um ponteiro ao elemento na base
CWndContainer::AddToElementsArray(0,m_simple_button);
return(true);
}
//---
Agora você não precisa calcular nada, pois basta passar as coordenadas relativas.
Um exemplo do que precisa ser feito agora:
//|| Cria um botão|
//+------------------------------------------------------------------+
bool CProgram::CreateSimpleButton(const int x_gap,const int y_gap,const string button_text)
{
//--- Passar o objeto do painel
m_simple_button.WindowPointer(m_window);
//--- Definir propriedades antes da criação
m_simple_button.ButtonXSize(100);
//--- Criando um botão
if(!m_simple_button.CreateSimpleButton(m_chart_id,m_subwin,button_text,x_gap,y_gap))
return(false);
//--- Adicione um ponteiro ao elemento na base
CWndContainer::AddToElementsArray(0,m_simple_button);
return(true);
}
//---
Nos seus exemplos acima, você está calculando coordenadas absolutas. Decisão estúpida seguida de conclusões erradas colocadas apressadamente em público.
Os métodos CElement ::X(), CElement ::X2(), CElement ::Y() e CElement::Y2() retornam coordenadas absolutas das bordas do elemento. E foi fácil entender isso apenas com a saída desses valores para o registro do terminal, se houver alguma dúvida.
Abaixo está um exemplo de cálculo da indentação( coordenadarelativa ) em relação a algum elemento. Há dois botões. A coordenada X (relativa) do segundo botão é calculada em relação à borda direita do primeiro botão.
//|| Cria a GUI do programa
//+------------------------------------------------------------------+
bool CProgram::CreateGUI(void)
{
//--- Criando um painel
if(!CreateWindow("EXPERT PANEL"))
return(false);
if(!CreateSimpleButton1(7,25,"BUTTON 1"))
return(false);
if(!CreateSimpleButton2(m_simple_button1.X2()-m_window.X()+5,25,"BUTTON 2"))
return(false);
//---
return(true);
}
//---
Como resultado, o segundo botão será definido com um recuo de 5 pixels da borda direita do primeiro botão:
//---
Ao alterar a largura ou a coordenada X do primeiro botão, a posição do segundo botão será ajustada automaticamente.
Portanto, os cálculos desnecessários estão apenas em seu exemplo citado acima.
//|| Cria a GUI do programa
//+------------------------------------------------------------------+
bool CProgram::CreateGUI(void)
{
//--- Criando um painel
if(!CreateWindow("EXPERT PANEL"))
return(false);
if(!CreateSimpleButton1(7,25,"BUTTON 1"))
return(false);
if(!CreateSimpleButton2(m_simple_button1.X2()-m_window.X()+5,25,"BUTTON 2"))
return(false);
//---
return(true);
}
//---
Como resultado, o segundo botão será definido com um recuo de 5 pixels a partir da borda direita do primeiro botão:
//---
Ao alterar a largura ou a coordenada X do primeiro botão, a posição do segundo botão será ajustada automaticamente.
Portanto, os cálculos extras estão apenas em seu exemplo citado acima.
Aqui... Isso não ficou muito claro:
if(!CreateSimpleButton2(m_simple_button1.X2()-m_window.X()+5,25,"BUTTON 2"))
Tenho que colocar esse recálculo em minhas funções para não escrever esse recálculo em todos os lugares ao especificar as coordenadas de um objeto recém-criado, mas para continuar escrevendo como era antes - é mais claro ver a relação de um objeto com outro. É uma questão de gosto e preferências de cada um, é claro...
A propósito, o navegador de arquivos não funciona mesmo quando se especificam as coordenadas, como você disse. Mas talvez seja apenas eu. Vou procurar o motivo.
Capturas de tela da plataforma de negociação MetaTrader
EURUSD, D1, 2016.12.12
MetaQuotes Software Corp., MetaTrader 5, Demonstração
Anatoly, parece que você esqueceu de editar o FileNavigator.mqh no arquivo
//| Cria uma lista em árvore|
//+------------------------------------------------------------------+
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\folder_w10.bmp"
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\text_file_w10.bmp"
//---
bool CFileNavigator::CreateTreeView(void)
{
//--- Salvar o ponteiro da janela
m_treeview.WindowPointer(m_wnd);
//--- Definir propriedades
m_treeview.Id(CElement::Id());
m_treeview.ResizeListAreaMode(true);
m_treeview.TreeViewAreaWidth(m_treeview_area_width);
m_treeview.ContentAreaWidth(m_content_area_width);
m_treeview.AutoXResizeMode(CElement::AutoXResizeMode());
m_treeview.AutoXResizeRightOffset(CElement::AutoXResizeRightOffset());
m_treeview.AnchorRightWindowSide(m_anchor_right_window_side);
m_treeview.AnchorBottomWindowSide(m_anchor_bottom_window_side);
//--- Formam matrizes da lista de árvores
int items_total=::ArraySize(m_g_item_text);
for(int i=0; i<items_total; i++)
{
//--- Definir a imagem para o item (pasta/arquivo)
string icon_path=(m_g_is_folder[i])? m_folder_icon : m_file_icon;
//--- Se for uma pasta, exclua o último caractere ('\') da string
if(m_g_is_folder[i])
m_g_item_text[i]=::StringSubstr(m_g_item_text[i],0,::StringLen(m_g_item_text[i])-1);
//--- Adicionar um item à lista da árvore
m_treeview.AddItem(i,m_g_prev_node_list_index[i],m_g_item_text[i],icon_path,m_g_item_index[i],
m_g_node_level[i],m_g_prev_node_item_index[i],m_g_items_total[i],m_g_folders_total[i],false,m_g_is_folder[i]);
}
//--- Criar uma lista em árvore
if(!m_treeview.CreateTreeView(m_chart_id,m_subwin,m_x-1,m_y+m_address_bar_y_size-1))
return(false);
//--- Salvar as dimensões do navegador
CElement::XSize(m_treeview.XSize());
CElement::YSize(m_treeview.YSize()+m_address_bar_y_size);
return(true);
}
//+------------------------------------------------------------------+
É aqui que você precisa adicioná-lo:
if(!m_treeview.CreateTreeView(m_chart_id,m_subwin,m_x-m_wnd.X()-1,m_y-m_wnd.Y()+m_address_bar_y_size-1))
return(false);
...
A propósito, o navegador de arquivos trava mesmo ao especificar as coordenadas, como você disse. Mas talvez seja só eu. Fui procurar o motivo.
Não consegui reproduzi-lo:
Eu mesmo não o reproduzi:
Verifique o FileNavigator.mqh na atualização mais recente.
Esse é o mais recente.
Quero dizer, no site, no artigo - talvez haja um antigo pregado nas atualizações. Peguei o arquivo da atualização mais recente, baixado do site na parte inferior do artigo a partir do zip.
Aqui, fiz as correções conforme escrevi acima:
Capturas de tela da plataforma de negociação MetaTrader
EURUSD, W1, 2016.12.12
MetaQuotes Software Corp., MetaTrader 5, Demo