Discussão do artigo "Linguagem MQL como um meio de marcação da interface gráfica de programas MQL. Parte II"

 

Novo artigo Linguagem MQL como um meio de marcação da interface gráfica de programas MQL. Parte II foi publicado:

Neste artigo continuaremos testando um novo conceito, em particular a descrição da interface de programas MQL usando as construções da linguagem MQL. A criação automática de GUIs com base no layout MQL fornece funcionalidade adicional para armazenamento em cache e geração dinâmica de elementos, gerenciamento de estilos e novos esquemas de manipulação de eventos. Incluímos uma versão aprimorada da biblioteca de controles padrão.

Podemos excluir qualquer elemento da interface que esteja no cache, ou seja, não apenas os adicionados pelo botão Inject. Dessa forma, podemos, por exemplo, excluir toda a metade esquerda ou a "caixa de rádio" direita. Mas a coisa mais interessante acontece se tentarmos remover o recipiente superior com dois botões. Como resultado, o botão Export perderá a vinculação com a caixa de diálogo e permanecerá no gráfico.

Formulário editável: adição e remoção de elementos

Formulário editável: adição e remoção de elementos

Isso acontece porque este é o único elemento que é intencionalmente descrito como uma variável automática, não uma variável dinâmica (a classe do formulário possui uma instância CButton m_button3).

Quando a biblioteca padrão tenta remover elementos da interface, ela delega isso à classe de matrizes CArrayObj, que por sua vez verifica o tipo de ponteiro e remove apenas objetos com POINTER_DYNAMIC. Assim, torna-se óbvio que, para a construção de uma interface responsiva, na qual os elementos possam se substituir ou serem completamente removidos, é desejável usar posicionamento dinâmico, e o cache oferece uma solução pronta para isso.

Autor: Stanislav Korotky

 
Прилагается усовершенствованная версия стандартной библиотеки элементов управления.

Então, tudo isso só funcionará com uma versão aprimorada da biblioteca padrão?

 
Não vou criticar o artigo por muito tempo, porque já está claro que o autor não pensa no leitor. Ele está falando consigo mesmo e será compreendido por aqueles que estão perfeitamente familiarizados com a biblioteca padrão - suas classes, métodos e variáveis. O autor "galopa" pelos códigos que conhece e modifica algo....

A falta de apresentação dos princípios gerais da biblioteca, da linguagem ou do editor reduz o valor do artigo. Todos podem "cavar" nas "entranhas" com palavras inteligentes, mas explicar a tecnologia em uma linguagem clara - não, porque você realmente precisa entender sua essência. Receio que o autor tenha sido vítima da ilusão de que ele criará uma linguagem de marcação a partir de uma biblioteca (que ele aprendeu) e, em seguida, criará imediatamente um estúdio. Ao mesmo tempo, ele considera ingenuamente que a emborrachamento de janelas e a adição de um elemento a um formulário são provas.

Como não vou esperar pelos conceitos do autor, não estou interessado em assistir a essa ação incompreensível. É uma pena. É uma pena que o autor tenha dificuldade em realizar suas ambições e provar o "ridículo" de seus resultados.

Boa sorte!
 
Реter Konow:
Não vou criticar o artigo por muito tempo, porque já está claro que o autor não pensa no leitor. Ele está falando consigo mesmo e será compreendido por aqueles que estão perfeitamente familiarizados com a biblioteca padrão - suas classes, métodos e variáveis. O autor "galopa" pelos códigos que conhece e modifica algo....

A falta de apresentação dos princípios gerais da biblioteca, da linguagem ou do editor reduz o valor do artigo. Todos podem "cavar" nas "entranhas" com palavras inteligentes, mas explicar a tecnologia em uma linguagem clara - não, porque você realmente precisa entender sua essência. Receio que o autor tenha sido vítima da ilusão de que ele criará uma linguagem de marcação a partir de uma biblioteca (que ele aprendeu) e, em seguida, criará imediatamente um estúdio. Ao mesmo tempo, ele considera ingenuamente que a emborrachamento de janelas e a adição de um elemento a um formulário são confirmações.

Como não vou esperar pelos conceitos do autor, não estou interessado em assistir a essa ação incompreensível. É uma pena. É uma pena que o autor tenha dificuldade em realizar suas ambições e provar o "ridículo" de seus resultados.

Boa sorte!

E aquele que conhece perfeitamente essa biblioteca dificilmente precisará de acréscimos.

 
Dmitry Fedoseev:

E é improvável que alguém que esteja perfeitamente familiarizado com essa biblioteca precise de acréscimos.

Se você ler a conclusão do artigo com atenção, poderá entender as conclusões (controversas) do autor:

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

1. o autor afirma ter verificado "a viabilidade do conceito de descrever o layout da interface gráfica dos programas MQL na própria linguagem MQL" (c).

  • Devido às especificidades da apresentação do material, não posso dizer nada a favor/contra essa conclusão. Ela não é óbvia.

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

2. "O uso da geração dinâmica de elementos com armazenamento centralizado no cache permite simplificar a criação e o gerenciamento da hierarquia de componentes. A maioria das tarefas relacionadas ao design da interface, como alterações uniformes de estilo, manipulação de eventos, edição imediata do layout e salvamento em um formato adequado para uso posterior, pode ser implementada com base no cache." (c)

  • Não está claro em que base teórica essa conclusão foi alcançada, pois não há descrição da tecnologia e o leitor não pode concordar nem negar. O leitor deve ser apresentado à tecnologia e, então, concordará com a prova de realisabilidade.

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

3. "Se você juntar esses recursos, verá que quase tudo está disponível para um editor de formulários visual simples. Ele poderia suportar apenas as propriedades mais importantes comuns a muitos "controles", mas ainda permitiria a formação de espaços em branco na interface."(c)

  • Novamente, sem uma descrição generalizada das nuances tecnológicas, o leitor que não é fluente no sistema de produção de editores visuais a partir de bibliotecas de gráficos não pode concordar nem argumentar com o autor. Não é óbvio.

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

4. "No entanto, vemos que mesmo a fase inicial de avaliação do novo conceito exigiu muito esforço. A implementação de um editor completo na prática é, portanto, um grande desafio. E essa é outra história." (c)

  • Na minha opinião, essa é a conclusão MAIS objetiva. Ou seja, "implementar um editor completo é outra história". Eu concordaria com essa conclusão. Não se pode simplesmente "correr" para fazer isso (eu mesmo estou tentando fazer isso há vários anos).

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

Minha conclusão: na conclusão do artigo (ou seja, na última conclusão), o autor está mais próximo da realidade. Porém, o artigo é destinado a leitores que devem chegar às mesmas conclusões à medida que o tópico se desenvolve e, para isso, é necessário revelar gradualmente a tecnologia. A principal desvantagem dos dois artigos é que não há divulgação da tecnologia. Seu conteúdo é uma discussão sobre a implementação das soluções não óbvias do autor sem nenhum prefácio. Espero que o autor leve isso em consideração.

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
В языке MQL5 предусмотрена обработка некоторых предопределенных событий. Функции для обработки этих событий должны быть определены в программе MQL5: имя функции, тип возвращаемого значения, состав параметров (если они есть) и их типы должны строго соответствовать описанию функции-обработчика события. Именно по типу возвращаемого значения и по...
 
Реter Konow:

Se você ler a conclusão do artigo com atenção, poderá entender as conclusões (controversas) do autor:

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

1. o autor afirma ter verificado "a viabilidade do conceito de descrever o layout da interface gráfica dos programas MQL na própria linguagem MQL" (c).

  • Devido às especificidades da apresentação do material, não posso dizer nada a favor/contra essa conclusão. Ela não é óbvia.

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

2. "O uso da geração de elementos dinâmicos com armazenamento centralizado em um cache facilita a criação e o gerenciamento de uma hierarquia de componentes. A maioria das tarefas relacionadas ao design da interface pode ser implementada com base no cache, como alterações uniformes de estilo, manipulação de eventos, edição do layout em tempo real e salvamento em um formato adequado para uso posterior." (c)

  • Não se sabe com que base teórica se chegou a essa conclusão, já que não há descrição da tecnologia e o leitor não pode concordar nem negar. O leitor deve ser apresentado à tecnologia e, então, concordará com a prova de realisabilidade.

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

3. "Se você juntar esses recursos, verá que quase tudo está disponível para um editor de formulários visual simples. Ele poderia suportar apenas as propriedades mais importantes comuns a muitos "controles", mas ainda assim permitir que você formasse espaços em branco na interface."(c)

  • Novamente, sem uma descrição generalizada das nuances tecnológicas, o leitor que não é fluente no sistema de produção de editores visuais a partir de bibliotecas de gráficos não pode concordar nem argumentar com o autor. Não é óbvio.

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

4. "No entanto, vemos que mesmo a fase inicial de avaliação do novo conceito exigiu muito esforço. A implementação de um editor completo na prática é, portanto, um grande desafio. E essa é outra história." (c)

  • Na minha opinião, essa é a conclusão MAIS objetiva. Ou seja, "implementar um editor completo é outra história". Eu concordaria com essa conclusão. Você não pode simplesmente fazer isso "descaradamente" (eu mesmo tentei fazer isso por vários anos).

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

Minha conclusão: na conclusão do artigo (ou seja, na última conclusão), o autor está mais próximo da realidade. Porém, o artigo é destinado a leitores que devem chegar às mesmas conclusões à medida que o tópico se desenvolve e, para isso, é necessário revelar gradualmente a tecnologia. A principal desvantagem dos dois artigos é que não há divulgação da tecnologia. Seu conteúdo é uma discussão sobre a implementação das soluções não óbvias do autor , sem qualquer prefácio a elas. Espero que o autor leve isso em consideração.

Eu me absterei, pois isso é proibitivo.

 

Fiz uma análise minuciosa do conteúdo do artigo e percebi que há "partículas" da tecnologia que eu estava procurando, mas elas estão arbitrariamente espalhadas pelo material. Ou seja, o autor não separou a teoria da implementação e misturou tudo, no processo de separação com abundantes exemplos de código. Decidi reunir os fundamentos de seu conceito em um só lugar para ter uma ideia completa dele.

Cópias dos fragmentos do artigo que explicam a tecnologia (a sequência foi preservada, os exemplos de código foram omitidos):

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

1. a estrutura geral da biblioteca de elementos padrão, levando em conta as versões adaptadas com suporte para "rubberstamping" e contêineres de terceiros, é fornecida no diagrama de classes. (minha adição: o diagrama é fornecido).

2. geração de elementos e armazenamento em cache

Até agora, os elementos foram construídos como instâncias automáticas em um objeto de janela. Eles são essencialmente "espaços em branco" que são inicializados por métodos como Create. O sistema de layout de elementos da GUI pode criar esses elementos por conta própria, em vez de buscá-los em uma janela. Para isso, basta ter algum tipo de armazenamento. Vamos chamá-lo de LayoutCache. Basicamente, é uma matriz de ponteiros da classe base (comum a todos os elementos), onde eles podem ser colocados usando o método save. A interface também implementa (se possível nesse nível abstrato) ou declara (para substituição posterior) métodos para pesquisar elementos por número, nome, referência ou fato da relação "pai" (feedback de elementos aninhados para o contêiner).

Vamos adicionar um cache como um membro estático à classe LayoutBase. Cada janela terá de criar uma instância de cache para si mesma e defini-la como um cache de trabalho usando setCache no início de um método como CreateLayout. Como os programas MQL são de thread único, temos a garantia de que as janelas (se forem necessárias várias) não serão formadas em paralelo e competirão pelo ponteiro do cache. Limparemos o ponteiro automaticamente no destrutor do LayoutBase quando a pilha terminar - isso significa que deixamos o último contêiner externo na descrição do layout e não há necessidade de salvar mais nada. Zerar a referência não significa que estamos limpando o cache. Isso apenas garante que o próximo layout em potencial não adicione erroneamente "controladores" de outra janela. Para preencher o cache, vamos adicionar um novo tipo de método init ao LayoutBase - desta vez sem um ponteiro ou referência a um elemento de GUI "de terceiros" nos parâmetros. Devido ao modelo, temos a capacidade de escrever um novo T e gerar objetos durante o processo de layout (por padrão, um objeto por vez, mas opcionalmente podemos ter vários).

Uma implementação concreta de cache é escrita para os elementos da biblioteca padrão - StdLayoutCache (aqui apresentada com abreviações, o código completo está no apêndice).

Observe que o método get procura um "controle" pelo número de sequência (se o parâmetro de entrada for positivo) ou pelo identificador (ele é passado com um sinal de menos). Aqui, por identificador, queremos dizer um número exclusivo atribuído pela biblioteca de componentes padrão para envio de eventos. Nos eventos, ele é passado no parâmetro lparam.

3. estilizador

Como o cache é um objeto que processa elementos de forma centralizada, é conveniente usá-lo para executar muitas outras tarefas além da estilização. Em particular, as regras de um único estilo (cor, fonte, recuo) podem ser aplicadas aos elementos de forma unificada. Basta configurar esse estilo em um único local, em vez de escrever as mesmas propriedades para cada "controle" separadamente. Além disso, o cache pode assumir a tarefa de lidar com mensagens para elementos armazenados em cache. Potencialmente, podemos construir dinamicamente, armazenar em cache e interagir com absolutamente todos os elementos. Assim, não precisaremos declarar nenhum elemento "explícito" na janela. Um pouco mais adiante, veremos como os elementos criados dinamicamente se comparam favoravelmente aos elementos automáticos.

Para dar suporte a estilos centralizados, a classe StdLayoutCache tem um método stall: O método apply será chamado para cada "controle" duas vezes: no estágio de inicialização (STYLE_PHASE_BEFORE_INIT) e no estágio de registro no contêiner (STYLE_PHASE_AFTER_INIT). Assim, os métodos LayoutBase::init adicionam uma chamada à primeira fase, e o destrutor adiciona cadeias de caracteres semelhantes, mas com STYLE_PHASE_AFTER_INIT para a segunda fase.

São necessárias duas fases porque as finalidades de estilo são diferentes. Às vezes, alguns elementos precisam ter propriedades individuais com prioridade mais alta do que as propriedades gerais definidas no estilizador. Na fase de inicialização, o "controle" ainda está vazio, sem as configurações feitas no layout. Na fase de registro, todas as propriedades já estão definidas nele e você pode alterar o estilo com base nelas. O exemplo mais óbvio é o seguinte. É desejável exibir todos os campos de entrada com o sinalizador "somente leitura" em cinza. Mas a propriedade "read-only" é atribuída ao "controle" durante o processo de layout, após a inicialização, de modo que o primeiro estágio não é adequado e o segundo estágio é necessário. Por outro lado, normalmente nem todos os campos de entrada terão esse sinalizador e, em todos os outros casos, é necessário definir a cor padrão antes que a linguagem de layout execute a personalização seletiva.

A propósito, uma tecnologia semelhante pode ser usada para a localização centralizada da interface dos programas MQL em diferentes idiomas nacionais.

4. processamento de eventos

A segunda função, que é logicamente atribuída ao cache, é o processamento de eventos. Para eles, na classe LayoutCache, é adicionado um método stub (C é um parâmetro do modelo da classe): Novamente, ele pode ser implementado em uma classe derivada, mas não necessariamente. Os códigos de evento são definidos pela biblioteca específica.

Para que esse método funcione, precisamos de definições de macro de captura de eventos semelhantes às da biblioteca padrão e escritas no mapa, por exemplo, assim: As novas macros redirecionarão os eventos para o objeto de cache.

5. Exemplo 2. Diálogo com controles

O projeto de demonstração contém a classe CControlsDialog com os tipos básicos de "controles" da biblioteca padrão. Por analogia com o primeiro exemplo, vamos remover todos os métodos para sua criação e substituí-los por um único CreateLayout. A propósito, havia 17 métodos desses métodos no projeto antigo, e eles eram chamados uns dos outros com a ajuda de operadores condicionais complexos. Na classe de cache, é declarado o manipulador de eventos onEvent, que conectaremos por meio do mapa de eventos. Aqui, o manipulador reflete a mensagem para a janela pai, onde ela é exibida no campo de informações, como nas versões anteriores do exemplo.

A classe estilizadora fornece a configuração dos mesmos campos para todos os elementos, uma fonte não padrão em todos os botões e a exibição do CEdit com o atributo "somente leitura" em cinza (temos um, mas, se for adicionado, ele se enquadrará automaticamente na configuração geral).

A referência do cache é armazenada na janela, é criada e excluída no construtor e no destruidor, respectivamente, com a referência da janela passada como parâmetro quando criada para fornecer feedback.


Um algoritmo para dimensionar elementos aninhados para que se ajustem ao tamanho do contêiner foi adicionado à classe CBox. Ele é executado no método AdjustFlexControls e só tem efeito se o valor especial WND_ALIGN_CONTENT for especificado nos sinalizadores de alinhamento do contêiner. Ele não faz parte da enumeração padrão ENUM_WND_ALIGN_FLAGS. O contêiner analisa os "controles" para ver quais são de tamanho fixo e quais não são. Os "controles" com tamanho fixo são aqueles para os quais não é especificado nenhum alinhamento com as laterais do contêiner (em uma dimensão específica). Para todos esses "controles", o contêiner calcula a soma de seus tamanhos, subtrai essa soma do tamanho total do contêiner e divide o restante proporcionalmente entre todos os "controles" restantes. Por exemplo, se houver dois "controles" no contêiner e nenhum deles tiver uma âncora, eles dividirão toda a área do contêiner pela metade.

Esse é um modo muito conveniente, mas não deve ser usado de forma abusiva em um conjunto de contêineres aninhados - devido ao algoritmo de uma passagem do cálculo do tamanho, o alinhamento dos elementos internos à área do contêiner, que, por sua vez, é ajustado ao conteúdo, gera incerteza (por esse motivo, as classes de layout têm um evento especial ON_LAYOUT_REFRESH, que a janela pode enviar a si mesma para repetir o cálculo do tamanho).

A macro ON_EVENT_LAYOUT_CTRL_DLG ativa as notificações de clique do mouse para qualquer botão da classe NotifiableButton (no nosso caso, há apenas um). A macro ON_EVENT_LAYOUT_INDEX envia o mesmo evento para o botão com o índice especificado no cache. Mas essa macro não pôde ser escrita, porque a última linha da macro ON_EVENT_LAYOUT_ARRAY enviará um clique do mouse para qualquer elemento no cache se o identificador lparam corresponder.

Em princípio, você poderia mover todos os itens para o cache e tratar seus eventos de uma nova maneira, mas a maneira antiga também funciona e elas podem ser combinadas.

Exemplo 3. Layouts dinâmicos do DynamicForm

Neste último exemplo, veremos um formulário em que todos os elementos serão criados dinamicamente no cache. Isso nos proporcionará alguns novos recursos importantes.

Como no exemplo anterior, o cache oferecerá suporte à estilização de elementos. As únicas configurações de estilo são as mesmas caixas proeminentes, que nos permitirão ver os contêineres aninhados uns nos outros e selecioná-los conforme desejado com o mouse.

Dentro do método CreateLayout, a seguinte estrutura de interface simples é descrita. O contêiner principal ocupa toda a área do cliente da janela, como de costume. Na parte superior, há um bloco com dois botões: Inject e Export. Todo o espaço abaixo dele é ocupado por um contêiner dividido em colunas esquerda e direita.

O contêiner onde os novos elementos devem ser inseridos é procurado primeiro no cache pelo nome "column1". Esse contêiner é o primeiro parâmetro quando o objeto injectionPanel é criado. O fato de o elemento a ser passado já estar no cache é levado em consideração de forma especial no algoritmo de layout - ele não é adicionado ao cache novamente, mas é colocado na pilha de contêineres como de costume. Dessa forma, é possível adicionar elementos a contêineres "antigos".

Com base na escolha do usuário, um objeto do tipo necessário é criado usando o novo operador no método auxiliar getPtr. Para que os "controles" adicionados funcionem corretamente, são gerados aleatoriamente identificadores exclusivos para eles. A classe AutoPtr especial fornece a exclusão do ponteiro ao sair do bloco de código.

Se você adicionar muitos elementos, eles sairão dos limites do contêiner. Isso acontece porque as classes de contêiner que temos ainda não sabem como reagir corretamente ao estouro. Nesse caso, poderíamos, por exemplo, mostrar uma barra de rolagem e ocultar os elementos que ultrapassam os limites.

Mas isso não importa. O objetivo desse exemplo é que podemos gerar conteúdo dinâmico personalizando o formulário e fornecendo o preenchimento e o tamanho necessários dos contêineres.

Além de adicionar elementos, essa caixa de diálogo também sabe como excluí-los. Qualquer elemento do formulário pode ser selecionado com um clique do mouse. A classe e o nome do elemento são exibidos no registro, e o próprio elemento é destacado com uma moldura vermelha. Se você clicar em um elemento já selecionado, a caixa de diálogo solicitará a confirmação da exclusão e excluirá o elemento se você concordar. Tudo isso é implementado em nossa classe de cache.

Podemos excluir qualquer elemento da interface do usuário disponível no cache, ou seja, não apenas aqueles adicionados pelo botão Inject. Dessa forma, podemos, por exemplo, excluir toda a metade esquerda ou a "caixa de rádio" direita. Mas o mais interessante acontecerá se tentarmos excluir o contêiner superior com dois botões. Como resultado, o botão Exportar perderá sua ligação com a caixa de diálogo e permanecerá no gráfico.

Isso acontece porque ele é o único elemento deliberadamente descrito como uma variável automática em vez de dinâmica (há uma instância do CButton m_button3 na classe do formulário).

Quando a biblioteca padrão tenta remover elementos de interface, ela delega isso à classe de matriz CArrayObj, que, por sua vez, verifica o tipo de ponteiro e remove apenas objetos com POINTER_DYNAMIC. Assim, torna-se óbvio que, para criar uma interface adaptável em que os elementos possam substituir uns aos outros ou ser completamente excluídos, é desejável usar o posicionamento dinâmico, e o cache oferece uma solução pronta para isso.

Por fim, vamos nos voltar para o segundo botão da caixa de diálogo: Exportar. Como você pode imaginar pelo nome, ele se destina a salvar o estado atual da caixa de diálogo como um arquivo de texto na sintaxe de layout MQL considerada. É claro que o formulário permite personalizar sua aparência apenas de forma limitada, para fins de demonstração, mas a própria possibilidade de descarregar a aparência em um código MQL pronto, que pode ser facilmente copiado em um programa e obter a mesma interface, é potencialmente uma tecnologia bastante valiosa. Obviamente, apenas a interface é transferida, e o código de tratamento de eventos ou as configurações gerais do estilizador devem ser conectados de forma independente.

A exportação é fornecida pela classe LayoutExporter, que não será analisada em detalhes; os códigos-fonte estão anexados.



Документация по MQL5: Стандартная библиотека
Документация по MQL5: Стандартная библиотека
  • www.mql5.com
Стандартная библиотека MQL5 написана на языке MQL5 и предназначена для облегчения написания программ (индикаторов, скриптов, экспертов) конечным пользователям. Библиотека обеспечивает удобный доступ к большинству внутренних функций MQL5.
 
Tentei encontrar um sistema, um conceito, uma tecnologia no texto acima, mas não encontrei. Ele não é nem mesmo um "esboço" e se parece mais com um fluxo de consciência. Entretanto, se você mudar constantemente para exemplos de código, não perceberá isso. E é uma pena.
[Excluído]  
Реter Konow:
Tentei encontrar um sistema, um conceito, uma tecnologia no texto acima, mas não encontrei. Ele não é nem mesmo um "esboço" e se parece mais com um fluxo de consciência. Entretanto, se você mudar constantemente para exemplos de código, não perceberá isso. É uma pena.

Na verdade, tudo está claro para quem conhece OOP.

A culpa é de quem não conhece.

 
Koldun Zloy:

Na verdade, está bem claro para quem conhece OOP.

A culpa é de quem não conhece.

Entendo o desejo de defender o autor, mas isso deve ser feito no nível de um profissional, não de um jardim de infância.

Estamos falando sobre a estrutura da apresentação do conceito. De fato, não há nenhuma estrutura ou conceito no texto do artigo. Há pedaços e fragmentos, caoticamente espalhados em diferentes partes. No entanto, aqueles que desenvolveram sistemas complexos podem entender isso. Para o resto de nós, isso serve...

Desde o primeiro artigo, o objetivo foi declarado: verificar a possibilidade de realização do CONCEITO de layout de GUI por meio de MQL, na forma de um wrapper de linguagem ou vis.editor.

Portanto, não há CONCEITO, mas sim um raciocínio espontâneo diluído em códigos.

Exemplo: o autor primeiro fala sobre o cache como uma solução fundamental para gerar/destruir controladores, e imediatamente passa para o estilizador, ignorando todas as outras questões. Além disso, ele coloca as alterações no modelo de evento padrão após o tópico de estilos. Que tipo de prioridades estranhas são essas?
[Excluído]  

O objetivo dessa linguagem de marcação é que ela não requer um intérprete separado. Ela é incorporada diretamente ao código do programa.

Mas sem conhecimento de OOP, você não verá muita coisa nos artigos.

E já que você não planeja estudar OOP, por que está aqui?