Galeria de UIs escritas em MQL - página 58

 
hini #:

Sim, é importante liberar um programa completo primeiro.

Eu o farei.
 
Uma versão básica totalmente funcional do mecanismo e do construtor é uma meta válida e alcançável. Ela exige um plano claro e priorização. Por sua vez, isso significa o fim da adição de grandes tarefas aos planos e o início da solução de problemas urgentes.

Vou fazer uma analogia com a construção de um prédio alto. Vamos imaginar um projeto em que o encarregado não sabe exatamente quantos andares precisam ser construídos. Vamos supor que ele não tenha sido informado. Mas, no fundo, ele é um criador, uma pessoa criativa. Ele não se importa. Quanto maior, melhor. Ele gosta de casas altas e arranha-céus. Enquanto ele está trabalhando, a construção continua, os andares são acrescentados e o edifício cresce até o céu. Mas os apartamentos não podem ser entregues aos inquilinos, porque os andaimes não foram removidos e o espaço não foi limpo. Nem mesmo as portas foram colocadas. A casa está inacabada. Mas, para o encarregado, isso é insignificante. Ele está olhando para cima. Para o céu. E os inquilinos estão esperando impacientemente, eles precisam de apartamentos.

Em geral, é hora de o encarregado "mudar o firmware" e se reorganizar mentalmente. Parar de construir andares e começar a colocar portas nas aberturas. E, finalmente, começar a limpar a área, rebocar as paredes, colocar o parquet e instalar lustres ....

Deixe-me colocar desta forma: os pisos, por enquanto, não serão construídos. Em vez disso, os pisos que já foram construídos serão finalizados. O trabalho será planejado de forma que a casa seja entregue aos inquilinos o mais rápido possível.

Afinal de contas, a casa foi construída para eles....


 

Olá a todos,

À luz da discussão recente, gostaria de propor que documentássemos os resultados e o progresso do projeto de Peter Konow no "Codebase" em vez de no fórum. O fórum é excelente para discussões e feedback imediato, mas não tem a estrutura e a coerência necessárias para apresentar o quadro geral e as políticas consistentes do projeto.

Ao usar o Codebase, podemos garantir que todas as informações relevantes sejam organizadas, facilmente acessíveis e forneçam uma visão geral clara do status do projeto. Isso não só ajudará a manter a clareza, mas também facilitará uma melhor colaboração e compreensão entre todos os membros da equipe e partes interessadas.

Ficaria muito grato se você pudesse considerar essa sugestão.

 
Yutaka Okamoto projeto de Peter Konow sejam documentados no Codebase em vez de no fórum. O fórum é ótimo para discussões e feedback imediato, mas não tem a estrutura e a coerência necessárias para apresentar o panorama geral e as políticas consistentes do projeto.

Com o uso de uma "base de código", podemos garantir que todas as informações relevantes sejam organizadas, facilmente acessíveis e forneçam uma visão clara do status do projeto. Isso não só ajudará a manter a clareza, mas também promoverá uma melhor cooperação e compreensão entre todos os membros da equipe e as partes interessadas.

Ficaria muito grato se você considerasse essa proposta.

É uma sugestão muito racional, obrigado. Sem dúvida, a base de código é conveniente para a publicação de atualizações e a comunicação com os usuários. É um ótimo complemento para o desenvolvimento do projeto. Embora eu quase não tenha usado a base de código no passado, agora vejo o sentido prático de explorar os termos e condições e me adaptar aos requisitos. Para ter uma ideia das possibilidades e limitações dessa plataforma, procurarei projetos de membros conhecidos da comunidade. Tomando o exemplo deles, poderei conduzir o projeto na base de código de forma informativa e competente.

 

Tenho uma versão programada para hoje.

No entanto, decidi seguir o conselho útil de um membro do fórum e publicar a nova versão na base de código. Para fazer isso corretamente, precisarei de alguns dias para estudar exemplos de publicações semelhantes, para fazer um plano de execução paralela do projeto no fórum e lá. E também para passar pela moderação.

Algumas palavras sobre esta versão:

1. Conceitualizei e implementei um sistema de interação programática entre um programa de usuário e sua interface gráfica.

Mais detalhes:

  • Após a realização de testes técnicos e a análise dos resultados, decidiu-se usar funções de elemento em vez de propriedades globais abstratas. Como se viu, essa é a variante mais eficaz e simples do acoplamento de programas de algoritmos com o ambiente gráfico.
  • Foram feitos acréscimos às funções de salvamento de projetos e impressão de arquivos UIDATA.mqh e API.mqh para que cada elemento interativo da interface receba uma função de wrapper automaticamente quando o projeto for salvo.
  • Ao mesmo tempo, as funções de wrapper de elemento têm um corpo muito pequeno e sua principal tarefa é chamar a função central, passando três parâmetros principais: número do elemento, valor e valor da propriedade.
  • Asimplicidade externa das funções não impede a versatilidade de sua aplicação:

1. Quando chamadas com colchetes vazios, as funções retornam o valor do parâmetro do elemento com um dos três tipos: int, double, string dependendo do tipo do elemento.

     int i    = w6_i_CHECKBOX_Some_checkbox(); //Элемент чекбокс. Буква i  после префикса означает что тип возвращаемого/устанавливаемого значения int.
     
     double d = w6_d_S_EDIT_Spin_the_value();  //Элемент поле ввода с кнопками. Буква d после префикса означает что тип возвращаемого/устанавливаемого значения double.

     string s = w7_s_EDIT_Comment_1();         //Элемент текстовое поле ввода. Буква s означает что тип возвращаемого/устанавливаемого значения string.

2. Quando chamadas com um valor entre colchetes, as funções definem o valor passado para o parâmetro do elemento e, em seguida, o redesenham (o valor é definido como int, double ou string, dependendo do tipo de elemento).

     int i    = w6_i_CHECKBOX_Some_checkbox(0/1/2/3); //Элемент чекбокс. Передача нуля,единицы, двойки или тройки для смены между нейтральным, активированным, нетр.блокир. и актив. блокир. состояниями элемента. 
                                                      //Тот же метод работает для всех кнопок.
     
     double d = w6_d_S_EDIT_Spin_the_value(653.89);   //Элемент поле ввода с кнопками. Передача значения параметра в функцию для установки его в элемент.

     string s = w7_s_EDIT_Comment_1("Any text");      //Элемент текстовое поле ввода. Передача текста для установки в поле ввода.   


3. Quando chamadas com o valor padrão do primeiro parâmetro e um número de propriedade (dentre as propriedades disponíveis), as funções retornam o valor dessa propriedade do elemento (todos os números de propriedade são do tipo int, passados no parâmetro de propriedade).

      int i = w6_i_BUTTON_Start(get_i,_A_COLOR); //Элемент Кнопка. Возврат значения цвета из свойства _A_COLOR. Может быть указано другое значение или другое свойство из списка доступных свойств.
                                                                  //Однако, данных тип функции принимает значения только типа int, но может приводить их к другим родственным типам (uint, short, bool...).
                                                                  //Значение первого параметра get_i говорит функции что не нужно принимать значение первого параметра в расчет, а лишь вернуть значение свойства _A_COLOR.


4 . Quando chamadas comvalue e propertyvalue entre parênteses, as funções definem os valores passados para as propriedades disponíveis do elemento. Onúmero da propriedade é passado no parâmetro property e o valor da propriedadeé passado no parâmetrovalue .

     int i = w6_i_BUTTON_Start(C'255,0,0',_A_COLOR); //Элемент Кнопка. Передача и установка польз. значения цвета в свойство _A_COLOR. Может быть указано другое значение или другое свойство из списка доступных свойств.
                                                                      //Однако, тип функции этого элемента принимает значения только типа int, но может приводить их к другим родственным типам (uint, short, bool...).


A estrutura dos nomes do invólucro da função: w6_i_BUTTON_Start();

1. w é a letra inicial de todas as funções de wrapper. É uma abreviação de window.

2. 6 (ou outro número) - o número de sequência da janela que contém o elemento.

3. i (d ou s) - significa o tipo do valor retornado/definido do parâmetro do elemento.

  • Pode ser int: para botões, caixas de seleção, controles deslizantes, campos de entrada com/sem botões, barras de progresso, barras de gráfico, botões de rádio.
  • Pode ser double: para controles deslizantes, campos de entrada com/sem botões.
  • Pode ser string: para campos de entrada de texto, para elementos VALUE, para células de tabela, para listas pop-up.


4. BOTÃO - nome do tipo de elemento ao qual pertence a função de invólucro. Pode ser qualquer outro elemento.

5. start - nome de um elemento específico .


  • Todas as funções de wrapper têm uma estrutura de nome idêntica.
  • Repito: todas as funções são impressas automaticamente.

//----------------------------------------------------------------------------------------------------

Aplicação inteligente do sistema intellisense:

Decidiu-se usar um sistema de prefixo especial que ajuda a pesquisar e encontrar rapidamente as funções necessárias - wrappers de janelas e elementos. Aqui está um exemplo:

Todas as funções de wrapper de janelas e elementos têm a letra w no início. Entretanto, se você colocar um traço inferior depois de w: _ uma janela do intellisense será aberta com uma lista de nomes de todas as funções de janela da interface do usuário. Em seguida, você precisa encontrar a janela com o nome que está procurando na lista, observar seu número (que está impresso no nome da função), apagar o traço e colocar esse número depois de w. A lista do intellisense com os nomes das funções dos elementos incluídos na janela aparecerá imediatamente. Veja como isso é feito:

Essa é uma maneira simples de navegar rapidamente pela lista de funções de elementos. Você não precisa nem mesmo imprimi-las.

//----------------------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------

Além disso, foram feitas alterações e adições ao arquivo de API. Agora, mais informações sobre o elemento e a janela estão disponíveis para o usuário:

 switch(Element)
   {
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      BUTTON
//NAME:         Start
//PARAMETER:    int
//INIT STATE:   OFF
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   int w6_i_BUTTON_Start(int value = none, int Property = 0)      | PFX: w6
//=====================================================================================================================
  
case Settings_example_1___Start:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when button pressed or released?
               //------------------------------------------------------------------------------------------------------
               switch((int)action)
               {
                case pressed:  Alert("BUTTON Start pressed!");   break;
  
                case released:  Alert("BUTTON Start released!");   break;
               }
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
  
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      CHECKBOX
//NAME:         Set an option
//PARAMETER:    int
//INIT STATE:   OFF
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   int w6_i_CHECKBOX_Set_an_option(int value = none, int Property = 0)      | PFX: w6
//=====================================================================================================================
  
case Settings_example_1___Set_an_option:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when checkbox checked or unchecked?
               //------------------------------------------------------------------------------------------------------
               switch((int)action)
               {
                case checked:  Alert("CHECKBOX Set_an_option pressed!");   break;
  
                case unchecked:  Alert("CHECKBOX Set_an_option released!");   break;
               }
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
  
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      CHECKBOX
//NAME:         Set another option
//PARAMETER:    int
//INIT STATE:   OFF
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   int w6_i_CHECKBOX_Set_another_option(int value = none, int Property = 0)      | PFX: w6
//=====================================================================================================================
  
case Settings_example_1___Set_another_option:
  
               //------------------------------------------------------------------------------------------------------
               //What to do when checkbox checked or unchecked?
               //------------------------------------------------------------------------------------------------------
               switch((int)action)
               {
                case checked:  Alert("CHECKBOX Set_another_option pressed!");   break;
  
                case unchecked:  Alert("CHECKBOX Set_another_option released!");   break;
               }
               //------------------------------------------------------------------------------------------------------
               //Your comment:
               //------------------------------------------------------------------------------------------------------
               break;
  
//=====================================================================================================================
//WINDOW:       Settings example 1 | #: 6 | PFX: w_6 | GET/SET: int w_6_Settings_example_1(int value = get_i, int Property = 0)
//---------------------------------------------------------------------------------------------------------------------
//ELEMENT:      D_LIST
//NAME:         D_LIST 1
//PARAMETER:    string
//INIT OPTION:  L_ITEM  1
//LOCATION:     Location: Window's Main Frame
//---------------------------------------------------------------------------------------------------------------------
//GET/SET:   string w6_s_D_LIST_D_LIST_1(string value = get_s, int Property = 0)      | PFX: w6
//=====================================================================================================================
 
Espero poder experimentar esses recursos em breve.
 
hini #:
Espero poder testar esses recursos em breve.
Farei o upload da nova versão para o codobase amanhã à noite.
 
Lançamento tarde da noite.
 

Apresento uma versão do mecanismo que interage programaticamente com a GUI.

Fiz muita coisa. Há algo para contar e mostrar.

Após o teste público, eu o carregarei na base de código.

Aconteceu uma coisa interessante...

Mais detalhes amanhã.

Arquivos anexados:
4uh38_06.08.24.zip  1712 kb
 

Um pouco antes do tempo, posso dizer que encontrei uma solução muito conveniente para os usuários. Dentro de seu código, eles podem navegar facilmente por janelas, elementos e propriedades. A solução permite que eles não se lembrem dos nomes dos elementos ou das propriedades, mas encontrem e trabalhem com eles facilmente. Ao mesmo tempo, cada elemento tem uma lista de propriedades get/set disponíveis somente para ele e para os elementos "relacionados". Com o prefixo incorporado no nome da função do elemento, o usuário a chama e nunca cometerá o erro de tentar retornar ou definir uma propriedade que o elemento não possui.

As funções de wrapper se mostraram tão versáteis e fáceis de usar que eu mesmo fiquei surpreso. Retornam o valor de um parâmetro quando os colchetes estão vazios, definem quando o valor é um, retornam o valor de uma propriedade de uma lista quando o primeiro parâmetro está vazio e o índice da propriedade está no segundo. Eles definem um valor para uma propriedade quando há um valor no primeiro parâmetro e um índice de propriedade no segundo. Elas também retornam uma notificação de resultado como 1 em caso de sucesso e -1 em caso de erro (valor ou propriedade inválida). As funções redesenham os próprios elementos. Você não precisa se preocupar com isso.

O que você pode fazer com as funções de wrapper:

1. Obter o valor do parâmetro do elemento.

2. Definir o valor de um parâmetro de elemento.

3. Obter valores de propriedades de elementos da lista individual de propriedades pertencentes ao seu tipo de elementos (chamado pelo prefixo escrito no nome da função).

4. Definir valores de propriedades de elementos da mesma lista.

5. Definir o estado do elemento: neutro, ativado, (ligado/desligado), neutro bloqueado, ativado bloqueado.

6. Retorna o estado atual do elemento.


No primeiro caso, a função retorna o valor do parâmetro.

No segundo caso, ela retorna o resultado: bem-sucedido ou erro. O erro é enviado para o registro.

No terceiro caso, retorna o valor da propriedade.

No quarto - resultado: sucesso ou erro na definição da propriedade.

No quinto, retorna 1 ou -1.

No sexto - retorna o índice de estado do elemento (detalhes abaixo).


Tudo é feito por uma função de wrapper que é impressa automaticamente. Para encontrá-la, digite w_, a lista do intellisense será aberta e conterá os nomes das janelas. Em uma delas está o elemento que você está procurando. Você precisa se lembrar aproximadamente em qual janela ele está. Em seguida, apague o demônio e digite o número da janela e selecione a que você precisa na lista de itens. Sem memorização.

Você também não precisa se lembrar das propriedades dos elementos. Dê uma olhada no nome do recurso e veja o prefixo para abrir uma lista de propriedades individuais. Digite-o, abra-o e selecione a propriedade. Você não precisa se lembrar de nada. Também não precisa digitar nada. O Intellisense faz tudo.

O Windows também tem seus próprios wrappers. Eles podem abri-los e fechá-los. O restante dos recursos ainda não foi implementado.


Fiz uma grande atualização no arquivo da API. Ele agora tem uma quantidade ENORME de informações mais úteis sobre o elemento. A saber: prefixos, propriedades individuais, protótipos da função do elemento e sua janela, a localização exata do elemento (tabela, tela e guia à qual o elemento pertence, se houver), o tipo de seu parâmetro (int, double, string...), as propriedades de seu parâmetro (valor mínimo, valor máximo, etapa, número de dígitos após o ponto decimal) são impressos. Valor inicial ou opção selecionada (dependendo do elemento). Tudo foi projetado de forma bastante legível e compreensível.

Testei parcialmente a nova funcionalidade e estou satisfeito com ela. Tudo funciona como planejado.

Amanhã mostrarei isso na prática.