Tabla de contenido:

Administrador de ventanas integrado: 10 pasos
Administrador de ventanas integrado: 10 pasos

Video: Administrador de ventanas integrado: 10 pasos

Video: Administrador de ventanas integrado: 10 pasos
Video: Como ser ADMINISTRADOR en WINDOWS 10 AL 100%, 🔴 DOS MÉTODOS infalibles - 2021 📌 2024, Mes de julio
Anonim
Administrador de ventanas integrado
Administrador de ventanas integrado
Administrador de ventanas integrado
Administrador de ventanas integrado
Administrador de ventanas integrado
Administrador de ventanas integrado
Administrador de ventanas integrado
Administrador de ventanas integrado

Este proyecto muestra cómo implementar un administrador de ventanas con ventanas superpuestas móviles en un microcontrolador integrado con un panel LCD y una pantalla táctil. Hay paquetes de software disponibles comercialmente para hacer esto, pero cuestan dinero y son de código cerrado. Este, llamado MiniWin, es gratuito y de código abierto. Está escrito en C99 totalmente compatible y se puede utilizar en una aplicación C o C ++. Los objetivos de MiniWin son ser fáciles de usar, fáciles de modificar, expandibles, portátiles a una amplia gama de hardware y no demasiado hambrientos de recursos.

Además de proporcionar el código para administrar sus ventanas, MiniWin tiene una colección de controles de interfaz de usuario: botones, controles deslizantes, barras de progreso, árboles, etc. Puede tener múltiples ventanas de diferentes tipos o múltiples instancias del mismo tipo. Las ventanas se pueden mover, cambiar de tamaño, maximizar, minimizar, cerrar, todas las cosas habituales que se hacen con las ventanas en administradores de ventanas más grandes. Las fuentes TrueType con kerning y anti-aliasing (hace que el texto parezca suave) también son compatibles para una representación atractiva del texto.

En cada ventana tienes un área de cliente (tu espacio dentro del borde y debajo de la barra superior). En esto, puede agregar controles para hacer un diálogo o puede usar la biblioteca de gráficos incorporada para dibujar lo que quiera. Todas las funciones de la biblioteca de gráficos son compatibles con las ventanas. No tiene que preocuparse por dónde está su ventana, qué se superpone o si está minimizada.

Además de crear sus propias ventanas, también se incluyen algunos cuadros de diálogo estándar que son muy fáciles de instanciar, por ejemplo, cuadros de diálogo de confirmación (solo un botón Aceptar o Sí / No), configuradores de fecha / hora, selectores de archivos, selectores de color, etc.

MiniWin utiliza un sistema de cola de mensajes de diseño de administrador de Windows estándar. Las ventanas pueden interactuar entre sí y con el administrador de ventanas a través de mensajes. No llama a funciones para hacer cosas directamente, agrega un mensaje a la cola y el administrador de ventanas lo promulgará por usted.

MiniWin se ha adaptado a placas de desarrollo estándar con pantallas táctiles de los proveedores de microcontroladores ST, NXP y Renesas. Hay controladores de hardware y proyectos de ejemplo para todos estos dispositivos. Además, MiniWin se puede construir para Windows o Linux para que pueda simular su código de interfaz de usuario antes de obtener su hardware integrado.

MiniWin tiene un generador de código. Puede especificar sus ventanas y controles en un archivo JSON fácil de crear y legible por humanos y el generador de código analiza el archivo y crea el código por usted (hay muchos ejemplos a seguir). Crea aplicaciones de simulador completas de Windows o Linux que pueden simplemente construirse y está su pantalla LCD simulada con las ventanas MiniWin funcionando. Puede tomar exactamente el mismo código generado y colocarlo en un proyecto incrustado y tener el mismo código mostrando las mismas ventanas y controles momentos más tarde en su hardware incrustado.

MiniWin no requiere soporte operativo en el dispositivo integrado. Todo se ejecuta en un solo hilo. MiniWin se puede integrar con un RTOS que se ejecuta en un procesador integrado y hay ejemplos que integran MiniWin con FreeRTOS.

Este instructivo muestra cómo poner MiniWin en funcionamiento en un procesador STM32 M4 usando la placa Discovery barata STM32F429 que viene con una pantalla táctil QVGA ya conectada. Estos están fácilmente disponibles en su proveedor de componentes electrónicos.

MiniWin se ejecuta en microcontroladores de rango medio y superiores.

Suministros

Placa de desarrollo STM32F429I-DISC1 y un cable micro USB

Descarga STM32CubeIDE que es gratuita.

Paso 1: obtener el código

Obtener el código
Obtener el código

En primer lugar, necesita tener instalado STM32CubeIDE. Lo obtienes del sitio web de ST. Tienes que registrarte y lleva un tiempo descargarlo e instalarlo. Todo es gratis.

Mientras se instala, descargue el código fuente MiniWin y descomprímalo. Es grande, pero solo usarás una pequeña parte. Haga clic en el botón verde "Clonar o descargar" aquí …

github.com/miniwinwm/miniwinwm

luego elija Descargar zip. Descomprime el contenido.

Paso 2: construcción de un proyecto de ejemplo

Construyendo un proyecto de ejemplo
Construyendo un proyecto de ejemplo
Construyendo un proyecto de ejemplo
Construyendo un proyecto de ejemplo

Primero construyamos uno de los proyectos de ejemplo. Uno bueno se llama MiniWinSimple. Inicie STM32CubeIDE y luego haga esto:

  1. Elija Archivo | Importar…
  2. Abra General y elija Proyecto existente en el espacio de trabajo. Próximo.
  3. Haga clic en Examinar y navegue hasta donde descomprimió MiniWin. Luego vaya a la carpeta STM32CubeIDE / MiniWinSimple / STM32F429. Haga clic en Seleccionar carpeta.
  4. En Proyecto: marque MiniWinSimple_STM32F429 y luego haga clic en Finalizar.
  5. El proyecto MiniWinSimple_STM32F429 aparecerá en su Explorador de proyectos. Selecciónelo y luego constrúyalo con Project | Build Project.
  6. Ahora conecte su cable USB a la placa y a su computadora y ejecútelo usando Ejecutar | Depurar y cuando se descargue elija Ejecutar | Reanudar. Obtendrá una pantalla de calibración de pantalla la primera vez, así que toque el centro de las 3 cruces en la pantalla LCD. Ahora puede interactuar con la ventana de la pantalla.

Para mover una ventana, arrástrela por su barra de título. Para cambiar el tamaño de una ventana, use el ícono de triángulo blanco a la izquierda de la barra de título. Las ventanas de MiniWin no se pueden cambiar de tamaño arrastrando los bordes, ya que las pantallas en las que se usa MiniWin son demasiado pequeñas. Para minimizar, maximizar o cerrar una ventana, use los íconos en el extremo derecho de la barra de título (cerrar puede estar deshabilitado). Cuando una ventana está minimizada, no puede mover los iconos minimizados. Se acumulan desde abajo de izquierda a derecha.

Paso 3: ejecutar el generador de código

Ejecutando el generador de código
Ejecutando el generador de código

Ahora cambiaremos el proyecto de ejemplo generando algunas ventanas propias y soltando el nuevo código. Para hacer esto, ejecutaremos el generador de código.

  1. Abra un símbolo del sistema y vaya a la carpeta donde descomprimió MiniWin y luego a la carpeta Tools / CodeGen.
  2. El ejecutable para Windows CodeGen.exe ya está disponible. Para Linux, debe compilarlo escribiendo make. (También puede compilarlo desde el código fuente para Windows si le preocupa ejecutar un ejecutable descargado pero necesita el compilador y el entorno de desarrollo instalados. Consulte la documentación de MiniWin en la carpeta de documentos para obtener más detalles).
  3. En esta carpeta hay algunos archivos JSON de ejemplo. Usaremos example_empty.json. Primero debe editarlo para configurarlo para Windows o Linux. Ábrelo en un editor y en la parte superior, donde encontrarás "TargetType", cambia el valor de "Linux" o "Windows" por el que estás ejecutando el generador de código.
  4. Ahora escriba codegen example_empty.json en el símbolo del sistema.
  5. Vaya a su proyecto en STM32CubeIDE y abra la carpeta MiniWinSimple_Common. Elimina todos los archivos allí.
  6. Dejamos el "TargetName" en el archivo JSON como predeterminado en "MiniWinGen", por lo que ese es el nombre de nuestra carpeta de código generado. Vaya a la carpeta donde descomprimió MiniWin y luego la carpeta MiniWinGen_Common. Ahora seleccione todos estos archivos y arrástrelos y suéltelos en STM32CubeIDE en la carpeta MiniWinSimple_Common de su proyecto.
  7. Ahora reconstruya y vuelva a ejecutar el proyecto en STM32CubeIDE y aparecerá su nueva ventana de diseño. El botón de la ventana desapareció porque example_empty.json no define ninguno.

Paso 4: agregar una ventana

Agregar una ventana
Agregar una ventana

Ahora agregaremos una segunda ventana al archivo de configuración JSON y volveremos a generar el código.

1. Abra example_empty.json en un editor de texto.

2. En la sección "Ventanas" hay una serie de definiciones de ventanas que actualmente solo tiene una ventana. Copia todo esto …

{

"Nombre": "W1", "Título": "Ventana 1", "X": 10, "Y": 15, "Ancho": 200, "Alto": 180, "Borde": verdadero, "Barra de título": verdadero, "Visible": verdadero, "Minimizado": falso}

y péguelo de nuevo con una coma que separe las 2 definiciones.

3. Cambie "W1" a "W2" y "Ventana 1" a "Ventana 2". Cambie "X", "Y", "Ancho" y "Alto" a algunos valores diferentes, teniendo en cuenta que la resolución de la pantalla es de 240 de ancho por 320 de alto.

4. Guarde el archivo y vuelva a ejecutar el generador de código.

5. Copie los archivos como en el paso anterior, reconstruya y vuelva a ejecutar. Ahora tendrá 2 ventanas en su pantalla.

Paso 5: agregar un control

Agregar un control
Agregar un control

Ahora agregaremos algunos controles a su nueva ventana. Edite el mismo archivo que en el paso anterior.

1. En la especificación de la ventana W1, agregue una coma después de la última configuración ("Minimizado": falso) y luego agregue este texto.

"MenuBar": verdadero, "MenuBarEnabled": true, "MenuItems": ["Fred", "Bert", "Pete", "Alf", "Ian"], "Botones": [{"Nombre": "B1", "Etiqueta": "Botón1", "X": 10, "Y": 10, "Habilitado": verdadero, "Visible": verdadero}]

Esta sección agrega una barra de menú con 5 elementos y la habilita (las barras de menú se pueden deshabilitar globalmente, pruébelo). También agrega un botón que está habilitado y visible (se pueden crear invisibles y luego hacer visibles en el código más adelante).

2. Regenere el código, cópielo, reconstruya y vuelva a ejecutar todo como antes.

Paso 6: hacer que los controles hagan algo

Hacer que los controles hagan algo
Hacer que los controles hagan algo

Ahora tenemos la interfaz de usuario básica que necesitamos para que funcione. Para este ejemplo, aparecerá un cuadro de diálogo de selección de color cuando se presione el botón en la Ventana 1.

Vaya a su proyecto en STM32CubeIDE y abra la carpeta MiniWinSimple_Common y luego abra el archivo W1.c (el nombre de este archivo corresponde al campo "Nombre" de la ventana en el archivo JSON cuando se generó el código).

En este archivo encontrará la función window_W1_message_function (). Se parece a esto:

void window_W1_message_function (const mw_message_t * message) {MW_ASSERT (message! = (void *) 0, "Parámetro de puntero nulo"); / * La siguiente línea detiene las advertencias del compilador ya que la variable no se usa actualmente * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Agrega cualquier código de inicialización de ventana aquí * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Agregar código de manejo de menú de ventana aquí * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Agregue su código de controlador para este control aquí * /} break; predeterminado: / * Mantener feliz a MISRA * / break; }}

Esto es llamado por el administrador de ventanas para esta ventana cada vez que el administrador de ventanas necesita informar a la ventana que algo ha sucedido. En este caso, nos interesa saber que se ha pulsado el único botón de la ventana. En la declaración de cambio para los tipos de mensajes, verá un caso para MW_BUTTON_PRESSED_MESSAGE. Este código se ejecuta cuando se presiona el botón. Solo hay un botón en esta ventana, pero podría haber más, por lo que se comprueba cuál es el botón. En este caso, solo podría ser el botón B1 (el nombre corresponde al nombre del botón en el archivo JSON nuevamente).

Entonces, después de esta etiqueta de caso, agregue el código para que aparezca un cuadro de diálogo de selección de color, que es este:

mw_create_window_dialog_colour_chooser (10, 10, "Color", MW_HAL_LCD_RED, falso, mensaje-> destinatario_handle);

Los parámetros son los siguientes:

  • 10, 10 es la ubicación en la pantalla del diálogo
  • "Color" es el título del diálogo.
  • MW_HAL_LCD_RED es el color predeterminado con el que comenzará el cuadro de diálogo
  • falso significa que no muestra un tamaño grande (intente configurarlo en verdadero y vea la diferencia)
  • mensaje-> identificador del destinatario es el propietario de este diálogo, en este caso es esta ventana. El identificador de una ventana está en el parámetro de mensaje de la función. Esta es la ventana a la que se enviará la respuesta del diálogo.

Para averiguar el valor del color que el usuario eligió, el administrador de ventanas enviará a nuestra ventana un mensaje con el color elegido cuando el usuario presione el botón Aceptar en el cuadro de diálogo. Por lo tanto, también debemos interceptar este mensaje con otro caso en la declaración de cambio que se ve así:

caso MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{mw_hal_lcd_colour_t elegido_color = mensaje-> mensaje_data; (vacío) color_elegido; } rotura;

Todavía no estamos haciendo nada con el color elegido, así que simplemente lo convertimos en vacío para evitar una advertencia del compilador. El código final de esta función ahora se ve así:

void window_W1_message_function (const mw_message_t * mensaje)

{MW_ASSERT (mensaje! = (Void *) 0, "Parámetro de puntero nulo"); / * La siguiente línea detiene las advertencias del compilador ya que la variable no se usa actualmente * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Agrega cualquier código de inicialización de ventana aquí * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Agregar código de manejo de menú de ventana aquí * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Agregue su código de controlador para este control aquí * / mw_create_window_dialog_colour_chooser (10, 10, "Color", MW_HAL_LCD_RED, falso, mensaje-> destinatario_handle); } rotura; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {mw_hal_lcd_colour_t selected_colour = message-> message_data; (vacío) color_elegido; } rotura; predeterminado: / * Mantener feliz a MISRA * / break; }}

La ejecución del código se muestra en la imagen de arriba. Puede notar que cuando se muestra un cuadro de diálogo, debe responder a él y descartarlo antes de hacer cualquier otra cosa. A esto se le llama comportamiento modal. Los cuadros de diálogo en MiniWin y todos siempre globalmente modales y solo puede mostrar uno a la vez. Hay más explicación aquí …

en.wikipedia.org/wiki/Modal_window

Paso 7: Dibujar en la ventana

Dibujando en la ventana
Dibujando en la ventana

Hasta ahora solo hemos usado controles y se dibujan a sí mismos. Es hora de hacer un dibujo personalizado en nuestra ventana. La parte en la que puede dibujar está dentro de los bordes (si los hay, son opcionales), dentro de las barras de desplazamiento (si están definidas, también son opcionales) y debajo de la barra de título (si hay una, eso también es opcional). Se llama área de cliente en terminología de ventanas.

Hay una biblioteca de comandos de gráficos en MiniWin que puede usar. Todos son conscientes de la ventana. Eso significa que no tiene que preocuparse por si la ventana está visible, parcialmente oscurecida por otras ventanas, encendida, parcialmente apagada o completamente fuera de la pantalla, o si la coordenada de donde está dibujando está en el área del cliente o más allá de ella.. Todo está cuidado por ti. No puede dibujar fuera de su área de cliente.

Dibujar en áreas de clientes en la terminología de Windows se llama pintura y cada ventana tiene una función de pintura donde usted dibuja. No llamas a tu función de pintura, el administrador de ventanas lo hace por ti cuando es necesario. Es necesario cuando se mueve una ventana o se cambia la posición o la visibilidad de otra ventana en la parte superior. Si necesita volver a pintar su ventana porque algunos de los datos de los que depende el contenido de la ventana han cambiado (es decir, sabe que se requiere un repintado en lugar de que el administrador de ventanas lo sepa), entonces le dice al administrador de ventanas que se necesita un repintado y llama su función de pintura. No lo llamas tú mismo. (Todo esto se demuestra en la siguiente sección).

Primero, necesita encontrar su función de pintura. El generador de código lo crea por usted y está justo encima de la función del controlador de mensajes modificada en la sección anterior. Vaya a su proyecto y abra el archivo W1.c nuevamente.

En este archivo encontrará la función window_W1_paint_function (). Se parece a esto:

void window_W1_paint_function (mw_handle_t window_handle, const mw_gl_draw_info_t * draw_info)

{MW_ASSERT (draw_info! = (Void *) 0, "Parámetro de puntero nulo"); / * Rellenar el área del cliente de la ventana con blanco sólido * / mw_gl_set_fill (MW_GL_FILL); mw_gl_set_solid_fill_colour (MW_HAL_LCD_WHITE); mw_gl_set_border (MW_GL_BORDER_OFF); mw_gl_clear_pattern (); mw_gl_rectangle (draw_info, 0, 0, mw_get_window_client_rect (window_handle).width, mw_get_window_client_rect (window_handle).height); / * Agrega tu código de pintura de ventana aquí * /}

Este es el código simple generado y todo lo que hace es llenar el área del cliente con blanco sólido. Dibujemos un círculo amarillo relleno en el área del cliente. Primero tenemos que entender el concepto de contexto gráfico (otra cosa de Windows). Establecemos los parámetros de dibujo en el contexto de gráficos y luego llamamos a una rutina de dibujo de círculo genérico. Las cosas que tenemos que establecer en este ejemplo son si el círculo tiene un borde, estilo de línea de borde, color de borde, si el círculo está relleno, color de relleno y patrón de relleno. Puede ver el código de arriba que hace algo similar para llenar el área del cliente con un rectángulo blanco relleno sólido sin bordes. Los valores en el contexto de gráficos no se recuerdan entre cada llamada de la función de pintura, por lo que debe configurar los valores cada vez (aunque se recuerdan con la función de pintura).

En el código anterior, puede ver que el relleno está activado y el patrón de relleno está desactivado, por lo que no es necesario volver a configurarlos. Necesitamos establecer el borde, el estilo de la línea del borde en sólido, el color de primer plano del borde en negro y el color de relleno en amarillo de esta manera:

mw_gl_set_fg_colour (MW_HAL_LCD_BLACK);

mw_gl_set_solid_fill_colour (MW_HAL_LCD_YELLOW); mw_gl_set_line (MW_GL_SOLID_LINE); mw_gl_set_border (MW_GL_BORDER_ON); mw_gl_circle (draw_info, window_simple_data.circle_x, window_simple_data.circle_y, 25);

Agregue este código en el comentario de esta función donde dice que agregue su código. A continuación, necesitamos dibujar un círculo que se hace así:

mw_gl_circle (dibujar_info, 30, 30, 15);

Esto dibuja un círculo en las coordenadas 30, 30 con radio 15. Reconstruya el código y vuelva a ejecutarlo y verá un círculo en la ventana como se muestra arriba. Notarás que el círculo y el botón se superponen, pero el botón está en la parte superior. Esto es por diseño. Los controles están siempre encima de todo lo que dibuja en el área del cliente.

Paso 8: datos de la ventana

Datos de ventana
Datos de ventana

Hasta ahora hemos implementado nuestro propio código en la función de mensaje de la ventana 1 (para manejar los mensajes entrantes) y su función de pintura (para dibujar en el área del cliente de la ventana). Ahora es el momento de vincular los dos. Vamos a rellenar el círculo dibujado en la función de pintura con el color que el usuario elige con el selector de color cuando se presiona el botón. Recuerde que no llamamos a la función de pintura, el administrador de ventanas lo hace, por lo que nuestra función de mensaje (que conoce el color elegido) no puede llamar a la función de pintura directamente por sí misma. En su lugar, necesitamos almacenar en caché los datos y dejar que el administrador de ventanas sepa que es necesario volver a pintar. El administrador de ventanas llamará a la función de pintura que puede usar los datos almacenados en caché.

En la parte superior de W1.c, verá una estructura de datos vacía y un objeto de este tipo declarado por el generador de código como este:

estructura typedef

{/ * Agregue sus miembros de datos aquí * / char dummy; / * Algunos compiladores se quejan de estructuras vacías; elimine esto cuando agregue sus miembros * /} window_W1_data_t; estático window_W1_data_t window_W1_data;

Aquí es donde almacenamos en caché nuestros datos para que se conserven en todas las llamadas y se conocen como datos de ventana. Solo necesitamos almacenar el color elegido aquí, así:

estructura typedef

{/ * Agregue sus miembros de datos aquí * / mw_hal_lcd_colour_t selected_colour; } window_W1_data_t; estático window_W1_data_t window_W1_data = {MW_HAL_LCD_YELLOW};

Le daremos un color inicial de amarillo. Ahora en la función de mensaje cambiaremos ligeramente el código para guardar el color elegido aquí así:

caso MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{window_W1_data.chosen_colour = message-> message_data; } rotura;

Luego cambiaremos la función de pintar para usar este valor cuando dibuje el círculo así:

mw_gl_set_solid_fill_colour (window_W1_data.chosen_colour);

Ahora hemos cambiado los datos de los que depende el contenido de la ventana, por lo que debemos informar al administrador de ventanas que es necesario volver a pintar la ventana. Lo hacemos en la función de mensaje cuando se recibe el mensaje de diálogo OK, así:

mw_paint_window_client (mensaje-> destinatario_handle);

Esto no hace que la ventana se pinte directamente. Es una función de utilidad que envía un mensaje al administrador de ventanas de que es necesario volver a pintar una ventana (si ingresa a ella, puede ver cómo sucede esto). La ventana que debe volver a pintarse en este caso es ella misma, y el identificador de la ventana está en el parámetro de mensaje de la función del controlador de mensajes.

El archivo completo ahora se ve así si no está seguro de dónde van algunos de los fragmentos de código anteriores:

#incluir

#include "miniwin.h" #include "miniwin_user.h" #include "W1.h" typedef struct {/ * Agregue sus miembros de datos aquí * / mw_hal_lcd_colour_t selected_colour; } window_W1_data_t; estático window_W1_data_t window_W1_data = {MW_HAL_LCD_YELLOW}; void window_W1_paint_function (mw_handle_t window_handle, const mw_gl_draw_info_t * draw_info) {MW_ASSERT (draw_info! = (void *) 0, "Parámetro de puntero nulo"); / * Rellenar el área del cliente de la ventana con blanco sólido * / mw_gl_set_fill (MW_GL_FILL); mw_gl_set_solid_fill_colour (MW_HAL_LCD_WHITE); mw_gl_set_border (MW_GL_BORDER_OFF); mw_gl_clear_pattern (); mw_gl_rectangle (draw_info, 0, 0, mw_get_window_client_rect (window_handle).width, mw_get_window_client_rect (window_handle).height); / * Agrega tu código de pintura de ventana aquí * / mw_gl_set_fg_colour (MW_HAL_LCD_BLACK); mw_gl_set_solid_fill_colour (window_W1_data.chosen_colour); mw_gl_set_line (MW_GL_SOLID_LINE); mw_gl_set_border (MW_GL_BORDER_ON); mw_gl_circle (dibujar_info, 30, 30, 15); } void window_W1_message_function (const mw_message_t * message) {MW_ASSERT (message! = (void *) 0, "Parámetro de puntero nulo"); / * La siguiente línea detiene las advertencias del compilador ya que la variable no se usa actualmente * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Agrega cualquier código de inicialización de ventana aquí * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Agregar código de manejo de menú de ventana aquí * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Agregue su código de controlador para este control aquí * / mw_create_window_dialog_colour_chooser (10, 10, "Color", MW_HAL_LCD_RED, falso, mensaje-> destinatario_handle); } rotura; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {window_W1_data.chosen_colour = message-> message_data; mw_paint_window_client (mensaje-> destinatario_handle); } rotura; predeterminado: / * Mantener feliz a MISRA * / break; }}

Construya y ejecute de nuevo y debería poder establecer el color de relleno del círculo.

Este ejemplo de datos de ventana utiliza datos que se almacenan en una estructura de datos estática en la parte superior del archivo de origen. Esto está bien si solo tiene una instancia de la ventana, como lo hacemos en este ejemplo, pero si tiene más de una instancia, todas compartirán la misma estructura de datos. Es posible tener datos por instancia para que varias instancias del mismo tipo de ventana tengan sus propios datos. Esto se explica en la documentación de MiniWin que se encuentra en el directorio de documentos. El ejemplo de archivo lo usa para mostrar múltiples imágenes en el mismo tipo de ventana (como se ve en la imagen principal en la parte superior de este instructable).

Paso 9: Diversión con las fuentes finales

Un poco de diversión con las fuentes finales
Un poco de diversión con las fuentes finales

MiniWin admite la representación de fuentes TrueType. Si hay algo que hace que su interfaz de usuario se vea bien, son las fuentes atractivas. Este último paso muestra cómo representar una fuente TrueType en una ventana MiniWin.

Hay dos formas de renderizar fuentes TrueType. Uno es dibujarlos directamente en su área de cliente como se hizo anteriormente para el círculo, el otro es agregar un control de cuadro de texto en su ventana. Estamos haciendo lo último porque es más fácil.

Ahora agregaremos un control de cuadro de texto en nuestro archivo de configuración JSON. Agréguelo a la definición de Windows 2 para que se vea así:

como esto:

{

"Nombre": "W2", "Título": "Ventana 2", "X": 50, "Y": 65, "Ancho": 100, "Alto": 80, "Borde": verdadero, "Barra de título": verdadero, "Visible": verdadero, "Minimizado": falso, "TextBoxes": [{"Nombre": "TB1", "X": 0, "Y": 0, "Ancho": 115, "Alto": 50, "Justificación": "Centro", "BackgroundColour": "MW_HAL_LCD_YELLOW", "ForegroundColour": "MW_HAL_LCD_BLACK", "Fuente": "mf_rlefont_BLKCHCRY16", "Habilitado": verdadero, "Visible": verdadero}]}

Unas breves palabras sobre las fuentes TrueType en MiniWin. Las fuentes vienen en archivos.ttf. En los administradores de ventanas de computadoras más grandes, estos se representan en su pantalla cuando son necesarios. Esto requiere mucha capacidad de procesamiento y memoria y no es adecuado para dispositivos pequeños. En MiniWin, se procesan previamente en mapas de bits y se vinculan en el momento de la compilación con un tamaño y estilo de fuente fijos (negrita, cursiva, etc.), es decir, debe decidir qué fuentes, en qué tamaño y estilo va a utilizar en el momento de la compilación. Esto se ha hecho para usted con dos fuentes de ejemplo en el archivo zip MiniWin que descargó. Si desea utilizar otras fuentes en otros tamaños y estilos, consulte la documentación de MiniWin en la carpeta de documentos. Hay herramientas en MiniWin para Windows y Linux para preprocesar archivos.ttf en archivos de código fuente que puede colocar en su proyecto.

Y una segunda palabra rápida: la mayoría de las fuentes están protegidas por derechos de autor, incluidas las que encontrará en Microsoft Windows. Úselos a voluntad para uso personal, pero cualquier cosa que publique debe asegurarse de que la licencia con la que se publican las fuentes lo permita, como es el caso de las 2 fuentes incluidas en MiniWin, ¡pero no las fuentes de Microsoft!

¡De vuelta al código! Genere, suelte archivos, compile y vuelva a ejecutar como antes y verá que la ventana 2 ahora tiene un texto predeterminado sobre un fondo amarillo en una fuente extravagante. Cambiemos el texto editando el archivo fuente de Windows 2 W2.c.

Necesitamos comunicarnos con el cuadro de texto que acabamos de crear y la forma en que lo hace, como cualquier comunicación en MiniWin, es enviándole un mensaje. Queremos establecer el texto en el control cuando se crea la ventana pero antes de que se muestre, por lo que agregamos código en el controlador de mensajes en el caso MW_WINDOW_CREATED_MESSAGE. Esto es recibido por el código de ventana justo antes de que se muestre la ventana y está diseñado para inicializaciones como esta. El generador de código creó un marcador de posición que se ve así en la función del controlador de mensajes:

caso MW_WINDOW_CREATED_MESSAGE:

/ * Agregue aquí cualquier código de inicialización de ventana * / break;

Aquí vamos a publicar un mensaje en el control del cuadro de texto indicándole qué texto queremos que muestre usando la función mw_post_message de esta manera:

caso MW_WINDOW_CREATED_MESSAGE:

/ * Agregue aquí cualquier código de inicialización de ventana * / mw_post_message (MW_TEXT_BOX_SET_TEXT_MESSAGE, message-> receiver_handle, text_box_TB1_handle, 0UL, "Fue una noche oscura y tormentosa…", MW_CONTROL_MESSAGE); rotura;

Estos son los parámetros:

  • MW_TEXT_BOX_SET_TEXT_MESSAGE: este es el tipo de mensaje que enviamos al control. Se enumeran en miniwin.hy se documentan en la documentación.
  • message-> receiver_handle: de quién es el mensaje, esta ventana, cuyo identificador está en el parámetro del mensaje que se pasa a la función del controlador de mensajes.
  • text_box_TB1_handle: a quién enviamos el mensaje: el identificador del control del cuadro de texto. Estos se enumeran en el archivo generado miniwin_user.h.
  • 0UL - Valor de datos, nada en este caso.
  • "Fue una noche oscura y tormentosa …" - Valor del puntero - el nuevo texto.
  • MW_CONTROL_MESSAGE: tipo de destinatario que es un control.

Eso es todo. Reconstruya y vuelva a ejecutar como de costumbre y obtendrá el cuadro de texto que se muestra como en la imagen de arriba.

La publicación de mensajes es fundamental para MiniWin (como lo es para todos los administradores de ventanas). Para más ejemplos, mire los proyectos de ejemplo en el archivo zip y para una explicación completa lea la sección sobre mensajes MiniWin en la documentación.

Paso 10: ir más lejos

Image
Image

Eso es todo por esta introducción básica a MiniWin. MiniWin puede hacer mucho más de lo que se ha demostrado aquí. Por ejemplo, la pantalla del tablero que se usa en este instructable es pequeña y los controles son pequeños y deben usarse con un dibber. Sin embargo, otros ejemplos y hardware usan controles más grandes (hay 2 tamaños) en pantallas más grandes y estos se pueden operar con los dedos.

Hay muchos otros tipos de control además de los demostrados aquí. Para obtener más controles, eche un vistazo a los diversos archivos JSON de ejemplo en la carpeta del generador de código. Todos los tipos de control se tratan en estos ejemplos.

Windows tiene muchas opciones. El borde, la barra de título y los iconos son todos configurables. Puede tener barras de desplazamiento y áreas de cliente de ventana de desplazamiento, varias instancias del mismo tipo de ventana y las ventanas pueden estar desnudas (solo un área de cliente, sin borde ni barra de título), lo que significa que están fijas en el momento de la compilación en su lugar en la pantalla (vea la imagen en esta sección con íconos grandes de tamaño (en realidad son 6 ventanas desnudas).

MiniWin no utiliza memoria dinámica. Esto lo hace adecuado para pequeños dispositivos restringidos y es un requisito para algunos proyectos integrados. MiniWin y el código que genera también es totalmente compatible con MISRA 2012 al nivel 'requerido'.

Para obtener más información, consulte la carpeta de documentos para ver la documentación y también las otras aplicaciones de ejemplo en el archivo zip. Aquí hay ejemplos que muestran cómo utilizar todas las funciones de MiniWin y cómo integrar MiniWin con FatFS y FreeRTOS.

Recomendado: