Cuprins:

Manager ferestre încorporate: 10 pași
Manager ferestre încorporate: 10 pași

Video: Manager ferestre încorporate: 10 pași

Video: Manager ferestre încorporate: 10 pași
Video: Începe O Agenție de SMM (SMMA) In 10 Pași Simpli În 2023 *pentru începători* 2024, Noiembrie
Anonim
Manager ferestre încorporate
Manager ferestre încorporate
Manager ferestre încorporate
Manager ferestre încorporate
Manager ferestre încorporate
Manager ferestre încorporate
Manager ferestre încorporate
Manager ferestre încorporate

Acest proiect arată cum să implementați un manager de ferestre cu ferestre mobile suprapuse pe un microcontroler încorporat cu un panou LCD și un ecran tactil. Există pachete software disponibile în comerț pentru a face acest lucru, dar costă bani și sunt sursă închisă. Acesta, numit MiniWin, este gratuit și open-source. Este scris în C99 complet conform și poate fi utilizat într-o aplicație C sau C ++. Obiectivele MiniWin sunt de a fi ușor de utilizat, ușor de modificat, extensibil, portabil pentru o gamă largă de hardware și nu prea înfometate de resurse.

Pe lângă furnizarea codului pentru gestionarea ferestrelor dvs. MiniWin are o colecție de controale ale interfeței utilizatorului - butoane, glisoare, bare de progres, copaci etc. Puteți avea mai multe ferestre de diferite tipuri sau instanțe multiple de același tip. Ferestrele pot fi mutate, redimensionate, maximizate, reduse la minimum, închise - toate lucrurile obișnuite pe care le faceți cu ferestrele în managerii de ferestre mai mari. Fonturile TrueType cu kerning și anti-aliasing (fac ca textul să pară smooooooth) sunt, de asemenea, acceptate pentru redarea textului atractivă.

În fiecare fereastră aveți o zonă client (spațiul dvs. în interiorul chenarului și sub bara de sus). Pe aceasta puteți adăuga controale pentru a crea un dialog sau puteți utiliza biblioteca grafică încorporată pentru a desena orice doriți. Toate funcțiile bibliotecii grafice sunt conștiente de ferestre. Nu trebuie să vă faceți griji cu privire la locul unde este fereastra dvs., ce se suprapune sau dacă este minimizată.

Pe lângă crearea propriilor ferestre, există și câteva dialoguri standard, care sunt foarte ușor de instanțiat - de exemplu, dialoguri de confirmare (doar un buton OK sau Da / Nu), setatoare de timp / dată, selectoare de fișiere, selectoare de culoare etc.

MiniWin utilizează un sistem de coadă de mesaje standard pentru proiectarea managerului Windows. Windows poate interacționa între ele și managerul de ferestre prin mesaje. Nu apelați funcții pentru a face lucrurile direct, adăugați un mesaj la coadă și managerul de ferestre îl va promova.

MiniWin a fost portat pe plăci de dezvoltare standard cu afișaje pe ecran tactil de la furnizorii de microcontrolere ST, NXP și Renesas. Există drivere hardware și exemple de proiecte pentru toate aceste dispozitive. În plus, MiniWin poate fi construit pentru Windows sau Linux, astfel încât să puteți simula codul interfeței dvs. de utilizator înainte de a obține hardware-ul încorporat.

MiniWin are un generator de cod. Puteți specifica ferestrele și comenzile într-un fișier JSON ușor de citit de către om, iar generatorul de cod analizează fișierul și creează codul pentru dvs. (există o mulțime de exemple de urmat). Creează aplicații de simulare complete pentru Windows sau Linux, care pot fi construite și există afișajul LCD simulat cu ferestrele MiniWin funcționale. Puteți să luați exact același cod generat și să-l introduceți într-un proiect încorporat și să aveți același cod care să arate aceleași ferestre și să controleze câteva momente mai târziu pe hardware-ul dvs. încorporat.

MiniWin nu necesită suport de operare pe dispozitivul încorporat. Totul rulează într-un singur fir. MiniWin poate fi integrat cu un RTOS care rulează pe un procesor încorporat și există exemple de integrare a MiniWin cu FreeRTOS.

Această instrucțiune arată cum să funcționeze MiniWin pe un procesor STM32 M4 folosind placa ieftină STM32F429 Discovery care vine cu un ecran tactil QVGA deja atașat. Acestea sunt ușor disponibile de la furnizorul dvs. de componente electronice.

MiniWin rulează pe microcontrolere mid-range și peste.

Provizii

Placă de dezvoltare STM32F429I-DISC1 și un cablu micro USB

Descărcare STM32CubeIDE care este gratuită.

Pasul 1: Obținerea codului

Obținerea codului
Obținerea codului

Mai întâi de toate aveți nevoie de STM32CubeIDE instalat. Primiți asta de pe site-ul ST. Trebuie să vă înregistrați și durează ceva timp să îl descărcați și să îl instalați. Totul este gratuit.

În timp ce se instalează, descărcați sursa MiniWin și dezarhivați-o. Este mare, dar veți folosi doar o mică parte din acesta. Faceți clic aici pe butonul verde „Clonează sau Descarcă” …

github.com/miniwinwm/miniwinwm

apoi alegeți Descărcați Zip. Dezarhivați conținutul.

Pasul 2: Construirea unui exemplu de proiect

Construirea unui exemplu de proiect
Construirea unui exemplu de proiect
Construirea unui exemplu de proiect
Construirea unui exemplu de proiect

Mai întâi să construim unul dintre exemplele de proiecte. Unul bun se numește MiniWinSimple. Porniți STM32CubeIDE apoi faceți acest lucru:

  1. Alegeți Fișier | Importați …
  2. Deschideți General și alegeți Proiect existent în spațiul de lucru. Următorul.
  3. Faceți clic pe Răsfoiți și navigați până unde ați dezarhivat MiniWin. Apoi accesați folderul STM32CubeIDE / MiniWinSimple / STM32F429. Faceți clic pe Selectare folder.
  4. În Proiect: bifați MiniWinSimple_STM32F429 apoi faceți clic pe Finalizare.
  5. Proiectul MiniWinSimple_STM32F429 va apărea în Project Explorer. Selectați-l, apoi creați-l cu Project | Build Project.
  6. Acum conectați cablul USB la placă și la computer și rulați-l folosind Run | Debug și atunci când este descărcat, alegeți Run | Reluați. Veți primi un afișaj de calibrare a ecranului prima dată, așa că atingeți centrul celor 3 cruci de pe ecranul LCD. Acum puteți interacționa cu fereastra de pe ecran.

Pentru a muta o fereastră, trageți-o de bara de titlu. Pentru a redimensiona o fereastră, utilizați pictograma triunghi alb din stânga barei de titlu. Ferestrele MiniWin nu pot fi redimensionate prin glisarea marginilor, deoarece afișajele folosite MiniWin sunt prea mici. Pentru a minimiza, maximiza sau închide o fereastră, utilizați pictogramele din partea dreaptă a barei de titlu (închiderea poate fi dezactivată). Când o fereastră este minimizată, nu puteți muta pictogramele minimizate în jur. Se acumulează de jos în stânga în dreapta.

Pasul 3: Rularea generatorului de cod

Rularea generatorului de cod
Rularea generatorului de cod

Acum vom schimba exemplul de proiect prin generarea unor ferestre proprii și introducerea noului cod. Pentru a face acest lucru, vom rula generatorul de cod.

  1. Deschideți un prompt de comandă și mergeți la folderul în care ați dezarhivat MiniWin și apoi la folderul Tools / CodeGen.
  2. Executabilul pentru Windows CodeGen.exe este deja disponibil. Pentru Linux trebuie să îl construiți tastând make. (Puteți să-l construiți și din sursă pentru Windows dacă vă faceți griji să rulați un executabil descărcat, dar aveți nevoie de compilatorul și mediul de dezvoltare instalat. Consultați documentația MiniWin din folderul docs pentru detalii).
  3. În acest folder sunt câteva exemple de fișiere JSON. Vom folosi example_empty.json. Trebuie mai întâi să îl editați pentru a-l configura pentru Windows sau Linux. Deschideți-l într-un editor și în partea de sus, unde veți găsi „TargetType”, schimbați valoarea „Linux” sau „Windows” pe ceea ce executați generatorul de cod.
  4. Acum tastați codegen example_empty.json în promptul de comandă.
  5. Mergeți la proiectul dvs. în STM32CubeIDE și deschideți folderul MiniWinSimple_Common. Ștergeți toate fișierele de acolo.
  6. Am lăsat „TargetName” în fișierul JSON ca implicit la „MiniWinGen”, deci acesta este numele folderului nostru de cod generat. Accesați folderul în care ați dezarhivat MiniWin și apoi folderul MiniWinGen_Common. Acum selectați toate aceste fișiere și glisați și fixați apoi în STM32CubeIDE în folderul MiniWinSimple_Common al proiectului dumneavoastră.
  7. Acum reconstruiți și rulați din nou proiectul în STM32CubeIDE și va apărea noua fereastră de proiectare. Butonul din fereastră a dispărut deoarece example_empty.json nu definește niciunul.

Pasul 4: Adăugarea unei ferestre

Adăugarea unei ferestre
Adăugarea unei ferestre

Acum vom adăuga o a doua fereastră la fișierul de configurare JSON și vom regenera codul.

1. Deschideți example_empty.json într-un editor de text.

2. Sub secțiunea „Windows” există o serie de definiții Windows care în prezent are o singură fereastră. Copiază toate acestea …

{

"Name": "W1", "Title": "Window 1", "X": 10, "Y": 15, "Width": 200, "Height": 180, "Border": true, "TitleBar": adevărat, „Vizibil”: adevărat, „Minimizat”: fals}

și lipiți-l din nou cu o virgulă care separă cele 2 definiții.

3. Schimbați „W1” la „W2” și „Fereastra 1” la „Fereastra 2”. Schimbați „X”, „Y”, „Lățime” și „Înălțime” la unele valori diferite ținând cont de rezoluția ecranului de 240 lățime pe 320 înălțime.

4. Salvați fișierul și rulați din nou generatorul de cod.

5. Copiați fișierele ca la pasul anterior, reconstruiți și reluați. Acum veți avea 2 ferestre pe ecran.

Pasul 5: Adăugarea unui control

Adăugarea unui control
Adăugarea unui control

Acum vom adăuga câteva controale la noua fereastră. Editați același fișier ca la pasul anterior.

1. În specificația pentru fereastra W1 adăugați o virgulă după ultima setare („Minimizat”: fals) apoi adăugați acest text

„MenuBar”: adevărat, "MenuBarEnabled": adevărat, "MenuItems": ["Fred", "Bert", "Pete", "Alf", "Ian"], "Buttons": [{"Name": "B1", "Label": „Buton1”, „X”: 10, „Y”: 10, „Activat”: adevărat, „Vizibil”: adevărat}]

Această secțiune adaugă o bară de meniu cu 5 elemente și o activează (barele de meniu pot fi dezactivate la nivel global, încercați). De asemenea, adaugă un buton care este activat și vizibil (pot fi create invizibile și apoi vizibile în cod ulterior).

2. Regenerați codul, copiați-l în întregime, reconstruiți, reluați totul ca înainte.

Pasul 6: Efectuarea comenzilor să facă ceva

Făcând comenzile să facă ceva
Făcând comenzile să facă ceva

Acum avem interfața de bază de care avem nevoie pentru a o face să facă ceva. Pentru acest exemplu, vom afișa un dialog de selectare a culorilor atunci când butonul din fereastra 1 este apăsat.

Mergeți la proiectul dvs. în STM32CubeIDE și deschideți folderul MiniWinSimple_Common și apoi deschideți fișierul W1.c (numele acestui fișier corespunde câmpului "Nume" al ferestrei în fișierul JSON când a fost generat codul).

În acest fișier veți găsi funcția window_W1_message_function (). Arată așa:

void window_W1_message_function (const mw_message_t * message) {MW_ASSERT (message! = (void *) 0, "Null pointer parameter"); / * Linia următoare oprește avertismentele compilatorului, deoarece variabila este în prezent neutilizată * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Adăugați aici orice cod de inițializare a ferestrei * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Adăugați aici codul de gestionare a meniului ferestrei * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Adăugați codul de gestionare pentru acest control aici * /} pauză; implicit: / * Păstrează MISRA fericit * / pauză; }}

Acest lucru este apelat de managerul de ferestre pentru această fereastră ori de câte ori managerul de ferestre trebuie să anunțe fereastra că sa întâmplat ceva. În acest caz, suntem interesați să știm că singurul buton al ferestrei a fost apăsat. În declarația de comutare pentru tipurile de mesaje, veți vedea un caz pentru MW_BUTTON_PRESSED_MESSAGE. Acest cod rulează când butonul a fost apăsat. Există doar un singur buton în această fereastră, dar ar putea fi mai multe, deci se verifică ce buton este. În acest caz, ar putea fi doar butonul B1 (numele corespunde cu numele butonului din fișierul JSON din nou).

Deci, după această etichetă de caz, adăugați codul pentru a afișa un dialog de selectare a culorilor, care este acesta:

mw_create_window_dialog_colour_chooser (10, 10, "Culoare", MW_HAL_LCD_RED, fals, mesaj-> destinatar_handle);

Parametrii sunt după cum urmează:

  • 10, 10 este locația de pe ecranul casetei de dialog
  • „Culoare” este titlul dialogului
  • MW_HAL_LCD_RED este culoarea implicită cu care va începe dialogul
  • false înseamnă că nu arată dimensiuni mari (încercați să o setați la adevărat și vedeți diferența)
  • mesaj-> handle-ul destinatarului este cel care deține acest dialog, în acest caz este această fereastră. Mânerul unei ferestre se află în parametrul mesajului funcției. Aceasta este fereastra către care va fi trimis răspunsul de dialog.

Pentru a afla valoarea culorii pe care utilizatorul a ales-o, managerul de ferestre va trimite ferestrei noastre un mesaj cu culoarea aleasă atunci când utilizatorul apasă butonul OK din dialog. Prin urmare, trebuie să interceptăm și acest mesaj cu un alt caz în declarația switch care arată astfel:

cazul MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{mw_hal_lcd_colour_t selected_colour = message-> message_data; (nul) culoare_aleasă; } pauză;

Încă nu facem nimic cu culoarea aleasă, așa că aruncăm-o în gol pentru a preveni un avertisment al compilatorului. Codul final al acestei funcții arată acum:

void window_W1_message_function (const mw_message_t * message)

{MW_ASSERT (mesaj! = (Void *) 0, "Parametru indicator nul"); / * Linia următoare oprește avertismentele compilatorului, deoarece variabila este în prezent neutilizată * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Adăugați aici orice cod de inițializare a ferestrei * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Adăugați aici codul de gestionare a meniului ferestrei * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Adăugați codul de gestionare pentru acest control aici * / mw_create_window_dialog_colour_chooser (10, 10, "Color", MW_HAL_LCD_RED, false, message-> recipient_hand) } pauză; caz MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {mw_hal_lcd_colour_t selected_colour = message-> message_data; (nul) culoare_aleasă; } pauză; implicit: / * Păstrează MISRA fericit * / pauză; }}

Rularea codului este afișată în imaginea de mai sus. S-ar putea să observați că atunci când se afișează un dialog trebuie să răspundeți la acesta și să îl respingeți înainte de a face orice altceva. Aceasta se numește comportament modal. Dialogurile în MiniWin și toate sunt întotdeauna modale la nivel global și puteți avea o singură afișare la un moment dat. Există mai multe explicații aici …

en.wikipedia.org/wiki/Modal_window

Pasul 7: Desen în fereastră

Desen în fereastră
Desen în fereastră

Până acum am folosit doar comenzi, iar acestea se desenează singure. Este timpul să facem câteva desene personalizate pe fereastra noastră. Partea pe care o puteți desena se află în interiorul chenarelor (dacă există, sunt opționale), în interiorul barelor de defilare (dacă este definit, de asemenea, opțional) și sub bara de titlu (dacă există una, și asta este opțional). Se numește zona clientului în terminologia ferestrei.

Există o bibliotecă de comenzi grafice în MiniWin pe care o puteți utiliza. Toți sunt conștienți de fereastră. Asta înseamnă că nu trebuie să vă faceți griji dacă fereastra este vizibilă, parțial ascunsă de alte ferestre, pornită, parțial oprită sau complet de pe ecran, sau dacă coordonata locului în care desenați este în zona clientului sau dincolo de aceasta. Totul este îngrijit pentru tine. Nu puteți desena în afara zonei clientului.

Desenarea pe zonele client în terminologia Windows se numește pictură și fiecare fereastră are o funcție de vopsire în care faceți desenul. Nu vă apelați funcția de vopsire, managerul de ferestre o face pentru dvs. atunci când este necesar. Este necesar atunci când o fereastră este mutată sau o altă fereastră de deasupra își schimbă poziția sau vizibilitatea. Dacă aveți nevoie de revopsirea ferestrei, deoarece unele dintre datele de care depinde conținutul ferestrei s-au schimbat (adică știți că este necesară o repictare mai degrabă decât știind managerul de ferestre), atunci spuneți managerului de ferestre că este nevoie de o revopsire și sună funcția dvs. de vopsea. Nu o numiți singur. (Acest lucru este demonstrat în secțiunea următoare).

În primul rând, trebuie să vă găsiți funcția de vopsire. Generatorul de cod îl creează pentru dvs. și este chiar deasupra funcției de gestionare a mesajelor modificată în secțiunea anterioară. Mergeți la proiectul dvs. și deschideți din nou fișierul W1.c.

În acest fișier veți găsi funcția window_W1_paint_function (). Arată așa:

void window_W1_paint_function (mw_handle_t window_handle, const mw_gl_draw_info_t * draw_info)

{MW_ASSERT (draw_info! = (Void *) 0, "Parametru indicator nul"); / * Umpleți zona clientului ferestrei cu alb solid * / 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); / * Adăugați aici codul pentru pictura ferestrei * /}

Acesta este codul generat ca generat și tot ce face este să umple zona clientului cu alb solid. Să desenăm un cerc plin de culoare galbenă pe zona clientului. Mai întâi trebuie să înțelegem conceptul unui context grafic (un alt lucru cu Windows). Setăm parametrii de desen în contextul grafic și apelăm apoi la o rutină de desenare a cercurilor generică. Lucrurile pe care trebuie să le stabilim în acest exemplu sunt dacă cercul are un chenar, stilul liniei de chenar, culoarea chenarului, dacă cercul este umplut, culoarea de umplere și modelul de umplere. Puteți vedea codul de mai sus care face ceva similar pentru umplerea zonei clientului cu un dreptunghi alb fără margini plin. Valorile din contextul grafic nu sunt amintite între fiecare apel al funcției de vopsire, deci trebuie să configurați valorile de fiecare dată (ele sunt însă amintite cu funcția de vopsire).

În codul de mai sus puteți vedea că umplerea este activată și tiparul de umplere este dezactivat, deci nu este nevoie să le setăm din nou. Trebuie să setăm frontieră, stilul liniei de frontieră la solid, culoarea de prim-plan la frontieră la negru și culoare de umplere la galben astfel:

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

Adăugați acest cod la comentariul din această funcție, unde scrie că adăugați codul. Apoi trebuie să desenăm un cerc care se face astfel:

mw_gl_circle (draw_info, 30, 30, 15);

Aceasta desenează un cerc la coordonatele 30, 30 cu raza 15. Reconstruiți codul și reluați-l și veți vedea un cerc în fereastră așa cum se arată mai sus. Veți observa că cercul și butonul se suprapun, dar butonul este deasupra. Aceasta este prin design. Comenzile sunt întotdeauna deasupra a tot ceea ce atrageți în zona clientului.

Pasul 8: Date ferestre

Date ferestre
Date ferestre

Până în prezent, am implementat propriul nostru cod în funcția de mesaj a ferestrei 1 (pentru a gestiona mesajele primite) și funcția de vopsire (pentru a desena în zona clientului ferestrei). Acum este timpul să le legăm pe cele două. Vă permite să umpleți cercul desenat în funcția de vopsire cu culoarea pe care o alege utilizatorul de selectorul de culoare atunci când butonul a fost apăsat. Amintiți-vă că nu numim funcția de vopsire, managerul de ferestre o face, astfel încât funcția noastră de mesaj (care știe culoarea aleasă) nu poate apela direct funcția de vopsire. În schimb, trebuie să stocăm datele în cache și să anunțăm managerul de ferestre că este necesară o repictare. Managerul de ferestre va apela apoi funcția de vopsire care poate utiliza datele din cache.

În partea de sus a W1.c veți vedea o structură de date goală și un obiect de acest tip declarat de către generatorul de cod astfel:

typedef struct

{/ * Adăugați membrii de date aici * / char dummy; / * Unele compilatoare se plâng de structuri goale; eliminați acest lucru când adăugați membrii dvs. * /} window_W1_data_t; static window_W1_data_t window_W1_data;

Aici ne stocăm datele în cache, astfel încât acestea să fie păstrate între apeluri și să fie cunoscute sub numele de date ale ferestrei. Trebuie doar să stocăm culoarea aleasă aici, astfel:

typedef struct

{/ * Adăugați membrii de date aici * / mw_hal_lcd_colour_t selected_colour; } window_W1_data_t; static window_W1_data_t window_W1_data = {MW_HAL_LCD_YELLOW};

Îi vom da o culoare inițială de galben. Acum, în funcția de mesaj, vom schimba ușor codul pentru a salva culoarea aleasă aici astfel:

cazul MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{window_W1_data.chosen_colour = message-> message_data; } pauză;

Apoi vom schimba funcția de vopsire pentru a utiliza această valoare atunci când desenează cercul astfel:

mw_gl_set_solid_fill_colour (window_W1_data.chosen_colour);

Acum am schimbat datele de care depinde conținutul ferestrei, așa că trebuie să anunțăm managerul de ferestre că fereastra trebuie revopsită. O facem în funcția de mesaj când este primit mesajul de dialog OK, astfel:

mw_paint_window_client (mesaj-> destinatar_handle);

Acest lucru nu face ca fereastra să fie vopsită direct. Este o funcție utilitară care trimite un mesaj managerului de ferestre că o fereastră trebuie revopsită (dacă pășiți în ea, puteți vedea cum se întâmplă acest lucru). Fereastra care trebuie revopsită în acest caz este ea însăși, iar mânerul pentru fereastră se află în parametrul mesajului pentru funcția de gestionare a mesajelor.

Întregul fișier arată acum așa dacă nu sunteți sigur unde se îndreaptă unele dintre fragmentele de cod de mai sus:

#include

#include "miniwin.h" #include "miniwin_user.h" #include "W1.h" typedef struct {/ * Adăugați membrii de date aici * / mw_hal_lcd_colour_t selected_colour; } window_W1_data_t; static 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"); / * Umpleți zona clientului ferestrei cu alb solid * / 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); / * Adăugați aici codul de pictură a ferestrei * / 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"); / * Linia următoare oprește avertismentele compilatorului, deoarece variabila este în prezent neutilizată * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Adăugați aici orice cod de inițializare a ferestrei * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Adăugați aici codul de gestionare a meniului ferestrei * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Adăugați codul de gestionare pentru acest control aici * / mw_create_window_dialog_colour_chooser (10, 10, "Color", MW_HAL_LCD_RED, false, message-> recipient_hand) } pauză; cazul MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {window_W1_data.chosen_colour = message-> message_data; mw_paint_window_client (mesaj-> destinatar_handle); } pauză; implicit: / * Păstrează MISRA fericit * / pauză; }}

Construiește și rulează din nou și ar trebui să poți seta culoarea de umplere a cercului.

Acest exemplu de date de fereastră folosește date stocate într-o structură de date statice în partea de sus a fișierului sursă. Acest lucru este în regulă dacă aveți o singură instanță a ferestrei, așa cum facem în acest exemplu, dar dacă aveți mai multe instanțe, atunci toate vor partaja aceeași structură de date. Este posibil să aveți date pe instanță, astfel încât mai multe instanțe de același tip de fereastră să aibă propriile date. Acest lucru este explicat în documentația MiniWin din directorul docs. Exemplul de fișier îl folosește pentru a afișa mai multe imagini în același tip de fereastră (așa cum se vede în imaginea principală din partea de sus a acestui instructable).

Pasul 9: O oarecare distracție finală a fontului

Câteva distracții finale pentru fonturi
Câteva distracții finale pentru fonturi

MiniWin acceptă redarea fonturilor TrueType. Dacă există un lucru care face ca interfața dvs. de utilizator să arate bine, acestea sunt fonturi atractive. Acest ultim pas arată cum să redați un font TrueType într-o fereastră MiniWin.

Există două moduri de redare a fonturilor TrueType. Una este să le atrageți direct pe zona dvs. de client așa cum s-a făcut anterior pentru cerc, cealaltă este să adăugați un control de casetă text în fereastra dvs. Facem acest lucru din urmă, deoarece este mai ușor.

Acum vom adăuga un control casetă text în fișierul nostru de configurare JSON. Adăugați-l în definiția ferestrei 2, astfel încât să arate astfel:

asa:

{

"Name": "W2", "Title": "Window 2", "X": 50, "Y": 65, "Width": 100, "Height": 80, "Border": true, "TitleBar": adevărat, "Vizibil": adevărat, "Minimizat": fals, "TextBoxes": [{"Nume": "TB1", "X": 0, "Y": 0, "Lățime": 115, "Înălțime": 50, "Justificare": "Centru", "BackgroundColour": "MW_HAL_LCD_YELLOW", "ForegroundColour": "MW_HAL_LCD_BLACK", "Font": "mf_rlefont_BLKCHCRY16", "Enabled": adevărat, "Vizibil": adevărat}]}

Un cuvânt rapid despre fonturile TrueType din MiniWin. Fonturile vin în fișiere.ttf. În administratorii de ferestre de pe computerele mai mari, acestea sunt redate pe afișajul dvs. atunci când sunt necesare. Acest lucru necesită multă putere de procesare și memorie și nu este potrivit pentru dispozitivele mici. În MiniWin, acestea sunt pre-procesate în bitmap-uri și sunt conectate la momentul compilării la o dimensiune și stil fixe (aldine, italice etc.), adică trebuie să decideți ce fonturi la ce dimensiune și stil veți utiliza la momentul compilării. Acest lucru a fost făcut pentru dvs. pentru două exemple de fonturi din fișierul zip MiniWin pe care l-ați descărcat. Dacă doriți să utilizați alte fonturi la alte dimensiuni și stiluri, consultați documentația MiniWin din folderul docs. Există instrumente în MiniWin pentru Windows și Linux pentru pre-procesarea fișierelor.ttf în fișiere cu cod sursă pe care le puteți introduce în proiect.

Și un al doilea cuvânt rapid - majoritatea fonturilor sunt drepturi de autor, inclusiv cele pe care le veți găsi în Microsoft Windows. Folosiți-le după bunul plac pentru uz personal, dar orice publicați trebuie să vă asigurați că licența cu care sunt publicate fonturile o permite, așa cum este cazul celor 2 fonturi incluse în MiniWin, dar nu și a fonturilor Microsoft!

Înapoi la cod! Generați, plasați fișiere, construiți și reluați ca înainte și veți vedea că Fereastra 2 are acum un text implicit pe un fundal galben într-un font ciudat. Permite modificarea textului editând fișierul sursă al ferestrei 2 W2.c.

Trebuie să comunicăm cu caseta de text pe care tocmai am creat-o și modul în care faceți acest lucru ca orice comunicare din MiniWin este de a-i trimite un mesaj. Vrem să setăm textul în control atunci când este creată fereastra, dar înainte ca aceasta să fie afișată, așa că adăugăm cod în handlerul de mesaje în cazul MW_WINDOW_CREATED_MESSAGE. Acest lucru este primit de codul ferestrei chiar înainte de afișarea ferestrei și este destinat inițializărilor de acest fel. Generatorul de cod a creat un suport de locație care arată astfel în funcția de gestionare a mesajelor:

cazul MW_WINDOW_CREATED_MESSAGE:

/ * Adăugați aici orice cod de inițializare a ferestrei * / break;

Aici vom posta un mesaj în controlul casetei de text spunându-i ce text dorim să fie afișat folosind funcția mw_post_message astfel:

cazul MW_WINDOW_CREATED_MESSAGE:

/ * Adăugați aici orice cod de inițializare a ferestrei * / mw_post_message (MW_TEXT_BOX_SET_TEXT_MESSAGE, message-> recipient_handle, text_box_TB1_handle, 0UL, "Era o noapte întunecată și furtunoasă …", MW_CONTROL_MESSAGE); pauză;

Iată parametrii:

  • MW_TEXT_BOX_SET_TEXT_MESSAGE - Acesta este tipul de mesaj pe care îl trimitem controlului. Acestea sunt listate în miniwin.h și documentate în documentație.
  • message-> recipient_handle - Acesta este de la cine provine mesajul - această fereastră - al cărei handle este în parametrul mesajului transmis în funcția de gestionare a mesajelor.
  • text_box_TB1_handle - Cui îi trimitem mesajul - mânerul controlului casetei de text. Acestea sunt listate în fișierul generat miniwin_user.h.
  • 0UL - Valoarea datelor, nimic în acest caz.
  • „A fost o noapte întunecată și furtunoasă …” - Valoarea indicatorului - noul text.
  • MW_CONTROL_MESSAGE - Tip de destinatar care este un control.

Asta e. Reconstruiți și reluați ca de obicei și veți obține caseta de text afișată ca în imaginea de mai sus.

Postarea mesajelor este fundamentală pentru MiniWin (așa cum este și pentru toți managerii de ferestre). Pentru mai multe exemple, consultați exemplele de proiecte din fișierul zip și pentru o explicație cuprinzătoare citiți secțiunea despre mesajele MiniWin din documentație.

Pasul 10: Mergeți mai departe

Image
Image

Asta este pentru această introducere de bază la MiniWin. MiniWin poate face mult mai mult decât s-a demonstrat aici. De exemplu, ecranul de pe placa utilizat în acest instructable este mic, iar comenzile sunt mici și trebuie utilizate cu un dibber. Cu toate acestea, alte exemple și hardware folosesc comenzi mai mari (există 2 dimensiuni) pe afișaje mai mari și acestea pot fi acționate cu degetul.

Există multe alte tipuri de control decât cele demonstrate aici. Pentru controale suplimentare, aruncați o privire la diferitele exemple de fișiere JSON din folderul generatorului de cod. Toate tipurile de control sunt acoperite în aceste exemple.

Windows are o mulțime de opțiuni. Bordura, bara de titlu și pictogramele sunt toate configurabile. Puteți avea bare de defilare și ferestre de defilare zone ale clientului, mai multe instanțe de același tip de fereastră și ferestre pot fi goale (doar o zonă client, fără margine sau bară de titlu) ceea ce înseamnă că acestea sunt fixate la ora de compilare pe loc pe afișaj (vezi imaginea din această secțiune cu pictograme de dimensiuni mari - acestea sunt de fapt 6 ferestre goale).

MiniWin nu folosește memorie dinamică. Acest lucru îl face potrivit pentru dispozitive cu constrângeri mici și este o cerință pentru unele proiecte încorporate. MiniWin și codul pe care îl generează sunt, de asemenea, pe deplin conforme MISRA 2012 la nivelul „necesar”.

Pentru informații suplimentare, aruncați o privire în folderul docs pentru documentație și, de asemenea, alte exemple de aplicații din fișierul zip. Aici sunt exemple care arată cum să utilizați toate caracteristicile MiniWin și cum să integrați MiniWin cu FatFS și FreeRTOS.

Recomandat: