Inhoudsopgave:

Embedded Window Manager: 10 stappen
Embedded Window Manager: 10 stappen

Video: Embedded Window Manager: 10 stappen

Video: Embedded Window Manager: 10 stappen
Video: 30 лучших советов и рекомендаций по Windows 10 на 2020 год 2024, Juli-
Anonim
Ingesloten vensterbeheer
Ingesloten vensterbeheer
Ingesloten vensterbeheer
Ingesloten vensterbeheer
Ingesloten vensterbeheer
Ingesloten vensterbeheer
Ingesloten vensterbeheer
Ingesloten vensterbeheer

Dit project laat zien hoe een windowmanager met beweegbare overlappende vensters kan worden geïmplementeerd op een ingebouwde microcontroller met een LCD-paneel en een aanraakscherm. Er zijn in de handel verkrijgbare softwarepakketten om dit te doen, maar deze kosten geld en zijn closed source. Deze, genaamd MiniWin, is gratis en open-source. Het is geschreven in volledig compatibele C99 en kan worden gebruikt in een C- of C++-toepassing. De doelen van MiniWin zijn eenvoudig te gebruiken, gemakkelijk aan te passen, uitbreidbaar, overdraagbaar naar een breed scala aan hardware en niet al te veel resources.

Naast het leveren van de code om uw vensters te beheren, heeft MiniWin een verzameling bedieningselementen voor de gebruikersinterface - knoppen, schuifregelaars, voortgangsbalken, bomen enz. U kunt meerdere vensters van verschillende typen hebben of meerdere instanties van hetzelfde type. Windows kan worden verplaatst, vergroot of verkleind, gemaximaliseerd, geminimaliseerd, gesloten - alle gebruikelijke dingen die u doet met vensters in grotere vensterbeheerders. TrueType-lettertypen met tekenspatiëring en anti-aliasing (laat de tekst er glad uitzien) worden ook ondersteund voor een aantrekkelijke tekstweergave.

In elk venster heb je een klantengebied (je ruimte binnen de rand en onder de bovenste balk). Hierop kunt u besturingselementen toevoegen om een dialoogvenster te maken of u kunt de ingebouwde grafische bibliotheek gebruiken om te tekenen wat u maar wilt. Alle functies van de grafische bibliotheek zijn vensterbewust. U hoeft zich geen zorgen te maken over waar uw raam is, wat het overlapt of dat het geminimaliseerd is.

Naast het maken van uw eigen vensters zijn er ook enkele standaarddialoogvensters die zeer eenvoudig te instantiëren zijn - bijvoorbeeld bevestigingsdialoogvensters (alleen een OK of Ja/Nee-knop), tijd-/datumstellers, bestandskiezers, kleurkiezers enz.

MiniWin gebruikt een standaard berichtenwachtrijsysteem van Windows Manager. Windows kan via berichten met elkaar en met de vensterbeheerder communiceren. Je roept functies niet aan om dingen direct te doen, je voegt een bericht toe aan de wachtrij en de windowmanager voert het voor je uit.

MiniWin is geport naar standaard ontwikkelborden met touchscreen-displays van microcontrollerleveranciers ST, NXP en Renesas. Er zijn hardwarestuurprogramma's en voorbeeldprojecten voor al deze apparaten. Daarnaast kan MiniWin worden gebouwd voor Windows of Linux, zodat u uw gebruikersinterfacecode kunt simuleren voordat u uw embedded hardware aanschaft.

MiniWin heeft een codegenerator. U kunt uw vensters en bedieningselementen specificeren in een eenvoudig te maken door mensen leesbaar JSON-bestand en de codegenerator parseert het bestand en maakt de code voor u (er zijn veel voorbeelden die volgen). Het creëert complete Windows- of Linux-simulatortoepassingen die gewoon kunnen worden gebouwd en daar is uw gesimuleerde LCD-scherm met uw MiniWin-vensters werkend. U kunt exact dezelfde gegenereerde code nemen en deze in een embedded project plaatsen en dezelfde code even later dezelfde vensters en bedieningselementen laten zien op uw embedded hardware.

MiniWin vereist geen operationele ondersteuning op het ingebouwde apparaat. Het loopt allemaal in één draad. MiniWin kan worden geïntegreerd met een RTOS die draait op een ingebouwde processor en er zijn voorbeelden die MiniWin integreren met FreeRTOS.

Deze instructable laat zien hoe je MiniWin in gebruik kunt nemen op een STM32 M4-processor met behulp van het goedkope STM32F429 Discovery-bord dat wordt geleverd met een QVGA-aanraakscherm dat al is bevestigd. Deze zijn gemakkelijk verkrijgbaar bij uw leverancier van elektronische componenten.

MiniWin draait op mid-range microcontrollers en hoger.

Benodigdheden

STM32F429I-DISC1 ontwikkelbord en een micro-USB-kabel

STM32CubeIDE-download die gratis is.

Stap 1: De code verkrijgen

De code verkrijgen
De code verkrijgen

Allereerst moet STM32CubeIDE geïnstalleerd zijn. Dat haal je van de website van ST. U moet zich registreren en het duurt even om het te downloaden en te installeren. Het is allemaal gratis.

Terwijl dat aan het installeren is, download je de MiniWin-bron en pak je het uit. Het is groot, maar je gebruikt er maar een klein deel van. Klik hier op de groene knop 'Klonen of downloaden'…

github.com/miniwinwm/miniwinwm

kies vervolgens Zip downloaden. Pak de inhoud uit.

Stap 2: Een voorbeeldproject bouwen

Een voorbeeldproject bouwen
Een voorbeeldproject bouwen
Een voorbeeldproject bouwen
Een voorbeeldproject bouwen

Laten we eerst een van de voorbeeldprojecten bouwen. Een goede heet MiniWinSimple. Start STM32CubeIDE op en doe dit:

  1. Kies Bestand|Importeren…
  2. Open Algemeen en kies Bestaand project in werkruimte. Volgende.
  3. Klik op Bladeren en navigeer naar waar je MiniWin hebt uitgepakt. Ga dan naar de map STM32CubeIDE\MiniWinSimple\STM32F429. Klik op Map selecteren.
  4. In Project: vink MiniWinSimple_STM32F429 aan en klik vervolgens op Voltooien.
  5. MiniWinSimple_STM32F429-project verschijnt in uw Projectverkenner. Selecteer het en bouw het vervolgens met Project|Build Project.
  6. Sluit nu uw USB-kabel aan op het bord en uw computer en voer het uit met Run|Debug en wanneer het is gedownload, kiest u Run|Resume. U krijgt de eerste keer een schermkalibratieweergave, dus raak het midden van de 3 kruisjes op het LCD-scherm aan. U kunt nu communiceren met het venster op het display.

Om een venster te verplaatsen, sleept u het aan de titelbalk. Om het formaat van een venster te wijzigen, gebruikt u het witte driehoekje links van de titelbalk. MiniWin-vensters kunnen niet worden vergroot of verkleind door de randen te verslepen, omdat de schermen waarop MiniWin wordt gebruikt, te klein zijn. Gebruik de pictogrammen aan de rechterkant van de titelbalk om een venster te minimaliseren, maximaliseren of sluiten (sluiten is mogelijk uitgeschakeld). Wanneer een venster is geminimaliseerd, kunt u de geminimaliseerde pictogrammen niet verplaatsen. Ze bouwen zich op van linksonder naar rechts.

Stap 3: De codegenerator uitvoeren

De codegenerator uitvoeren
De codegenerator uitvoeren

Nu zullen we het voorbeeldproject wijzigen door enkele eigen vensters te genereren en de nieuwe code erin te laten vallen. Om dit te doen, zullen we de codegenerator uitvoeren.

  1. Open een opdrachtprompt en ga naar de map waarin u MiniWin hebt uitgepakt en vervolgens naar de map Tools\CodeGen.
  2. Het uitvoerbare bestand voor Windows CodeGen.exe is al beschikbaar. Voor Linux moet je het bouwen door make te typen. (U kunt het ook vanuit de broncode voor Windows bouwen als u zich zorgen maakt over het uitvoeren van een gedownload uitvoerbaar bestand, maar u moet de compiler en de ontwikkelomgeving hebben geïnstalleerd. Zie de MiniWin-documentatie in de docs-map voor details).
  3. In deze map staan enkele voorbeelden van JSON-bestanden. We gebruiken example_empty.json. U moet het eerst bewerken om het in te stellen voor Windows of Linux. Open het in een editor en bovenaan waar je "TargetType" vindt, verander de "Linux" of "Windows" waarde naar waar je de codegenerator op draait.
  4. Typ nu codegen example_empty.json in de opdrachtprompt.
  5. Ga naar je project in STM32CubeIDE en open de map MiniWinSimple_Common. Verwijder alle bestanden daarin.
  6. We hebben de "TargetName" in het JSON-bestand als standaard gelaten bij "MiniWinGen", dus dat is de naam van onze map met gegenereerde code. Ga naar de map waar je MiniWin hebt uitgepakt en vervolgens naar de map MiniWinGen_Common. Selecteer nu al deze bestanden en sleep ze naar STM32CubeIDE in de MiniWinSimple_Common-map van uw project.
  7. Bouw het project nu opnieuw op en voer het opnieuw uit in STM32CubeIDE en uw nieuwe ontwerpvenster zal verschijnen. De knop in het venster is verdwenen omdat example_empty.json er geen definieert.

Stap 4: Een venster toevoegen

Een venster toevoegen
Een venster toevoegen

We voegen nu een tweede venster toe aan het JSON-configuratiebestand en genereren de code opnieuw.

1. Open example_empty.json in een teksteditor.

2. Onder de sectie "Windows" is er een reeks vensterdefinities die momenteel slechts één venster heeft. Kopieer dit alles…

{

"Naam": "W1", "Titel": "Venster 1", "X": 10, "Y": 15, "Breedte": 200, "Hoogte": 180, "Border": waar, "TitleBar": true, "Zichtbaar": true, "Minimised": false }

en plak het er opnieuw in met een komma die de 2 definities scheidt.

3. Wijzig "W1" in "W2" en "Venster 1" in "Venster 2". Verander "X", "Y", "Breedte" en "Hoogte" in een aantal verschillende waarden, rekening houdend met de schermresolutie is 240 breed bij 320 hoog.

4. Sla het bestand op en voer de codegenerator opnieuw uit.

5. Kopieer de bestanden zoals in de vorige stap, herbouw en start opnieuw. Je hebt nu 2 vensters op je scherm.

Stap 5: Een besturingselement toevoegen

Een besturingselement toevoegen
Een besturingselement toevoegen

Nu voegen we enkele bedieningselementen toe aan uw nieuwe venster. Bewerk hetzelfde bestand als in de vorige stap.

1. Voeg in de specificatie voor venster W1 een komma toe na de laatste instelling ("Minimised": false) en voeg dan deze tekst toe

"Menubalk": waar, "MenuBarEnabled": true, "MenuItems": ["Fred", "Bert", "Pete", "Alf", "Ian"], "Buttons": [{ "Name": "B1", "Label": "Knop1", "X": 10, "Y": 10, "Ingeschakeld": waar, "Zichtbaar": waar }]

Deze sectie voegt een menubalk toe met 5 items en schakelt deze in (menubalken kunnen globaal worden uitgeschakeld, probeer het). Het voegt ook een knop toe die is ingeschakeld en zichtbaar is (ze kunnen onzichtbaar worden gemaakt en later zichtbaar worden gemaakt in code).

2. Genereer de code, kopieer deze, herbouw, voer alles opnieuw uit zoals voorheen.

Stap 6: De besturing iets laten doen

De besturing iets laten doen
De besturing iets laten doen

Nu hebben we de basisgebruikersinterface die we nodig hebben om het iets te laten doen. Voor dit voorbeeld zullen we een dialoogvenster voor het kiezen van kleuren openen wanneer op de knop in venster 1 wordt gedrukt.

Ga naar uw project in STM32CubeIDE en open de map MiniWinSimple_Common en open vervolgens het bestand W1.c (de naam van dit bestand komt overeen met het veld "Naam" van het venster in het JSON-bestand toen de code werd gegenereerd).

In dit bestand vind je functie window_W1_message_function(). Het ziet er zo uit:

void window_W1_message_function(const mw_message_t *message){ MW_ASSERT(message!= (void*)0, "Null pointer parameter"); /* De volgende regel stopt de compilerwaarschuwingen omdat de variabele momenteel niet wordt gebruikt */ (void)window_W1_data; switch (message->message_id) { case MW_WINDOW_CREATED_MESSAGE: /* Voeg hier een vensterinitialisatiecode toe */ break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: /* Voeg hier de verwerkingscode van het venstermenu toe */ break; case MW_BUTTON_PRESSED_MESSAGE: if (message->sender_handle == button_B1_handle) { /* Voeg hier uw handlercode voor dit besturingselement toe */} break; standaard: /* Houd MISRA tevreden */ pauze; } }

Dit wordt door de vensterbeheerder voor dit venster aangeroepen wanneer de vensterbeheerder het venster moet laten weten dat er iets is gebeurd. In dit geval willen we weten dat de enige knop van het venster is ingedrukt. In de switch-instructie voor berichttypen ziet u een case voor MW_BUTTON_PRESSED_MESSAGE. Deze code wordt uitgevoerd wanneer de knop is ingedrukt. Er is maar één knop in dit venster, maar het kunnen er meer zijn, dus er wordt gekeken welke knop het is. In dit geval zou het alleen knop B1 kunnen zijn (naam komt weer overeen met de naam van de knop in het JSON-bestand).

Dus voeg na dit caselabel de code toe om een dialoogvenster voor het kiezen van kleuren te openen, namelijk dit:

mw_create_window_dialog_colour_chooser(10, 10, "Colour", MW_HAL_LCD_RED, false, message->recipient_handle);

De parameters zijn als volgt:

  • 10, 10 is de locatie op het scherm van het dialoogvenster
  • "Kleur" is de titel van het dialoogvenster
  • MW_HAL_LCD_RED is de standaardkleur waarmee het dialoogvenster begint
  • false betekent dat het formaat niet groot is (probeer het op true in te stellen en zie het verschil)
  • message->recipient handle is wie de eigenaar is van dit dialoogvenster, in dit geval is het dit venster. De handle van een venster bevindt zich in de berichtparameter van de functie. Dit is het venster waarnaar het dialoogantwoord wordt verzonden.

Om de waarde te achterhalen van de kleur die de gebruiker heeft gekozen, stuurt de vensterbeheerder ons venster een bericht met de gekozen kleur wanneer de gebruiker op de OK-knop in het dialoogvenster drukt. Daarom moeten we dit bericht ook onderscheppen met een ander geval in de switch-instructie die er als volgt uitziet:

geval MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{ mw_hal_lcd_colour_t choice_colour = message->message_data; (ongeldig) gekozen_kleur; } pauze;

We doen nog niets met de gekozen kleur, dus casten we deze gewoon naar ongeldig om een compilerwaarschuwing te voorkomen. De uiteindelijke code van deze functie ziet er nu als volgt uit:

void window_W1_message_function(const mw_message_t *bericht)

{ MW_ASSERT(bericht!= (void*)0, "Null pointer parameter"); /* De volgende regel stopt de compilerwaarschuwingen omdat de variabele momenteel niet wordt gebruikt */ (void)window_W1_data; switch (message->message_id) { case MW_WINDOW_CREATED_MESSAGE: /* Voeg hier een vensterinitialisatiecode toe */ break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: /* Voeg hier de verwerkingscode van het venstermenu toe */ break; case MW_BUTTON_PRESSED_MESSAGE: if (message->sender_handle == button_B1_handle) { /* Voeg hier uw handlercode voor dit besturingselement toe */ mw_create_window_dialog_colour_chooser (10, 10, "Colour", MW_HAL_LCD_RED, false, message->recipient); } pauze; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: { mw_hal_lcd_colour_t choice_colour = message->message_data; (ongeldig) gekozen_kleur; } pauze; standaard: /* Houd MISRA tevreden */ pauze; } }

Het uitvoeren van de code wordt getoond in de afbeelding hierboven. U merkt misschien dat wanneer een dialoogvenster wordt weergegeven, u erop moet reageren en het moet sluiten voordat u iets anders doet. Dit wordt modaal gedrag genoemd. Dialogen in MiniWin en allemaal altijd globaal modaal en je kunt er maar één tegelijk laten zien. Hier staat meer uitleg…

en.wikipedia.org/wiki/Modal_window

Stap 7: Tekenen in het venster

Tekenen in het venster
Tekenen in het venster

Tot nu toe hebben we alleen besturingselementen gebruikt en ze tekenen zichzelf. Het is tijd om een aangepaste tekening op ons raam te maken. Het deel waarop u kunt tekenen, bevindt zich binnen de randen (als die er zijn, zijn ze optioneel), binnen de schuifbalken (indien gedefinieerd, ook optioneel) en onder de titelbalk (als die er is, is dat ook optioneel). In de vensterterminologie wordt dit het klantengebied genoemd.

Er is een bibliotheek met grafische opdrachten in MiniWin die u kunt gebruiken. Ze zijn allemaal raambewust. Dat betekent dat u zich geen zorgen hoeft te maken of het venster zichtbaar is, gedeeltelijk wordt verduisterd door andere vensters, aan, gedeeltelijk uit of volledig buiten het scherm, of dat de coördinaat van waar u tekent zich op het clientgebied of daarbuiten bevindt. Het wordt allemaal voor je geregeld. U kunt niet buiten uw klantengebied tekenen.

Tekenen op klantgebieden in vensterterminologie wordt schilderen genoemd en elk venster heeft een verffunctie waar u uw tekening maakt. Je roept je verffunctie niet aan, de windowmanager doet het voor je wanneer dat nodig is. Het is nodig wanneer een venster wordt verplaatst of wanneer een ander venster bovenaan de positie of zichtbaarheid verandert. Als u uw venster opnieuw moet schilderen omdat sommige gegevens waarvan de inhoud van het venster afhankelijk is, zijn veranderd (dwz u weet dat opnieuw schilderen vereist is in plaats van dat de vensterbeheerder weet), dan vertelt u de vensterbeheerder dat er opnieuw moet worden geverfd en hij roept uw verffunctie. Je noemt het niet zelf. (Dit wordt allemaal gedemonstreerd in de volgende sectie).

Eerst moet u uw verffunctie vinden. De codegenerator maakt het voor u en het staat net boven de berichthandlerfunctie die in de vorige sectie is gewijzigd. Ga naar je project en open bestand W1.c opnieuw.

In dit bestand vind je de functie window_W1_paint_function(). Het ziet er zo uit:

void window_W1_paint_function(mw_handle_t window_handle, const mw_gl_draw_info_t *draw_info)

{ MW_ASSERT(draw_info!= (void*)0, "Null pointer parameter"); /* Vul het clientgebied van het venster met effen wit */ 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); /* Voeg hier uw raamschildercode toe */ }

Dit is de kale as-generated code en het enige wat het doet is het klantengedeelte vullen met effen wit. Laten we een geel gevulde cirkel tekenen op het klantengebied. Eerst moeten we het concept van een grafische context begrijpen (een ander Windows-ding). We stellen tekenparameters in de grafische context in en roepen vervolgens een generieke cirkeltekenroutine aan. Wat we in dit voorbeeld moeten instellen, zijn of de cirkel een rand heeft, een grenslijnstijl, een randkleur, of de cirkel gevuld is, een opvulkleur en een opvulpatroon. U kunt de bovenstaande code zien die iets soortgelijks doet voor het vullen van het clientgebied met een randloze, effen gevulde witte rechthoek. De waarden in de grafische context worden niet onthouden tussen elke aanroep van de verffunctie, dus je moet de waarden elke keer instellen (ze worden wel onthouden met de verffunctie).

In de bovenstaande code kun je zien dat de vulling is ingeschakeld en het vulpatroon is uitgeschakeld, dus we hoeven deze niet opnieuw in te stellen. We moeten de rand instellen op, de stijl van de grenslijn op effen, de voorgrondkleur op zwart en de vulkleur op geel als volgt:

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);

Voeg deze code toe bij de opmerking in deze functie waar staat dat je je code moet toevoegen. Vervolgens moeten we een cirkel tekenen die als volgt wordt gedaan:

mw_gl_circle(draw_info, 30, 30, 15);

Dit tekent een cirkel op coördinaten 30, 30 met straal 15. Herbouw de code en voer het opnieuw uit en je zult een cirkel zien in het venster zoals hierboven weergegeven. Je zult zien dat de cirkel en de knop elkaar overlappen, maar de knop zit bovenaan. Dit is door het ontwerp. De bedieningselementen bevinden zich altijd bovenop alles wat u in het klantengebied tekent.

Stap 8: Venstergegevens

Venstergegevens
Venstergegevens

Tot nu toe hebben we onze eigen code geïmplementeerd in de berichtfunctie van Window 1 (om binnenkomende berichten te verwerken) en de paint-functie (om te tekenen op het clientgebied van het venster). Nu is het tijd om de twee te koppelen. Laten we de cirkel die in de verffunctie is getekend, vullen met de kleur die de gebruiker kiest door de kleurkiezer toen de knop werd ingedrukt. Onthoud dat we de verffunctie niet aanroepen, de windowmanager doet het, dus onze berichtfunctie (die de gekozen kleur kent) kan de verffunctie niet rechtstreeks zelf aanroepen. In plaats daarvan moeten we de gegevens in de cache opslaan en de vensterbeheerder laten weten dat opnieuw schilderen vereist is. De windowmanager zal dan de paint-functie aanroepen die de gegevens in de cache kan gebruiken.

Bovenaan W1.c zie je een lege datastructuur en een object van dit type gedeclareerd door de codegenerator als volgt:

typedef struct

{ /* Voeg hier uw gegevensleden toe */ char dummy; /* Sommige compilers klagen over lege structs; verwijder dit wanneer u uw leden toevoegt */ } window_W1_data_t; statisch window_W1_data_t window_W1_data;

Dit is waar we onze gegevens in de cache opslaan, zodat deze bij alle oproepen worden bewaard en ook wel de venstergegevens worden genoemd. We hoeven alleen de gekozen kleur hier op te slaan, zoals deze:

typedef-struct

{ /* Voeg hier uw gegevensleden toe */ mw_hal_lcd_colour_t choice_colour; } window_W1_data_t; statisch window_W1_data_t window_W1_data = {MW_HAL_LCD_YELLOW};

We geven het de startkleur geel. Nu zullen we in de berichtenfunctie de code iets veranderen om de gekozen kleur hier als volgt op te slaan:

geval MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{ window_W1_data.chosen_colour = bericht->bericht_data; } pauze;

Vervolgens veranderen we de verffunctie om deze waarde te gebruiken wanneer deze de cirkel als volgt tekent:

mw_gl_set_solid_fill_colour (window_W1_data.chosen_colour);

Nu hebben we de gegevens gewijzigd waarvan de inhoud van het venster afhankelijk is, dus we moeten de vensterbeheerder laten weten dat het venster opnieuw moet worden geverfd. We doen het in de berichtfunctie wanneer het dialoogvenster OK-bericht wordt ontvangen, zoals dit:

mw_paint_window_client(bericht->ontvanger_handle);

Hierdoor wordt het raam niet direct geverfd. Het is een hulpprogramma-functie die een bericht naar de vensterbeheerder stuurt dat een venster opnieuw moet worden geverfd (als je erin stapt, kun je zien hoe dit gebeurt). Het venster dat in dit geval opnieuw moet worden geverfd, is zichzelf en de hendel naar het venster bevindt zich in de berichtparameter voor de berichthandlerfunctie.

Het hele bestand ziet er nu als volgt uit als je niet zeker weet waar sommige van de bovenstaande codefragmenten naartoe gaan:

#erbij betrekken

#include "miniwin.h" #include "miniwin_user.h" #include "W1.h" typedef struct { /* Voeg hier uw gegevensleden toe */ mw_hal_lcd_colour_t choice_colour; } window_W1_data_t; statisch 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, "Null pointer parameter"); /* Vul het clientgebied van het venster met effen wit */ 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); /* Voeg hier uw raamschildercode toe */ 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(draw_info, 30, 30, 15); } void window_W1_message_function(const mw_message_t *message) { MW_ASSERT(message!= (void*)0, "Null pointer parameter"); /* De volgende regel stopt de compilerwaarschuwingen omdat de variabele momenteel niet wordt gebruikt */ (void)window_W1_data; switch (message->message_id) { case MW_WINDOW_CREATED_MESSAGE: /* Voeg hier een vensterinitialisatiecode toe */ break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: /* Voeg hier de verwerkingscode van het venstermenu toe */ break; case MW_BUTTON_PRESSED_MESSAGE: if (message->sender_handle == button_B1_handle) { /* Voeg hier uw handlercode voor dit besturingselement toe */ mw_create_window_dialog_colour_chooser (10, 10, "Colour", MW_HAL_LCD_RED, false, message->recipient); } pauze; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: { window_W1_data.chosen_colour = message->message_data; mw_paint_window_client(bericht->ontvanger_handle); } pauze; standaard: /* Houd MISRA tevreden */ pauze; } }

Bouw en ren opnieuw en je zou de vulkleur van de cirkel moeten kunnen instellen.

Dit voorbeeld van venstergegevens gebruikt gegevens die zijn opgeslagen in een statische gegevensstructuur bovenaan het bronbestand. Dit is prima als je maar één exemplaar van het venster hebt, zoals in dit voorbeeld, maar als je meer dan één exemplaar hebt, delen ze allemaal dezelfde gegevensstructuur. Het is mogelijk om gegevens per instantie te hebben, zodat meerdere instanties van hetzelfde venstertype hun eigen gegevens hebben. Dit wordt uitgelegd in de MiniWin-documentatie in de docs-map. Het bestandsvoorbeeld gebruikt het om meerdere afbeeldingen in hetzelfde venstertype weer te geven (zoals te zien in de hoofdafbeelding helemaal bovenaan deze instructable).

Stap 9: wat laatste lettertypeplezier

Wat laatste lettertypeplezier
Wat laatste lettertypeplezier

MiniWin ondersteunt TrueType-lettertypeweergave. Als er één ding is waardoor uw gebruikersinterface er goed uitziet, dan zijn het wel aantrekkelijke lettertypen. Deze laatste stap laat zien hoe u een TrueType-lettertype in een MiniWin-venster kunt weergeven.

Er zijn twee manieren om TrueType-lettertypen weer te geven. Een daarvan is om ze rechtstreeks op uw klantengebied te tekenen, zoals eerder voor de cirkel werd gedaan, de andere is om een tekstvakbesturingselement aan uw venster toe te voegen. We doen het laatste omdat het makkelijker is.

Nu voegen we een tekstvakbesturingselement toe aan ons JSON-configuratiebestand. Voeg het toe aan de definitie van Window 2, zodat het er als volgt uitziet:

zoals dit:

{

"Naam": "W2", "Titel": "Venster 2", "X": 50, "Y": 65, "Breedte": 100, "Hoogte": 80, "Border": waar, "TitleBar": true, "Visible": true, "Minimised": false, "TextBoxes": [{ "Name": "TB1", "X": 0, "Y": 0, "Breedte": 115, "Hoogte": 50, "Justification": "Centre", "BackgroundColour": "MW_HAL_LCD_YELLOW", "ForegroundColour": "MW_HAL_LCD_BLACK", "Font": "mf_rlefont_BLKCHCRY16", "Enabled": true, "Visible": true }]

Een kort woord over TrueType-lettertypen in MiniWin. Lettertypen komen in.ttf-bestanden. In windowmanagers op grotere computers worden deze op uw scherm weergegeven wanneer ze nodig zijn. Dit kost veel rekenkracht en geheugen en is niet geschikt voor kleine apparaten. In MiniWin worden ze voorbewerkt tot bitmaps en tijdens het compileren gekoppeld aan een vaste lettergrootte en -stijl (vet, cursief enz.), d.w.z. je moet beslissen welke lettertypen met welke grootte en stijl je gaat gebruiken tijdens het compileren. Dit is voor u gedaan voor twee voorbeeldlettertypen in het MiniWin-zipbestand dat u hebt gedownload. Als u andere lettertypen met andere formaten en stijlen wilt gebruiken, raadpleegt u de MiniWin-documentatie in de map docs. Er zijn hulpmiddelen in MiniWin voor Windows en Linux voor het voorbewerken van.ttf-bestanden in broncodebestanden die u in uw project kunt neerzetten.

En een tweede kort woord: de meeste lettertypen zijn auteursrechtelijk beschermd, inclusief die in Microsoft Windows. Gebruik ze naar believen voor persoonlijk gebruik, maar alles wat u publiceert, moet u ervoor zorgen dat de licentie waarmee de lettertypen worden gepubliceerd dit toestaat, zoals het geval is voor de 2 lettertypen in MiniWin, maar niet voor de lettertypen van Microsoft!

Terug naar de code! Genereer, zet bestanden neer, bouw en voer het opnieuw uit zoals voorheen en je zult zien dat Windows 2 nu wat standaardtekst heeft op een gele achtergrond in een gek lettertype. Laten we de tekst wijzigen door het bronbestand W2.c van Windows 2 te bewerken.

We moeten communiceren met het tekstvak dat we zojuist hebben gemaakt en de manier waarop u dat doet, zoals elke communicatie in MiniWin, is door er een bericht naar te sturen. We willen de tekst in het besturingselement instellen wanneer het venster wordt gemaakt, maar voordat het wordt weergegeven, dus voegen we code toe aan de berichthandler in het geval MW_WINDOW_CREATED_MESSAGE. Deze wordt ontvangen door de venstercode net voordat het venster wordt weergegeven en is bedoeld voor dergelijke initialisaties. De codegenerator heeft een plaatshouder gemaakt die er als volgt uitziet in de berichthandlerfunctie:

geval MW_WINDOW_CREATED_MESSAGE:

/* Voeg hier een vensterinitialisatiecode toe */ break;

Hier gaan we een bericht naar het tekstvakbesturingselement plaatsen om te vertellen welke tekst we willen dat het toont door de functie mw_post_message als volgt te gebruiken:

geval MW_WINDOW_CREATED_MESSAGE:

/* Voeg hier een vensterinitialisatiecode toe */ mw_post_message(MW_TEXT_BOX_SET_TEXT_MESSAGE, message->recipient_handle, text_box_TB1_handle, 0UL, "Twas a dark and stormy night…", MW_CONTROL_MESSAGE); pauze;

Dit zijn de parameters:

  • MW_TEXT_BOX_SET_TEXT_MESSAGE - Dit is het berichttype dat we naar de besturing sturen. Ze worden vermeld in miniwin.h en gedocumenteerd in de documentatie.
  • message->recipient_handle - Dit is van wie het bericht afkomstig is - dit venster - waarvan de handle zich in de berichtparameter bevindt die wordt doorgegeven aan de berichthandlerfunctie.
  • text_box_TB1_handle - Naar wie we het bericht sturen - de handle van het tekstvakbesturingselement. Deze staan vermeld in het gegenereerde bestand miniwin_user.h.
  • 0UL - Gegevenswaarde, niets in dit geval.
  • "Het was een donkere en stormachtige nacht…" - Pointerwaarde - de nieuwe tekst.
  • MW_CONTROL_MESSAGE - Type ontvanger dat een besturingselement is.

Dat is het. Herbouw en voer het opnieuw uit zoals gewoonlijk en je krijgt het tekstvak te zien zoals in de afbeelding hierboven.

Het plaatsen van berichten is van fundamenteel belang voor MiniWin (zoals voor alle vensterbeheerders). Kijk voor meer voorbeelden naar de voorbeeldprojecten in het zip-bestand en lees voor een uitgebreide uitleg de paragraaf over MiniWin-berichten in de documentatie.

Stap 10: Verder gaan

Image
Image

Dat was het voor deze basisintroductie tot MiniWin. MiniWin kan veel meer dan hier is aangetoond. Het scherm op het bord dat in deze instructable wordt gebruikt, is bijvoorbeeld klein en de bedieningselementen zijn klein en moeten met een dibber worden gebruikt. Andere voorbeelden en hardware gebruiken echter grotere bedieningselementen (er zijn 2 formaten) op grotere schermen en deze kunnen met de vinger worden bediend.

Er zijn veel andere soorten controle dan de hier getoonde. Bekijk voor meer bedieningselementen de verschillende voorbeeld-JSON-bestanden in de codegeneratormap. In deze voorbeelden worden alle besturingstypen behandeld.

Windows heeft veel mogelijkheden. De rand, titelbalk en pictogrammen zijn allemaal configureerbaar. U kunt schuifbalken en schuifvenster-clientgebieden hebben, meerdere exemplaren van hetzelfde venstertype en vensters kunnen naakt zijn (alleen een clientgebied, geen rand of titelbalk), wat betekent dat ze tijdens het compileren op hun plaats op het scherm worden geplaatst (zie de afbeelding in deze sectie met grote pictogrammen - dit zijn eigenlijk 6 naakte vensters).

MiniWin gebruikt geen dynamisch geheugen. Dit maakt het geschikt voor kleine beperkte apparaten en is een vereiste voor sommige embedded projecten. MiniWin en de code die het genereert, is ook volledig MISRA 2012-compatibel tot het 'vereiste' niveau.

Kijk voor meer informatie in de docs-map voor de documentatie en ook de andere voorbeeld-apps in het zip-bestand. Er zijn hier voorbeelden die laten zien hoe u alle functies van MiniWin kunt gebruiken en hoe u MiniWin kunt integreren met FatFS en FreeRTOS.

Aanbevolen: