Discusión sobre el artículo "El lenguaje MQL como medio de marcado de la interfaz gráfica de programas MQL. Parte 2"

 

Artículo publicado El lenguaje MQL como medio de marcado de la interfaz gráfica de programas MQL. Parte 2:

En este artículo, presentamos un nuevo concepto para la descripción de la interfaz de ventana de los programas MQL con la ayuda de las construcciones del lenguaje MQL. La creación de GUI basadas en el marcado MQL ofrece una funcionalidad adicional para almacenar la caché y generar de manera dinámica elementos, y también para gestionar los estilos y los nuevos esquemas de procesamiento de eventos. Aquí, ofrecemos la versión mejorada de la biblioteca estándar de los elementos de control.

Podemos eliminar cualquier elemento de la interfaz ubicado en la caché, es decir, no solo aquellos que han sido añadidos con el botón Inject. De esta forma, podemos, por ejemplo, eliminar toda la mitad izquierda o la "caja de radio" derecha. No obstante, lo más interesante sucederá cuando intentemos eliminar el contenedor superior con dos botones. Como resultado de ello, el botón Export perderá su vinculación con la ventana de diálogo y permanecerá en el gráfico.

Forma editada: añadiendo y eliminando elementos

Forma editada: añadiendo y eliminando elementos

Esto sucede así porque se trata del único elemento escrito a propósito como variable automática, no como dinámica (en la clase de la forma existe la instancia CButton m_button3).

Cuando la biblioteca estándar intenta eliminar los elementos de la interfaz, delega esta tarea en la clase de matrices CArrayObj, y esta, a su vez, comprueba el tipo de puntero y elimina solo los objetos con POINTER_DYNAMIC. Así, resulta obvio que, para construir una interfaz adaptativa donde los elementos puedan sustituir unos a otros, o bien sean totalmente eliminados, resultará deseable utilizar una ubicación dinámica, y la caché ofrece para ello soluciones ya preparadas.

Autor: Stanislav Korotky

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

Entonces, ¿todo esto sólo funcionará con una versión mejorada de la biblioteca estándar?

 
No voy a criticar el artículo durante mucho tiempo, porque ya está claro que el autor no piensa en el lector. Habla consigo mismo y le entenderán los que conozcan perfectamente la biblioteca estándar: sus clases, métodos y variables. El autor "galopa" por los códigos que conoce y modifica algo.....

La falta de presentación de los principios generales de la biblioteca, del lenguaje o del editor nivela el valor del artículo. Todo el mundo puede "cavar" en las "entrañas" con palabras ingeniosas, pero para explicar la tecnología en un lenguaje claro - no, porque realmente hay que entender su esencia. Me temo que el autor ha sido víctima de la ilusión de que va a hacer un lenguaje de marcado de una biblioteca (que ha aprendido) y luego inmediatamente hacer un estudio. Al mismo tiempo, considera ingenuamente como prueba el engomado de ventanas y la adición de un elemento a un formulario.

Como no voy a esperar conceptos del autor, no me interesa ver esta acción incomprensible. Es una lástima. Es una pena que el autor tenga dificultades para realizar sus ambiciones y demostrar la "ridiculez" de sus resultados.

¡Suerte!
 
Реter Konow:
No voy a criticar el artículo durante mucho tiempo, porque ya está claro que el autor no piensa en el lector. Habla consigo mismo y le entenderán los que conozcan perfectamente la biblioteca estándar: sus clases, métodos y variables. El autor "galopa" por los códigos que conoce y modifica algo....

La falta de presentación de los principios generales de la biblioteca, del lenguaje o del editor nivela el valor del artículo. Todo el mundo puede "cavar" en las "entrañas" con palabras ingeniosas, pero para explicar la tecnología en un lenguaje claro - no, porque realmente hay que entender su esencia. Me temo que el autor ha sido víctima de la ilusión de que va a hacer un lenguaje de marcado de una biblioteca (que ha aprendido) y luego inmediatamente hacer un estudio. Al mismo tiempo, considera ingenuamente que engomar una ventana y añadir un elemento a un formulario es una confirmación.

Como no voy a esperar conceptos del autor, no me interesa ver esta acción incomprensible. Lástima. Es una pena que el autor tenga dificultades para realizar sus ambiciones y demostrar la "ridiculez" de sus resultados.

¡Suerte!

Y quien conozca a la perfección esta biblioteca apenas necesitará añadidos.

 
Dmitry Fedoseev:

Y es poco probable que alguien que esté perfectamente familiarizado con esta biblioteca necesite alguna ampliación.

Si lees atentamente la conclusión del artículo, podrás entender las (controvertidas) conclusiones del autor:

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

1. el autor afirma haber comprobado "la viabilidad del concepto de describir el diseño de la interfaz gráfica de los programas MQL en el propio lenguaje MQL" (c).

  • Debido a las particularidades de la presentación del material, no puedo decir nada a favor/en contra de esta conclusión. No es evidente.

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

2. "El uso de la generación dinámica de elementos con almacenamiento centralizado en la caché permite simplificar la creación y gestión de la jerarquía de componentes. La mayoría de las tareas relacionadas con el diseño de interfaces, como los cambios uniformes de estilo, la gestión de eventos, la edición sobre la marcha del diseño y su almacenamiento en un formato adecuado para su uso posterior, pueden implementarse sobre la base de la caché." (c)

  • No se sabe sobre qué base teórica se llegó a esta conclusión, ya que no hay ninguna descripción de la tecnología y el lector no puede ni estar de acuerdo ni negarlo. El lector debería introducirse en la tecnología y entonces, estará de acuerdo con la prueba de realizabilidad.

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

3. "Si se juntan estas características, resulta que casi todo está disponible para un simple editor visual de formularios. Podría soportar sólo las propiedades más importantes comunes a muchos "controles", pero seguiría permitiendo la formación de espacios en blanco en la interfaz."(c)

  • De nuevo, -sin una descripción generalizada de los matices tecnológicos, el lector que no conozca a la perfección el sistema de producción de editores visuales a partir de grafotecas, no puede ni estar de acuerdo ni discutir con el autor. No es obvio.

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

4. "Sin embargo, vemos que incluso la fase inicial de evaluación del nuevo concepto requirió mucho esfuerzo. Implementar un editor completo en la práctica es, por tanto, todo un reto. Y esa es otra historia". (c)

  • En mi opinión, esta es la conclusión MÁS objetiva. Estoy de acuerdo con esta conclusión. No puedes "apresurarte" a hacerlo (yo mismo llevo varios años intentándolo).

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

Mi conclusión: en la conclusión del artículo (concretamente en la última conclusión), el autor se acerca más a la realidad. Pero, el artículo está dirigido a lectores que deben llegar a las mismas conclusiones a medida que se desarrolla el tema, y para ello, es necesario revelar gradualmente la tecnología. El principal inconveniente de los dos artículos es que no revelan la tecnología. Su contenido es una discusión sobre la aplicación de las soluciones no evidentes del autor sin ningún prefacio al respecto. Espero que el autor tenga esto en cuenta.

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

Si lees atentamente la conclusión del artículo, podrás entender las (controvertidas) conclusiones del autor:

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

1. el autor afirma haber comprobado "la viabilidad del concepto de describir el diseño de la interfaz gráfica de los programas MQL en el propio lenguaje MQL" (c).

  • Debido a las particularidades de la presentación del material, no puedo decir nada a favor/en contra de esta conclusión. No es evidente.

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

2. "Utilizar la generación dinámica de elementos con almacenamiento centralizado en una caché facilita la creación y gestión de una jerarquía de componentes. La mayoría de las tareas relacionadas con el diseño de interfaces pueden implementarse a partir de la caché, como los cambios uniformes de estilo, la gestión de eventos, la edición del diseño sobre la marcha y su almacenamiento en un formato adecuado para su uso posterior." (c)

  • No se sabe sobre qué base teórica se ha llegado a esta conclusión, ya que no hay ninguna descripción de la tecnología y el lector no puede ni estar de acuerdo ni negarlo. Habría que introducir al lector en la tecnología y entonces, estará de acuerdo con la prueba de realizabilidad.

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

3. "Si se juntan estas características, resulta que casi todo está disponible para un simple editor visual de formularios. Podría soportar sólo las propiedades más importantes comunes a muchos "controles", pero aún así permitirle formar espacios en blanco de la interfaz."(c)

  • De nuevo, -sin una descripción generalizada de los matices tecnológicos, un lector que no domine el sistema de producción de editores visuales a partir de bibliotecas de grafos no puede ni estar de acuerdo ni discutir con el autor. No es obvio.

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

4. "Sin embargo, vemos que incluso la fase inicial de evaluación del nuevo concepto requirió mucho esfuerzo. Implementar en la práctica un editor completo es, por tanto, todo un reto. Y esa es otra historia". (c)

  • En mi opinión, esta es la conclusión MÁS objetiva. Estoy de acuerdo con esta conclusión . No se puede hacer "precipitadamente" (yo mismo lo intenté durante varios años).

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

Mi conclusión: en la conclusión del artículo (concretamente en la última conclusión), el autor se acerca más a la realidad. Pero, el artículo está dirigido a lectores que deben llegar a las mismas conclusiones a medida que se desarrolla el tema, y para ello, es necesario revelar gradualmente la tecnología. El principal inconveniente de los dos artículos es que no revelan la tecnología. Su contenido es una discusión sobre la aplicación de las soluciones no evidentes del autor sin ningún prefacio al respecto. Espero que el autor tenga esto en cuenta.

Yo me abstendré, porque es prohibitivo.

 

Hice un análisis exhaustivo del contenido del artículo y me di cuenta de que hay "partículas" de la tecnología que buscaba, pero están dispersas arbitrariamente por todo el material. Es decir, el autor no separó la teoría de la aplicación y lo mezcló todo, separándolo de paso con abundantes ejemplos de código. Decidí recopilar los fundamentos de su concepto en un solo lugar para hacerme una idea completa del mismo.

Copias de los fragmentos del artículo que explican la tecnología (se conserva la secuencia, se omiten los ejemplos de código):

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

1. la estructura general de la biblioteca de elementos estándar, teniendo en cuenta las versiones adaptadas con soporte para "rubberstamping" y contenedores de terceros, se da en el diagrama de clases. (añadido mío: el diagrama está dado).

2. generación de elementos y almacenamiento en caché

Hasta ahora, los elementos se han construido como instancias automáticas dentro de un objeto ventana. Son esencialmente "espacios en blanco" que luego se inicializan mediante métodos como Create. El sistema de diseño de elementos GUI puede crear estos elementos por sí mismo, en lugar de obtenerlos de una ventana. Para ello, basta con tener algún tipo de almacenamiento. Llamémoslo LayoutCache. Básicamente, es un array de punteros de la clase base (común para todos los elementos), donde pueden ser colocados usando el método save. La interfaz también implementa (si es posible a este nivel abstracto) o declara (para overriding posterior) métodos para buscar elementos por número, nombre, referencia, o hecho de la relación "padre" (retroalimentación de elementos anidados al contenedor).

Añadamos una caché como miembro estático a la clase LayoutBase. Cada ventana tendrá que crear una instancia de caché para sí misma y establecerla como caché de trabajo utilizando setCache al principio de un método como CreateLayout. Dado que los programas MQL son monohilo, tenemos la garantía de que las ventanas (si se necesitan varias) no se formarán en paralelo y competirán por el puntero de la caché. Borraremos el puntero automáticamente en el destructor de LayoutBase cuando se acabe la pila - esto significa que hemos dejado el último contenedor exterior en la descripción del layout y no hay necesidad de guardar nada más. Poner a cero la referencia no significa que estemos borrando la caché. Sólo asegura que el potencial próximo layout no añadirá por error "controladores" de otra ventana. Para llenar la caché, vamos a añadir un nuevo tipo de método init a LayoutBase - esta vez sin un puntero o referencia a un elemento GUI "de terceros" en los parámetros. Gracias a la plantilla tenemos la posibilidad de escribir una nueva T y generar objetos durante el proceso de maquetación (por defecto, 1 objeto cada vez, pero opcionalmente podemos tener varios).

Una implementación concreta de la caché está escrita para los elementos de la librería estándar - StdLayoutCache (aquí se da con abreviaturas, el código completo está en el apéndice).

Observe que el método get busca un "control" bien por número de secuencia (si el parámetro de entrada es positivo) o por identificador (se pasa con signo menos). Aquí por identificador entendemos un número único asignado por la librería de componentes estándar para el envío de eventos. En los eventos se pasa en el parámetro lparam.

3. estilizador

Dado que el caché es un objeto que procesa elementos de forma centralizada, es conveniente utilizarlo para realizar muchas otras tareas además del estilizador. En particular, las reglas de un mismo estilo (color, fuente, sangría) pueden aplicarse a los elementos de forma unificada. Basta con configurar este estilo en un solo lugar, en lugar de escribir las mismas propiedades para cada "control" por separado. Además, la caché puede encargarse de gestionar los mensajes para los elementos almacenados en caché. Potencialmente podemos construir dinámicamente, almacenar en caché e interactuar con absolutamente todos los elementos. Entonces no necesitamos declarar ningún elemento "explícito" en la ventana. Un poco más adelante veremos cómo los elementos creados dinámicamente se comparan favorablemente con los automáticos.

Para soportar estilos centralizados, la clase StdLayoutCache tiene un método stall: El método apply será llamado para cada "control" dos veces: en la etapa de inicialización (STYLE_PHASE_BEFORE_INIT) y en la etapa de registro en el contenedor (STYLE_PHASE_AFTER_INIT). Así, los métodos LayoutBase::init añaden una llamada a la primera fase: y el destructor añade cadenas similares, pero con STYLE_PHASE_AFTER_INIT para la segunda fase.

Se necesitan dos fases porque los propósitos de estilo son diferentes. Algunos elementos a veces necesitan tener propiedades individuales que tienen una prioridad más alta que las generales establecidas en el estilizador. En la fase de inicialización, el "control" está todavía vacío - sin los ajustes realizados en el diseño. En la fase de registro, todas las propiedades ya están configuradas en él y, además, puede cambiar el estilo basándose en ellas. El ejemplo más obvio es el siguiente. Es deseable mostrar todos los campos de entrada con la bandera "sólo lectura" en gris. Pero la propiedad "sólo lectura" se asigna al "control" durante el proceso de diseño, después de la inicialización, por lo que la primera etapa no es adecuada y se requiere la segunda etapa. Por otra parte, normalmente no todos los campos de entrada tendrán esta bandera, y en todos los demás casos es necesario establecer el color por defecto antes de que el lenguaje de maquetación realice la personalización selectiva.

Por cierto, se puede utilizar una tecnología similar para la localización centralizada de la interfaz de los programas MQL en diferentes idiomas nacionales.

4. procesamiento de eventos

La segunda función, asignada lógicamente a la caché, es el procesamiento de eventos. Para ellos en la clase LayoutCache se añade un método stub (C es un parámetro de la plantilla de la clase): De nuevo, puede implementarse en una clase derivada, pero no necesariamente. Los códigos de evento son definidos por la librería específica.

Para que este método funcione, necesitamos definiciones de macros de captura de eventos similares a las de la librería estándar y escritas en el mapa, por ejemplo, así: Las nuevas macros redirigirán los eventos al objeto caché.

5. Ejemplo 2. Diálogo con Controles

El proyecto de demostración contiene la clase CControlsDialog con los tipos básicos de "controles" de la biblioteca estándar. Por analogía con el primer ejemplo, vamos a eliminar todos los métodos para su creación y sustituirlos por un único CreateLayout. Por cierto, en el antiguo proyecto había 17 métodos de este tipo, y eran llamados unos desde otros con la ayuda de complejos operadores condicionales. En la clase caché, se declara el manejador de eventos onEvent, que conectaremos a través del mapa de eventos. Aquí el manejador refleja el mensaje a la ventana padre, donde se muestra en el campo de información como en las versiones anteriores del ejemplo.

La clase styler permite establecer los mismos campos para todos los elementos, una fuente no estándar en todos los botones, y mostrar CEdit con el atributo "sólo lectura" en gris (tenemos uno, pero si lo añadimos, automáticamente entrará en la configuración general).

Una referencia a la caché se almacena en la ventana, se crea y se elimina en el constructor y destructor respectivamente, con la referencia de la ventana pasada como parámetro cuando se crea para proporcionar retroalimentación.


Se ha añadido a la clase CBox un algoritmo para escalar elementos anidados para ajustarlos al tamaño del contenedor. Se ejecuta en el método AdjustFlexControls y sólo tiene efecto si se especifica el valor especial WND_ALIGN_CONTENT en los indicadores de alineación del contenedor. No forma parte de la enumeración estándar ENUM_WND_ALIGN_FLAGS. El contenedor analiza los "controles" para ver cuáles son de tamaño fijo y cuáles no. Los "controles" con tamaño fijo son aquellos para los que no se especifica ninguna alineación con los lados del contenedor (en una dimensión determinada). Para todos estos "controles", el contenedor calcula la suma de sus tamaños, la resta del tamaño total del contenedor y divide el resto proporcionalmente entre todos los "controles" restantes. Por ejemplo, si hay dos "controles" en el contenedor, y ninguno de ellos tiene un ancla, compartirán toda el área del contenedor por la mitad.

Este es un modo muy conveniente, pero no se debe abusar de él en un conjunto de contenedores anidados - debido al algoritmo de una sola pasada del cálculo del tamaño, la alineación de los elementos internos al área del contenedor, que a su vez se ajusta al contenido genera incertidumbre (por esta razón, las clases de diseño tienen un evento especial ON_LAYOUT_REFRESH, que la ventana puede enviarse a sí misma para repetir el cálculo del tamaño).

La macro ON_EVENT_LAYOUT_CTRL_DLG habilita las notificaciones de clic de ratón para cualquier botón de la clase NotifiableButton (en nuestro caso, sólo hay uno). La macro ON_EVENT_LAYOUT_INDEX envía el mismo evento al botón con el índice especificado en la caché. Pero esta macro no podría escribirse, porque la última línea de la macro ON_EVENT_LAYOUT_ARRAY enviará un clic de ratón a cualquier elemento de la caché si su identificador lparam coincide.

En principio, podría mover todos los elementos a la caché y manejar sus eventos de una forma nueva, pero la forma antigua también funciona y pueden combinarse.

Ejemplo 3. Diseños dinámicos de DynamicForm

En este último ejemplo, veremos un formulario en el que todos los elementos se crearán dinámicamente en la caché. Esto nos dará un par de nuevas características importantes.

Como en el ejemplo anterior, la caché soportará el estilo de los elementos. Los únicos ajustes de estilo son las mismas cajas prominentes, que nos permitirán ver contenedores anidados unos dentro de otros y seleccionarlos a nuestro gusto con el ratón.

Dentro del método CreateLayout, se describe la siguiente estructura de interfaz simple. El contenedor principal ocupa toda el área cliente de la ventana, como es habitual. En la parte superior hay un bloque con dos botones: Inyectar y Exportar. Todo el espacio inferior lo ocupa un contenedor dividido en columnas izquierda y derecha.

El contenedor donde deben insertarse los nuevos elementos se busca primero en la caché con el nombre "columna1". Este contenedor viene como primer parámetro cuando se crea el objeto injectionPanel. El hecho de que el elemento que se va a pasar ya esté en la caché se tiene en cuenta de forma especial en el algoritmo de disposición: no se vuelve a añadir a la caché, sino que se coloca en la pila de contenedores como de costumbre. De esta forma es posible añadir elementos a contenedores "antiguos".

Basándose en la elección del usuario, se crea un objeto del tipo requerido utilizando el operador new en el método auxiliar getPtr. Para que los "controles" añadidos funcionen correctamente, se generan aleatoriamente identificadores únicos para ellos. La clase especial AutoPtr proporciona el borrado del puntero al salir del bloque de código.

Si añades demasiados elementos, se saldrán de los límites del contenedor. Esto ocurre porque las clases contenedoras que tenemos aún no saben cómo reaccionar correctamente al desbordamiento. En este caso podríamos, por ejemplo, mostrar una barra de desplazamiento y ocultar los elementos que sobresalen de los límites.

Pero no importa. Lo importante de este ejemplo es que podemos generar contenido dinámico personalizando el formulario y proporcionando el relleno y el tamaño necesarios de los contenedores.

Además de añadir elementos, este cuadro de diálogo también sabe cómo eliminarlos. Cualquier elemento del formulario puede seleccionarse con un clic del ratón. La clase y el nombre del elemento se muestran en el registro, y el propio elemento se resalta con un marco rojo. Si hace clic en un elemento ya seleccionado, el cuadro de diálogo le pedirá que confirme la eliminación y borrará el elemento si está de acuerdo. Todo esto se implementa en nuestra clase caché.

Podemos borrar cualquier elemento de interfaz de usuario disponible en la caché, es decir, no sólo los añadidos por el botón Inyectar. De esta forma podemos, por ejemplo, borrar toda la mitad izquierda o el "radio box" derecho. Pero lo más interesante ocurrirá si intentamos borrar el contenedor superior con dos botones. Como resultado, el botón Exportar perderá su vinculación con el cuadro de diálogo y permanecerá en el gráfico.

Esto sucede porque es el único elemento descrito deliberadamente como una variable automática en lugar de dinámica (hay una instancia de CButton m_button3 en la clase del formulario).

Cuando la librería estándar intenta eliminar elementos de la interfaz, delega esto a la clase de array CArrayObj, y ésta a su vez comprueba el tipo de puntero y elimina sólo los objetos con POINTER_DYNAMIC. Así, resulta obvio que para construir una interfaz adaptable en la que los elementos puedan reemplazarse entre sí o eliminarse por completo, es deseable utilizar la colocación dinámica, y la caché ofrece una solución lista para ello.

Por último, pasemos al segundo botón del cuadro de diálogo: Exportar. Como se puede adivinar por su nombre, está destinado a guardar el estado actual del diálogo como un archivo de texto en la sintaxis MQL-layout considerada. Por supuesto, la forma le permite personalizar su apariencia sólo hasta cierto punto, para fines de demostración, pero la posibilidad de descargar la apariencia en un código MQL ya hecho, que luego puede ser fácilmente copiado en un programa y obtener la misma interfaz, es potencialmente una tecnología muy valiosa. Por supuesto, sólo se transfiere la interfaz, y el código de manejo de eventos o la configuración general del estilizador deben conectarse de forma independiente.

La exportación la proporciona la clase LayoutExporter, no la veremos en detalle, se adjuntan los códigos fuente.



Документация по MQL5: Стандартная библиотека
Документация по MQL5: Стандартная библиотека
  • www.mql5.com
Стандартная библиотека MQL5 написана на языке MQL5 и предназначена для облегчения написания программ (индикаторов, скриптов, экспертов) конечным пользователям. Библиотека обеспечивает удобный доступ к большинству внутренних функций MQL5.
 
He intentado encontrar un sistema, un concepto, una tecnología en el texto anterior, pero no lo he conseguido. Ni siquiera es un "esbozo", sino más bien una corriente de conciencia. Sin embargo, si cambias constantemente a ejemplos de código, no te darás cuenta. Y es una pena.
[Eliminado]  
Реter Konow:
He intentado encontrar un sistema, un concepto, una tecnología en el texto anterior, pero no lo he conseguido. Ni siquiera es un "esbozo", sino más bien una corriente de conciencia. Sin embargo, si cambias constantemente a ejemplos de código, no te darás cuenta. Es una lástima.

En realidad, todo está claro para alguien que conozca la programación orientada a objetos.

La culpa es de los que no la conocen.

 
Koldun Zloy:

En realidad es bastante claro allí para alguien que sabe OOP.

La culpa es de los que no la conocen.

Entiendo el deseo de defender al autor, pero debería hacerse a nivel de un profesional, no de un parvulario.

Estamos hablando de la estructura de la presentación del concepto. De hecho, no hay estructura ni concepto en el texto del artículo. Hay trozos, dispersos caóticamente en diferentes partes. Sin embargo, quienes hayan desarrollado sistemas complejos podrán entenderlo. Para el resto de nosotros servirá...

Desde el primer artículo se planteó el objetivo: comprobar la realizabilidad del CONCEPTO de maquetación de GUI mediante MQL, en forma de wrapper de lenguaje o vis.editor.

Así pues, no hay CONCEPTO, sino razonamientos espontáneos diluidos con códigos.

Ejemplo: el autor habla primero de la caché como solución fundamental para generar/destruir controladores, e inmediatamente pasa al estilizador, obviando todas las demás cuestiones. Además, pone los cambios en el modelo de eventos estándar después del tema de los estilos. ¿Qué clase de extrañas prioridades son éstas?
[Eliminado]  

La gracia de este lenguaje de marcado es que no requiere un intérprete aparte. Está integrado directamente en el código del programa.

Pero sin conocimientos de POO, no se puede ver mucho en los artículos.

Y como no piensas estudiar POO, ¿por qué estás aquí?