Innehållsförteckning:

Inbäddad fönsterhanterare: 10 steg
Inbäddad fönsterhanterare: 10 steg

Video: Inbäddad fönsterhanterare: 10 steg

Video: Inbäddad fönsterhanterare: 10 steg
Video: multiple virtual keyboard activation on nemoshell (window manager based on wayland) 2024, Juli
Anonim
Inbäddad fönsterhanterare
Inbäddad fönsterhanterare
Inbäddad fönsterhanterare
Inbäddad fönsterhanterare
Inbäddad fönsterhanterare
Inbäddad fönsterhanterare
Inbäddad fönsterhanterare
Inbäddad fönsterhanterare

Detta projekt visar hur man implementerar en fönsterhanterare med rörliga överlappade fönster på en inbäddad mikrokontroller med en LCD-panel och en pekskärm. Det finns kommersiellt tillgängliga mjukvarupaket för att göra detta men de kostar pengar och är slutna källor. Den här, kallad MiniWin, är gratis och öppen källkod. Den är skriven i helt kompatibel C99 och kan användas i en C- eller C ++ - applikation. Målen med MiniWin är att vara enkla att använda, enkla att modifiera, utbyggbara, bärbara till ett brett utbud av hårdvara och inte för resurssugna.

Förutom att tillhandahålla koden för att hantera dina Windows MiniWin har en samling användargränssnittskontroller - knappar, reglage, förloppsindikatorer, träd etc. Du kan ha flera fönster av olika typer eller flera instanser av samma typ. Windows kan flyttas, storleksanpassas, maximeras, minimeras, stängas - allt det vanliga du gör med fönster i större fönsterhanterare. TrueType-teckensnitt med kerning och anti-aliasing (gör att text ser smooooooth ut) stöds också för attraktiv textåtergivning.

I varje fönster har du ett klientområde (ditt utrymme innanför gränsen och under det övre fältet). På detta kan du lägga till kontroller för att skapa en dialog eller så kan du använda det inbyggda grafikbiblioteket för att rita vad du vill. Alla grafikbibliotekets funktioner är fönstermedvetna. Du behöver inte oroa dig för var ditt fönster är, vad som överlappar det eller om det minimeras.

Förutom att skapa egna fönster finns det också några standarddialogrutor som är mycket enkla att instansera - till exempel bekräftelsedialogrutor (bara en OK- eller Ja/Nej -knapp), tids-/datuminställare, filväljare, färgväljare etc.

MiniWin använder ett vanligt Windows Manager -designmeddelandeskösystem. Windows kan interagera med varandra och fönsterhanteraren via meddelanden. Du ringer inte funktioner för att göra saker direkt, du lägger till ett meddelande i kön och fönsterhanteraren kommer att anta det åt dig.

MiniWin har portats till standardutvecklingskort med pekskärm från mikrokontrollleverantörerna ST, NXP och Renesas. Det finns hårdvarudrivrutiner och exempelprojekt för alla dessa enheter. Dessutom kan MiniWin byggas för Windows eller Linux så att du kan simulera din användargränssnittskod innan du får din inbäddade maskinvara.

MiniWin har en kodgenerator. Du kan ange dina fönster och kontroller i en enkelt att skapa en JSON -fil som är läsbar för män och kodgeneratorn analyserar filen och skapar koden åt dig (det finns många exempel att följa). Det skapar kompletta Windows- eller Linux -simulatorapplikationer som bara kan byggas och det finns din simulerade LCD -skärm med dina MiniWin -fönster som fungerar. Du kan ta exakt samma genererade kod och släppa den i ett inbäddat projekt och ha samma kod som visar samma fönster och kontroller ögonblick senare på din inbäddade maskinvara.

MiniWin kräver inget driftsstöd på den inbäddade enheten. Allt går i en enda tråd. MiniWin kan integreras med en RTOS som körs på en inbäddad processor och det finns exempel som integrerar MiniWin med FreeRTOS.

Denna instruerbara visar hur du får MiniWin igång på en STM32 M4 -processor med hjälp av det billiga STM32F429 Discovery -kortet som levereras med en QVGA -pekskärm som redan är ansluten. Dessa är lätt tillgängliga från din elektronikkomponentleverantör.

MiniWin körs på mellanstora mikrokontroller och högre.

Tillbehör

STM32F429I-DISC1 utvecklingskort och en mikro-USB-kabel

STM32CubeIDE nedladdning som är gratis.

Steg 1: Skaffa koden

Få koden
Få koden

Först och främst måste du installera STM32CubeIDE. Det får du från ST: s webbplats. Du måste registrera dig och det tar ett tag att ladda ner och installera det. Det är helt gratis.

Medan det installerar ladda ner MiniWin -källan och packa upp den. Det är stort, men du kommer bara att använda en liten del av det. Klicka på den gröna knappen "Klona eller ladda ner" här …

github.com/miniwinwm/miniwinwm

välj sedan Download Zip. Packa upp innehållet.

Steg 2: Bygga ett exempelprojekt

Bygga ett exempelprojekt
Bygga ett exempelprojekt
Bygga ett exempelprojekt
Bygga ett exempelprojekt

Låt oss först bygga ett av exempelprojekten. En bra heter MiniWinSimple. Starta STM32CubeIDE och gör sedan så här:

  1. Välj Arkiv | Importera …
  2. Öppna Allmänt och välj Existerande projekt till arbetsyta. Nästa.
  3. Klicka på Bläddra och navigera till var du packade upp MiniWin. Gå sedan till mappen STM32CubeIDE / MiniWinSimple / STM32F429. Klicka på Välj mapp.
  4. I projekt: kryssa i MiniWinSimple_STM32F429 och klicka sedan på Slutför.
  5. MiniWinSimple_STM32F429 -projektet visas i din Project Explorer. Välj det och bygg det sedan med Project | Build Project.
  6. Anslut nu din USB -kabel till kortet och datorn och kör den med Kör | Felsökning och välj Kör | Återuppta när den laddats ner. Du får en skärmkalibreringsdisplay första gången så rör vid mitten av de tre korsen på LCD -skärmen. Du kan nu interagera med fönstret på displayen.

Om du vill flytta ett fönster drar du det genom titelfältet. Om du vill ändra storlek på ett fönster använder du den vita triangelikonen till vänster om titelfältet. MiniWin -fönster kan inte ändras genom att dra gränserna eftersom skärmarna MiniWin används på är för små. För att minimera, maximera eller stänga ett fönster, använd ikonerna i högra änden av titelfältet (stäng kan vara inaktiverat). När ett fönster är minimerat kan du inte flytta de minimerade ikonerna. De bygger upp från nedre vänster till höger.

Steg 3: Kör kodgeneratorn

Kör kodgeneratorn
Kör kodgeneratorn

Nu kommer vi att ändra exempelprojektet genom att skapa några egna fönster och släppa in den nya koden. För att göra detta kör vi kodgeneratorn.

  1. Öppna en kommandotolk och gå till mappen där du packade upp MiniWin och sedan till Tools / CodeGen -mappen.
  2. Den körbara filen för Windows CodeGen.exe är redan tillgänglig. För Linux måste du bygga det genom att skriva make. (Du kan också bygga den från källan för Windows om du är orolig att köra en nedladdad körbar men du behöver installera kompilatorn och utvecklingsmiljön. Se MiniWin -dokumentationen i dokumentmappen för mer information).
  3. I den här mappen finns några exempel JSON -filer. Vi använder exempel_empty.json. Du måste redigera den först för att konfigurera den för Windows eller Linux. Öppna den i en redigerare och högst upp där du hittar "TargetType" ändra "Linux" eller "Windows" -värdet till vad du kör kodgeneratorn på.
  4. Skriv nu codegen example_empty.json i kommandotolken.
  5. Gå till ditt projekt i STM32CubeIDE och öppna mappen MiniWinSimple_Common. Ta bort alla filer där.
  6. Vi lämnade "TargetName" i JSON -filen som standard på "MiniWinGen" så det är namnet på vår mapp med genererad kod. Gå till mappen där du packade upp MiniWin och sedan MiniWinGen_Common -mappen. Välj nu alla dessa filer och dra och släpp sedan till STM32CubeIDE i projektets MiniWinSimple_Common -mapp.
  7. Bygg nu om och kör om projektet i STM32CubeIDE så visas ditt nya designfönster. Knappen i fönstret har gått eftersom exempel_empty.json inte definierar någon.

Steg 4: Lägga till ett fönster

Lägga till ett fönster
Lägga till ett fönster

Vi lägger nu till ett andra fönster i JSON -konfigurationsfilen och återskapar koden.

1. Öppna exempel_empty.json i en textredigerare.

2. Under avsnittet "Windows" finns det en rad Windows -definitioner som för närvarande bara har ett fönster. Kopiera allt detta …

{

"Namn": "W1", "Titel": "Fönster 1", "X": 10, "Y": 15, "Bredd": 200, "Höjd": 180, "Border": true, "TitleBar": true, "Visible": true, "Minimized": false}

och klistra in den igen med ett komma som skiljer de två definitionerna.

3. Ändra "W1" till "W2" och "Fönster 1" till "Fönster 2". Ändra "X", "Y", "Width" och "Height" till några olika värden med tanke på att skärmupplösningen är 240 bred vid 320 hög.

4. Spara filen och kör kodgeneratorn igen.

5. Kopiera filerna som i föregående steg, bygg om och kör om. Du kommer nu att ha två fönster på skärmen.

Steg 5: Lägga till en kontroll

Lägga till en kontroll
Lägga till en kontroll

Nu lägger vi till några kontroller i ditt nya fönster. Redigera samma fil som i föregående steg.

1. I specifikationen för fönster W1 lägger du till ett komma efter den sista inställningen ("Minimerad": falsk) och lägg sedan till den här texten

"Menyrad": sant, "MenuBarEnabled": true, "MenuItems": ["Fred", "Bert", "Pete", "Alf", "Ian"], "Buttons": [{"Name": "B1", "Label": "Button1", "X": 10, "Y": 10, "Enabled": true, "Synlig": true}]

Det här avsnittet lägger till en menyrad med 5 objekt och aktiverar den (menyrader kan vara inaktiverade globalt, prova det). Det lägger också till en knapp som är aktiverad och synlig (de kan skapas osynliga och sedan göras synliga i koden senare).

2. Återskapa koden, kopiera den över, bygg om, kör om allt som tidigare.

Steg 6: Få kontrollerna att göra något

Att få kontrollerna att göra något
Att få kontrollerna att göra något

Nu har vi det grundläggande användargränssnittet vi behöver för att få det att göra något. I det här exemplet dyker vi upp en färgväljardialogruta när knappen i fönster 1 trycks in.

Gå till ditt projekt i STM32CubeIDE och öppna MiniWinSimple_Common -mappen och öppna sedan filen W1.c (namnet på den här filen motsvarar fönstret "Namn" -fältet i JSON -filen när koden genererades).

I den här filen hittar du funktionen window_W1_message_function (). Det ser ut så här:

void window_W1_message_function (const mw_message_t *meddelande) {MW_ASSERT (meddelande! = (void *) 0, "Null pekar parameter"); / * Nästa rad stoppar kompilatorvarningar eftersom variabeln för närvarande är oanvänd */ (void) window_W1_data; switch (meddelande-> meddelande_id) {case MW_WINDOW_CREATED_MESSAGE: / * Lägg till valfri fönsterinitieringskod här * / break; fall MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Lägg till fönster menyhanteringskod här * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) { / * Lägg till din hanterarkod för denna kontroll här * /} break; standard: / * Håll MISRA glad * / paus; }}

Detta kallas av fönsterhanteraren för det här fönstret när fönsterhanteraren behöver meddela fönstret att något har hänt. I det här fallet är vi intresserade av att veta att fönsterets enda knapp har tryckts in. I switch -satsen för meddelandetyper ser du ett fall för MW_BUTTON_PRESSED_MESSAGE. Denna kod körs när knappen har tryckts in. Det finns bara en knapp i det här fönstret, men det kan finnas fler, så det kontrolleras vilken knapp det är. I det här fallet kan det bara vara knapp B1 (namnet motsvarar namnet på knappen i JSON -filen igen).

Så efter denna etikett lägger du till koden för att dyka upp en färgväljardialogruta, vilket är detta:

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

Parametrarna är följande:

  • 10, 10 är platsen på dialogrutans skärm
  • "Färg" är dialogens titel
  • MW_HAL_LCD_RED är standardfärgen som dialogrutan börjar med
  • falska medel visar inte stor storlek (försök att ställa in det till sant och se skillnaden)
  • meddelande-> mottagarhandtag är vem som äger den här dialogrutan, i det här fallet är det det här fönstret. Ett fönsters handtag finns i funktionens meddelandeparameter. Detta är fönstret som dialogrutan kommer att skickas till.

För att ta reda på värdet på färgen som användaren valde skickar fönsterhanteraren ett meddelande till fönstret med den valda färgen när användaren trycker på OK -knappen i dialogrutan. Därför måste vi också fånga upp detta meddelande med ett annat fall i switch -uttalandet som ser ut så här:

fall MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{mw_hal_lcd_colour_t selected_colour = meddelande-> meddelande_data; (void) vald_färg; } ha sönder;

Vi gör inget med den valda färgen ännu, så bara kasta bort det för att förhindra en kompilatorvarning. Den slutliga koden för denna funktion ser nu ut så här:

void window_W1_message_function (const mw_message_t *meddelande)

{MW_ASSERT (meddelande! = (Void*) 0, "Nullpekarparameter"); / * Nästa rad stoppar kompilatorvarningar eftersom variabeln för närvarande är oanvänd */ (void) window_W1_data; switch (meddelande-> meddelande_id) {case MW_WINDOW_CREATED_MESSAGE: / * Lägg till valfri fönsterinitieringskod här * / break; fall MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Lägg till fönster menyhanteringskod här * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) { / * Lägg till din hanterarkod för denna kontroll här * / mw_create_window_dialog_colour_chooser (10, 10, "Color", MW_HAL_LCD_RED, false, message-> recipient_) } ha sönder; fall MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {mw_hal_lcd_colour_t selected_colour = meddelande-> meddelande_data; (void) vald_färg; } ha sönder; standard: / * Håll MISRA glad * / paus; }}

Körning av koden visas i bilden ovan. Du kanske märker att när en dialogruta visas måste du svara på den och avfärda den innan du gör något annat. Detta kallas modalt beteende. Dialoger i MiniWin och alla alltid globalt modala och du kan bara ha en visning i taget. Det finns mer förklaring här …

en.wikipedia.org/wiki/Modal_window

Steg 7: Rita i fönstret

Rita i fönstret
Rita i fönstret

Hittills har vi bara använt kontroller, och de ritar sig själva. Det är dags att göra en anpassad ritning på vårt fönster. Den del du kan rita på är inuti gränserna (om de är några är de valfria), inuti rullningslisterna (om den är definierad, även valfri) och under rubriken (om det finns en, är det också valfritt). Det kallas klientområdet i fönsterterminologi.

Det finns ett bibliotek med grafikkommandon i MiniWin som du kan använda. De är alla medvetna om fönstret. Det betyder att du inte behöver oroa dig för om fönstret är synligt, delvis skymt av andra fönster, på, delvis av eller helt utanför skärmen, eller om koordinaten för var du ritar är på klientområdet eller bortom det. Allt är omhändertaget för dig. Du kan inte rita utanför ditt klientområde.

Att rita på klientområden i Windows -terminologi kallas målning och varje fönster har en färgfunktion där du ritar. Du kallar inte din färgfunktion, fönsterhanteraren gör det åt dig när det behövs. Det behövs när ett fönster flyttas eller ett annat fönster ovanför har sin position eller synlighet ändrad. Om du behöver måla om ditt fönster eftersom vissa av de data som fönstrets innehåll är beroende av har ändrats (dvs du vet att en ommålning krävs snarare än att fönsterhanteraren vet), säger du till fönsterhanteraren att en ommålning behövs och den ringer din färgfunktion. Du kallar det inte själv. (Allt detta visas i nästa avsnitt).

Först måste du hitta din färgfunktion. Kodgeneratorn skapar den åt dig och den ligger precis ovanför meddelandehanteringsfunktionen som modifierades i föregående avsnitt. Gå till ditt projekt och öppna filen W1.c igen.

I den här filen hittar du funktionen window_W1_paint_function (). Det ser ut så här:

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 pekar parameter"); / * Fyll fönstrets klientområde med fast vitt */ 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); / * Lägg till fönstermålningskoden här */}

Detta är den bara som genererade koden och allt det gör är att fylla klientområdet med fast vitt. Låt oss rita en gul fylld cirkel på klientområdet. Först måste vi förstå konceptet med ett grafiskt sammanhang (en annan Windows -sak). Vi ställer in ritningsparametrar i det grafiska sammanhanget och kallar sedan en generell cirkelritningsrutin. Saker vi måste ställa in i det här exemplet är om cirkeln har en kant, kantlinjestil, kantfärg, om cirkeln är fylld, fyllningsfärg och fyllningsmönster. Du kan se koden ovan som gör något liknande för att fylla klientområdet med en kantlös, fylld vit rektangel. Värdena i det grafiska sammanhanget kommer inte ihåg mellan varje samtal i färgfunktionen, så du måste ställa in värdena varje gång (de kommer ihåg med färgfunktionen dock).

I koden ovan kan du se att fyllning är på och fyllningsmönster är avstängd, så vi behöver inte ställa in dem igen. Vi måste ställa in gränsen på, kantlinjestil till fast, kantgrundsfärg till svart och fylla färg till gult så här:

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

Lägg till den här koden vid kommentaren i den här funktionen där det står att lägga till din kod. Därefter måste vi rita en cirkel som görs så här:

mw_gl_circle (draw_info, 30, 30, 15);

Detta ritar en cirkel vid koordinaterna 30, 30 med radie 15. Bygg om koden och kör den igen så ser du en cirkel i fönstret som visas ovan. Du kommer att märka att cirkeln och knappen överlappar varandra men knappen är överst. Detta är av design. Kontroller är alltid ovanpå allt du drar på klientområdet.

Steg 8: Fönstredata

Fönsterdata
Fönsterdata

Hittills har vi implementerat vår egen kod i fönster 1: s meddelandefunktion (för att hantera inkommande meddelanden) och dess färgfunktion (för att rita på fönsterets klientområde). Nu är det dags att länka de två. Låt oss fylla cirkeln som ritas i färgfunktionen med den färg som användaren väljer av färgväljaren när knappen trycktes in. Kom ihåg att vi inte kallar färgfunktionen, fönsterhanteraren gör det, så vår meddelandefunktion (som känner till den valda färgen) kan inte ringa färgfunktionen direkt själv. Istället måste vi cacha data och låta fönsterhanteraren veta att en ommålning krävs. Fönsterhanteraren ringer sedan till paint -funktionen som kan använda cachade data.

Högst upp på W1.c ser du en tom datastruktur och ett objekt av denna typ som deklareras av kodgeneratorn så här:

typedef struct

{ / * Lägg till dina data medlemmar här * / char dummy; /* Vissa kompilatorer klagar på tomma strukturer; ta bort detta när du lägger till dina medlemmar */} window_W1_data_t; statisk fönster_W1_data_t fönster_W1_data;

Det är här vi cachar våra data så att de bevaras över samtal och kallas fönsterdata. Vi behöver bara lagra den valda färgen här, så här:

typedef struct

{ / * Lägg till dina datamedlemmar här * / mw_hal_lcd_colour_t selected_colour; } fönster_W1_data_t; statisk fönster_W1_data_t fönster_W1_data = {MW_HAL_LCD_YELLOW};

Vi ger den en startfärg av gult. Nu i meddelandefunktionen ändrar vi koden något för att spara den valda färgen här så här:

fall MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{window_W1_data.chosen_colour = meddelande-> meddelande_data; } ha sönder;

Sedan ändrar vi färgfunktionen för att använda det här värdet när det ritar cirkeln så här:

mw_gl_set_solid_fill_colour (fönster_W1_data.val_färg);

Nu har vi ändrat de data som innehållet i fönstret beror på, så vi måste låta fönsterhanteraren veta att fönstret behöver målas om. Vi gör det i meddelandefunktionen när OK -meddelandet i dialogrutan tas emot, så här:

mw_paint_window_client (meddelande-> mottagarhandtag);

Detta gör inte att fönstret målas direkt. Det är en verktygsfunktion som skickar ett meddelande till fönsterhanteraren om att ett fönster måste målas om (om du går in i det kan du se hur detta händer). Fönstret som måste målas om i detta fall är sig själv, och handtaget till fönstret finns i meddelandeparametern till meddelandehanteringsfunktionen.

Hela filen ser nu ut så här om du är osäker på var några av kodavsnitten ovan tar vägen:

#omfatta

#include "miniwin.h" #include "miniwin_user.h" #include "W1.h" typedef struct { / * Lägg till dina datamedlemmar här * / mw_hal_lcd_colour_t vald_färg; } fönster_W1_data_t; statisk fönster_W1_data_t fönster_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 pekar parameter"); / * Fyll fönstrets klientområde med fast vitt */ 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); / * Lägg till fönstermålningskoden här */ mw_gl_set_fg_colour (MW_HAL_LCD_BLACK); mw_gl_set_solid_fill_colour (fönster_W1_data.val_färg); 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 *meddelande) {MW_ASSERT (meddelande! = (void *) 0, "Null pekar parameter"); / * Nästa rad stoppar kompilatorvarningar eftersom variabeln för närvarande är oanvänd */ (void) window_W1_data; switch (meddelande-> meddelande_id) {case MW_WINDOW_CREATED_MESSAGE: / * Lägg till valfri fönsterinitieringskod här * / break; fall MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Lägg till fönster menyhanteringskod här * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) { / * Lägg till din hanterarkod för denna kontroll här * / mw_create_window_dialog_colour_chooser (10, 10, "Color", MW_HAL_LCD_RED, false, message-> recipient_) } ha sönder; fall MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {window_W1_data.chosen_colour = meddelande-> meddelande_data; mw_paint_window_client (meddelande-> mottagarhandtag); } ha sönder; standard: / * Håll MISRA glad * / paus; }}

Bygg och kör igen och du bör kunna ställa in fyllningsfärgen på cirkeln.

Detta exempel på fönsterdata använder data som lagras i en statisk datastruktur längst upp i källfilen. Det här är bra om du bara har en instans av fönstret, som vi gör i det här exemplet, men om du har mer än en instans delar de alla samma datastruktur. Det är möjligt att ha per-instansdata så att flera instanser av samma fönstertyp har sina egna data. Detta förklaras i MiniWin -dokumentationen i dokumentkatalogen. Filexemplet använder den för att visa flera bilder i samma fönstertyp (så som den visas i huvudbilden högst upp i denna instruerbara).

Steg 9: Lite kul teckensnitt

Lite kul teckensnitt
Lite kul teckensnitt

MiniWin stöder TrueType -tolkning. Om det är något som får ditt användargränssnitt att se bra ut är det attraktiva teckensnitt. Det här sista steget visar hur du gör ett TrueType -teckensnitt i ett MiniWin -fönster.

Det finns två sätt att återge TrueType -teckensnitt. Det ena är att rita dem direkt på ditt klientområde som gjordes för cirkeln tidigare, det andra är att lägga till en textruta kontroll i ditt fönster. Vi gör det senare eftersom det är lättare.

Nu lägger vi till en textruta -kontroll i vår JSON -konfigurationsfil. Lägg till det i fönster 2: s definition så att det ser ut så här:

så här:

{

"Namn": "W2", "Titel": "Fönster 2", "X": 50, "Y": 65, "Bredd": 100, "Höjd": 80, "Border": true, "TitleBar": true, "Visible": true, "Minimized": false, "TextBoxes": [{"Name": "TB1", "X": 0, "Y": 0, "Width": 115, "Height": 50, "Motivering": "Center", "BackgroundColour": "MW_HAL_LCD_YELLOW", "ForegroundColour": "MW_HAL_LCD_BLACK", "Font": "mf_rlefont_BLKCHCRY16", "Enabled": true, "Visible": true}]}}

Ett snabbt ord om TrueType -teckensnitt i MiniWin. Teckensnitt finns i.ttf -filer. I fönsterhanterare på större datorer återges dessa på din skärm när de behövs. Detta tar mycket processorkraft och minne och är inte lämpligt för små enheter. I MiniWin förbehandlas de till bitmappar och länkas vid kompileringstid med en fast teckenstorlek och stil (fetstil, kursiv etc) dvs du måste bestämma vilka teckensnitt med vilken storlek och stil du ska använda vid kompileringstidpunkten. Detta har gjorts åt dig för två exempel på teckensnitt i MiniWin zip -filen som du laddade ner. Om du vill använda andra teckensnitt i andra storlekar och stilar, se MiniWin -dokumentationen i dokumentmappen. Det finns verktyg i MiniWin för Windows och Linux för förbehandling av.ttf-filer till källkodfiler som du kan släppa in i ditt projekt.

Och ett andra snabbord - de flesta teckensnitt är upphovsrättsliga, inklusive de du hittar i Microsoft Windows. Använd dem efter behag för personligt bruk, men allt du publicerar måste du se till att licensen teckensnitt publiceras med tillåter det, som är fallet för de två teckensnitt som ingår i MiniWin, men inte Microsofts teckensnitt!

Tillbaka till koden! Generera, släpp filer, bygg och kör på nytt som tidigare och du kommer att se att fönster 2 nu har lite standardtext på en gul bakgrund i ett galet teckensnitt. Låt oss ändra texten genom att redigera Window 2: s källfil W2.c.

Vi måste kommunicera med textrutan som vi just skapat och hur du gör det som med all kommunikation i MiniWin är att skicka ett meddelande. Vi vill ange texten i kontrollen när fönstret skapas men innan det visas, så vi lägger till kod i meddelandehanteraren i fallet MW_WINDOW_CREATED_MESSAGE. Detta tas emot av fönsterkoden strax innan fönstret visas och är avsett för initialiseringar som detta. Kodgeneratorn skapade en platshållare som ser ut så här i meddelandehanteringsfunktionen:

fall MW_WINDOW_CREATED_MESSAGE:

/ * Lägg till valfri fönsterinitieringskod här */ break;

Här kommer vi att lägga upp ett meddelande till textrutans kontroll som berättar vilken text vi vill att den ska visa med hjälp av funktionen mw_post_message så här:

fall MW_WINDOW_CREATED_MESSAGE:

/ * Lägg till valfri fönsterinitieringskod här */ 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); ha sönder;

Detta är parametrarna:

  • MW_TEXT_BOX_SET_TEXT_MESSAGE - Detta är den meddelandetyp vi skickar till kontrollen. De listas i miniwin.h och dokumenteras i dokumentationen.
  • meddelande-> mottagarhandtag - Det är vem meddelandet kommer från - det här fönstret - vars handtag finns i meddelandeparametern som skickas till meddelandehanteringsfunktionen.
  • text_box_TB1_handle - Vem vi skickar meddelandet till - handtaget på textrutans kontroll. Dessa listas i den genererade filen miniwin_user.h.
  • 0UL - Datavärde, ingenting i det här fallet.
  • "Var en mörk och stormig natt …" - Pekarvärde - den nya texten.
  • MW_CONTROL_MESSAGE - Mottagartyp som är en kontroll.

Det är allt. Bygg om och kör om som vanligt så får du textrutan som visas på bilden ovan.

Meddelandepostering är grundläggande för MiniWin (som det är för alla fönsterhanterare). För fler exempel, se exempelprojekten i zip -filen och för en omfattande förklaring läs avsnittet om MiniWin -meddelanden i dokumentationen.

Steg 10: Gå vidare

Image
Image

Det är det för denna grundläggande introduktion till MiniWin. MiniWin kan mycket mer än vad som har visats här. Till exempel är skärmen på tavlan som används i denna instruerbara liten och kontrollerna små och måste användas med en dibber. Andra exempel och hårdvara använder dock större kontroller (det finns 2 storlekar) på större skärmar och dessa kan manövreras med fingrar.

Det finns många andra typer av kontroll än de som visas här. För ytterligare kontroller, ta en titt på de olika exemplen JSON -filer i kodgeneratormappen. Alla kontrolltyper omfattas av dessa exempel.

Windows har många alternativ. Gränsen, titelfältet och ikonerna är alla konfigurerbara. Du kan ha rullningslister och rullningsfönsterklientområden, flera instanser av samma fönstertyp och fönster kan vara nakna (endast ett klientområde, ingen kant eller titelrad) vilket innebär att de fixas vid kompileringstid på displayen (se bilden i det här avsnittet med stora ikoner - det här är faktiskt 6 nakna fönster).

MiniWin använder inget dynamiskt minne. Detta gör den lämplig för små begränsade enheter och är ett krav för vissa inbäddade projekt. MiniWin och koden som den genererar är också helt MISRA 2012 -kompatibla till den "erforderliga" nivån.

För mer information, titta i dokumentmappen för dokumentationen och även de andra exempelapparna i zip -filen. Det finns exempel här som visar hur du använder alla funktioner i MiniWin och hur du integrerar MiniWin med FatFS och FreeRTOS.

Rekommenderad: