Spisu treści:

Wbudowany menedżer okien: 10 kroków
Wbudowany menedżer okien: 10 kroków

Wideo: Wbudowany menedżer okien: 10 kroków

Wideo: Wbudowany menedżer okien: 10 kroków
Wideo: Windows 10 za MNIEJ, niż 50 ZŁOTYCH? Nie dajcie się nabrać na "legalność". KŚ wyjaśnia 2024, Listopad
Anonim
Wbudowany menedżer okien
Wbudowany menedżer okien
Wbudowany menedżer okien
Wbudowany menedżer okien
Wbudowany menedżer okien
Wbudowany menedżer okien
Wbudowany menedżer okien
Wbudowany menedżer okien

Ten projekt pokazuje, jak zaimplementować menedżera okien z ruchomymi nachodzącymi na siebie oknami na wbudowanym mikrokontrolerze z panelem LCD i ekranem dotykowym. Istnieją dostępne na rynku pakiety oprogramowania, które to umożliwiają, ale są one kosztowne i są zamknięte. Ten, zwany MiniWin, jest darmowy i open-source. Jest napisany w pełni zgodnym C99 i może być używany w aplikacji C lub C++. Celem MiniWin jest bycie łatwym w użyciu, łatwym do modyfikacji, rozszerzalnym, przenośnym do szerokiej gamy sprzętu i niezbyt zasobożernym.

Oprócz dostarczania kodu do zarządzania twoimi oknami, MiniWin posiada zbiór kontrolek interfejsu użytkownika - przyciski, suwaki, paski postępu, drzewa itp. Możesz mieć wiele okien różnych typów lub wiele wystąpień tego samego typu. Okna można przesuwać, zmieniać rozmiar, maksymalizować, minimalizować, zamykać - wszystkie zwykłe rzeczy, które robisz z oknami w większych menedżerach okien. Czcionki TrueType z kerningiem i wygładzaniem (sprawia, że tekst wygląda gładko) są również obsługiwane w celu uzyskania atrakcyjnego renderowania tekstu.

W każdym oknie masz obszar klienta (twoja przestrzeń wewnątrz obramowania i poniżej górnego paska). Na tym możesz dodać kontrolki, aby utworzyć okno dialogowe lub możesz użyć wbudowanej biblioteki graficznej, aby narysować, co chcesz. Wszystkie funkcje biblioteki graficznej działają w oknie. Nie musisz się martwić o to, gdzie jest Twoje okno, co je zakrywa lub czy jest zminimalizowane.

Oprócz tworzenia własnych okien, dostępne są również standardowe okna dialogowe, które są bardzo łatwe do utworzenia - na przykład okna dialogowe potwierdzenia (tylko przyciski OK lub Tak/Nie), ustawiacze czasu/daty, selektory plików, selektory kolorów itp.

MiniWin korzysta ze standardowego systemu kolejki komunikatów projektu menedżera Windows. Okna mogą komunikować się ze sobą i menedżerem okien za pomocą wiadomości. Nie wywołujesz funkcji bezpośrednio, dodajesz wiadomość do kolejki, a menedżer okien wykona ją za Ciebie.

MiniWin został przeniesiony na standardowe płytki rozwojowe z ekranami dotykowymi od dostawców mikrokontrolerów ST, NXP i Renesas. Istnieją sterowniki sprzętowe i przykładowe projekty dla wszystkich tych urządzeń. Ponadto MiniWin może być zbudowany dla systemu Windows lub Linux, dzięki czemu można symulować kod interfejsu użytkownika przed uzyskaniem wbudowanego sprzętu.

MiniWin posiada generator kodu. Możesz określić okna i kontrolki w prostym do utworzenia pliku JSON czytelnym dla człowieka, a generator kodu przeanalizuje plik i utworzy kod za Ciebie (jest wiele przykładów do naśladowania). Tworzy kompletne aplikacje symulatora Windows lub Linux, które można po prostu zbudować, a symulowany wyświetlacz LCD z działającymi oknami MiniWin. Możesz wziąć dokładnie ten sam wygenerowany kod i wrzucić go do osadzonego projektu i mieć ten sam kod pokazujący te same okna i elementy sterujące chwilę później na wbudowanym sprzęcie.

MiniWin nie wymaga obsługi operacyjnej na wbudowanym urządzeniu. Wszystko działa w jednym wątku. MiniWin może być zintegrowany z RTOS działającym na wbudowanym procesorze i istnieją przykłady integracji MiniWin z FreeRTOS.

Ta instrukcja pokazuje, jak uruchomić MiniWin na procesorze STM32 M4 przy użyciu taniej płyty Discovery STM32F429, która jest już wyposażona w ekran dotykowy QVGA. Są one łatwo dostępne u dostawcy komponentów elektronicznych.

MiniWin działa na mikrokontrolerach klasy średniej i wyższych.

Kieszonkowe dzieci

Płytka rozwojowa STM32F429I-DISC1 i kabel micro USB

Pobierz STM32CubeIDE, który jest bezpłatny.

Krok 1: Uzyskanie kodu

Uzyskiwanie kodu
Uzyskiwanie kodu

Przede wszystkim potrzebujesz zainstalowanego STM32CubeIDE. Dostajesz to ze strony ST. Musisz się zarejestrować, a pobranie i zainstalowanie zajmuje trochę czasu. Wszystko za darmo.

Podczas instalacji pobierz źródło MiniWin i rozpakuj go. Jest duży, ale wykorzystasz tylko niewielką jego część. Kliknij zielony przycisk „Klonuj lub Pobierz” tutaj…

github.com/miniwinwm/miniwinwm

następnie wybierz Pobierz Zip. Rozpakuj zawartość.

Krok 2: Budowanie przykładowego projektu

Budowanie przykładowego projektu
Budowanie przykładowego projektu
Budowanie przykładowego projektu
Budowanie przykładowego projektu

Najpierw zbudujmy jeden z przykładowych projektów. Dobry nazywa się MiniWinSimple. Uruchom STM32CubeIDE, a następnie wykonaj następujące czynności:

  1. Wybierz Plik|Importuj…
  2. Otwórz Ogólne i wybierz Istniejący projekt w obszarze roboczym. Następny.
  3. Kliknij Przeglądaj i przejdź do miejsca, w którym rozpakowałeś MiniWin. Następnie przejdź do folderu STM32CubeIDE\MiniWinSimple\STM32F429. Kliknij Wybierz folder.
  4. W projekcie: zaznacz MiniWinSimple_STM32F429, a następnie kliknij przycisk Zakończ.
  5. Projekt MiniWinSimple_STM32F429 pojawi się w Eksploratorze projektów. Wybierz go, a następnie zbuduj go za pomocą Project|Build Project.
  6. Teraz podłącz kabel USB do płyty głównej i komputera i uruchom go za pomocą Run|Debug, a po pobraniu wybierz Run|Resume. Za pierwszym razem pojawi się ekran kalibracji ekranu, więc dotknij środka 3 krzyżyków na wyświetlaczu LCD. Możesz teraz wejść w interakcję z oknem na wyświetlaczu.

Aby przenieść okno, przeciągnij je za pasek tytułu. Aby zmienić rozmiar okna, użyj ikony białego trójkąta po lewej stronie paska tytułu. Nie można zmienić rozmiaru okien MiniWin przez przeciąganie obramowań, ponieważ wyświetlacze, na których jest używany MiniWin, są zbyt małe. Aby zminimalizować, zmaksymalizować lub zamknąć okno, użyj ikon po prawej stronie paska tytułu (zamykanie może być wyłączone). Gdy okno jest zminimalizowane, nie można przesuwać zminimalizowanych ikon. Narastają od lewego dolnego do prawego dołu.

Krok 3: Uruchamianie generatora kodu

Uruchamianie generatora kodu
Uruchamianie generatora kodu

Teraz zmienimy przykładowy projekt, generując własne okna i wrzucając nowy kod. W tym celu uruchomimy generator kodu.

  1. Otwórz wiersz polecenia i przejdź do folderu, w którym rozpakowałeś MiniWin, a następnie do folderu Tools\CodeGen.
  2. Plik wykonywalny dla systemu Windows CodeGen.exe jest już dostępny. Dla Linuksa musisz go zbudować, wpisując make. (Możesz również skompilować go ze źródła dla systemu Windows, jeśli martwisz się, że działa pobrany plik wykonywalny, ale potrzebujesz zainstalowanego kompilatora i środowiska programistycznego. Zobacz dokumentację MiniWin w folderze docs, aby uzyskać szczegółowe informacje).
  3. W tym folderze znajdują się przykładowe pliki JSON. Użyjemy example_empty.json. Musisz go najpierw edytować, aby skonfigurować go dla systemu Windows lub Linux. Otwórz go w edytorze i na górze, gdzie znajdziesz „TargetType”, zmień wartość „Linux” lub „Windows” na tę, na której działa generator kodu.
  4. Teraz wpisz codegen example_empty.json w wierszu polecenia.
  5. Przejdź do swojego projektu w STM32CubeIDE i otwórz folder MiniWinSimple_Common. Usuń wszystkie znajdujące się tam pliki.
  6. Zostawiliśmy „TargetName” w pliku JSON jako domyślny w „MiniWinGen”, więc jest to nazwa naszego folderu z wygenerowanym kodem. Przejdź do folderu, w którym rozpakowałeś MiniWin, a następnie folder MiniWinGen_Common. Teraz wybierz wszystkie te pliki i przeciągnij i upuść, a następnie do STM32CubeIDE w folderze MiniWinSimple_Common projektu.
  7. Teraz przebuduj i uruchom ponownie projekt w STM32CubeIDE, a pojawi się nowe okno projektu. Przycisk w oknie zniknął, ponieważ example_empty.json nie definiuje żadnego.

Krok 4: Dodawanie okna

Dodawanie okna
Dodawanie okna

Dodamy teraz drugie okno do pliku konfiguracyjnego JSON i ponownie wygenerujemy kod.

1. Otwórz example_empty.json w edytorze tekstu.

2. W sekcji "Windows" znajduje się tablica definicji okien, która aktualnie ma tylko jedno okno. Skopiuj to wszystko…

{

"Nazwa": "W1", "Tytuł": "Okno 1", "X": 10, "Y": 15, "Szerokość": 200, "Wysokość": 180, "Obramowanie": prawda, "TitleBar": true, "Visible": true, "Minimised": false }

i wklej go ponownie, oddzielając 2 definicje przecinkiem.

3. Zmień „W1” na „W2” i „Okno 1” na „Okno 2”. Zmień „X”, „Y”, „Width” i „Height” na różne wartości, pamiętając o rozdzielczości ekranu 240 szerokości na 320 wysokości.

4. Zapisz plik i ponownie uruchom generator kodu.

5. Skopiuj pliki jak w poprzednim kroku, przebuduj i uruchom ponownie. Teraz na ekranie pojawią się 2 okna.

Krok 5: Dodawanie kontrolki

Dodawanie kontrolki
Dodawanie kontrolki

Teraz dodamy kilka kontrolek do nowego okna. Edytuj ten sam plik, co w poprzednim kroku.

1. W specyfikacji dla okna W1 dodaj przecinek po ostatnim ustawieniu ("Zminimalizowane": false) następnie dodaj ten tekst

"MenuBar": prawda, "MenuBarEnabled": true, "MenuItems": ["Fred", "Bert", "Pete", "Alf", "Ian"], "Buttons": [{ "Name": "B1", "Label": "Przycisk1", "X": 10, "Y": 10, "Włączone": prawda, "Widoczny": prawda }]

Ta sekcja dodaje pasek menu z 5 pozycjami i włącza go (paski menu można globalnie wyłączyć, wypróbuj). Dodaje również przycisk, który jest włączony i widoczny (można je utworzyć jako niewidoczne, a następnie uwidocznić w kodzie później).

2. Zregeneruj kod, skopiuj go, przebuduj, uruchom ponownie tak jak poprzednio.

Krok 6: Sprawienie, by kontrolki coś zrobiły

Sprawienie, by kontrolki coś zrobiły
Sprawienie, by kontrolki coś zrobiły

Teraz mamy podstawowy interfejs użytkownika, którego potrzebujemy, aby coś zrobił. W tym przykładzie wyświetlimy okno dialogowe wyboru koloru po naciśnięciu przycisku w oknie 1.

Przejdź do swojego projektu w STM32CubeIDE i otwórz folder MiniWinSimple_Common, a następnie otwórz plik W1.c (nazwa tego pliku odpowiada polu „Nazwa” okna w pliku JSON podczas generowania kodu).

W tym pliku znajdziesz funkcję window_W1_message_function(). To wygląda tak:

void window_W1_message_function(const mw_message_t *message){ MW_ASSERT(komunikat != (void*)0, "Parametr wskaźnika zerowego"); /* Następna linia zatrzymuje ostrzeżenia kompilatora, ponieważ zmienna jest obecnie nieużywana */ (void)window_W1_data; switch (message->message_id) { case MW_WINDOW_CREATED_MESSAGE: /* Dodaj tutaj dowolny kod inicjalizacji okna */ break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: /* Dodaj tutaj kod obsługi menu okna */ break; case MW_BUTTON_PRESSED_MESSAGE: if (message->sender_handle == button_B1_handle) { /* Dodaj tutaj swój kod obsługi dla tej kontrolki */ } break; default: /* Utrzymuj MISRA szczęśliwy */ break; } }

Jest to wywoływane przez menedżera okien dla tego okna za każdym razem, gdy menedżer okien musi powiadomić okno, że coś się stało. W tym przypadku interesuje nas, że został naciśnięty jedyny przycisk okna. W instrukcji switch dla typów wiadomości zobaczysz wielkość liter dla MW_BUTTON_PRESSED_MESSAGE. Ten kod jest uruchamiany po naciśnięciu przycisku. W tym oknie jest tylko jeden przycisk, ale może być ich więcej, więc sprawdzamy, który to przycisk. W tym przypadku może to być tylko przycisk B1 (nazwa ponownie odpowiada nazwie przycisku w pliku JSON).

Więc po tej etykiecie sprawy dodaj kod, aby wyświetlić okno dialogowe wyboru koloru, które wygląda następująco:

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

Parametry są następujące:

  • 10, 10 to lokalizacja na ekranie okna dialogowego
  • „Kolor” to tytuł okna dialogowego
  • MW_HAL_LCD_RED to domyślny kolor, od którego rozpocznie się okno dialogowe
  • false oznacza, że nie wyświetla się dużego rozmiaru (spróbuj ustawić to na true i zobacz różnicę)
  • message->recipient handle jest właścicielem tego okna dialogowego, w tym przypadku jest to to okno. Uchwyt okna znajduje się w parametrze wiadomości funkcji. To jest okno, do którego zostanie wysłana odpowiedź w oknie dialogowym.

Aby poznać wartość koloru wybranego przez użytkownika, menedżer okien wyśle do naszego okna wiadomość z wybranym kolorem, gdy użytkownik naciśnie przycisk OK w oknie dialogowym. Dlatego musimy przechwycić również tę wiadomość innym przypadkiem w instrukcji switch, który wygląda tak:

przypadek MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{ mw_hal_lcd_color_t wybrany_kolor = wiadomość->dane_wiadomości; (nieważny)wybrany_kolor; } przerwa;

Nie robimy jeszcze nic z wybranym kolorem, więc po prostu rzutujemy go na void, aby zapobiec ostrzeżeniu kompilatora. Ostateczny kod tej funkcji wygląda teraz tak:

void window_W1_message_function(const mw_message_t *wiadomość)

{ MW_ASSERT(komunikat != (nieważny*)0, "Parametr wskaźnika zerowego"); /* Następna linia zatrzymuje ostrzeżenia kompilatora, ponieważ zmienna jest obecnie nieużywana */ (void)window_W1_data; switch (message->message_id) { case MW_WINDOW_CREATED_MESSAGE: /* Dodaj tutaj dowolny kod inicjalizacji okna */ break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: /* Dodaj tutaj kod obsługi menu okna */ break; case MW_BUTTON_PRESSED_MESSAGE: if (message->sender_handle == button_B1_handle) { /* Dodaj tutaj swój kod obsługi dla tej kontrolki */ mw_create_window_dialog_colour_chooser(10, 10, "Color", MW_HAL_LCD_RED, false, message->recipient_handle); } przerwa; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: { mw_hal_lcd_color_t wybrany_kolor = wiadomość->dane_wiadomości; (nieważny)wybrany_kolor; } przerwa; default: /* Utrzymuj MISRA szczęśliwy */ break; } }

Uruchomienie kodu pokazano na powyższym obrazku. Możesz zauważyć, że gdy pojawia się okno dialogowe, musisz na nie odpowiedzieć i odrzucić, zanim zrobisz cokolwiek innego. Nazywa się to zachowaniem modalnym. Okna dialogowe w MiniWin i wszystkie zawsze globalnie modalne i możesz wyświetlać tylko jeden na raz. Tutaj jest więcej wyjaśnień…

en.wikipedia.org/wiki/Modal_window

Krok 7: Rysowanie w oknie

Rysowanie w oknie
Rysowanie w oknie

Do tej pory używaliśmy tylko kontrolek, a one same się rysują. Czas zrobić własny rysunek w naszym oknie. Część, na której możesz rysować, znajduje się wewnątrz ramek (jeśli są, są opcjonalne), wewnątrz pasków przewijania (jeśli są zdefiniowane, również opcjonalne) i poniżej paska tytułu (jeśli jest, to też jest opcjonalne). W terminologii okiennej nazywa się to obszarem klienta.

W MiniWin dostępna jest biblioteka poleceń graficznych, z których możesz korzystać. Wszyscy są świadomi okna. Oznacza to, że nie musisz się martwić, czy okno jest widoczne, częściowo zasłonięte innymi oknami, włączone, częściowo wyłączone lub całkowicie poza ekranem lub czy współrzędna miejsca, w którym rysujesz, znajduje się w obszarze roboczym lub poza nim. To wszystko załatwione dla Ciebie. Nie możesz rysować poza swoim obszarem roboczym.

Rysowanie na obszarach klienta w terminologii Windows nazywa się malowaniem, a każde okno ma funkcję malowania, w której wykonujesz rysunek. Nie wywołujesz funkcji malowania, menedżer okien robi to za Ciebie, gdy jest to potrzebne. Jest to potrzebne, gdy okno zostanie przesunięte lub inne okno na górze ma zmienioną pozycję lub widoczność. Jeśli potrzebujesz odświeżenia okna, ponieważ niektóre dane, od których zależy zawartość okna, uległy zmianie (tj. wiesz, że wymagane jest odświeżenie, a nie wiedza menedżera okien), wtedy mówisz menedżerowi okien, że potrzebne jest odświeżenie i wywołuje Twoja funkcja malowania. Sam tego nie nazywasz. (Wszystko to zostało zademonstrowane w następnej sekcji).

Najpierw musisz znaleźć swoją funkcję malowania. Generator kodu tworzy go za Ciebie i znajduje się tuż nad funkcją obsługi wiadomości zmodyfikowaną w poprzedniej sekcji. Przejdź do swojego projektu i ponownie otwórz plik W1.c.

W tym pliku znajdziesz funkcję window_W1_paint_function(). To wygląda tak:

void window_W1_paint_function(mw_handle_t window_handle, const mw_gl_draw_info_t *draw_info)

{ MW_ASSERT(draw_info != (void*)0, "Parametr wskaźnika zerowego"); /* Wypełnij obszar klienta okna jednolitym białym kolorem */ 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(uchwyt_okna).width, mw_get_window_client_rect(uchwyt_okna).wysokość); /* Dodaj tutaj kod malowania okien */ }

To jest czysty kod wygenerowany, a wszystko, co robi, to wypełnienie obszaru klienta jednolitym białym kolorem. Narysujmy żółte wypełnione kółko w obszarze klienta. Najpierw musimy zrozumieć pojęcie kontekstu graficznego (kolejna rzecz dotycząca okien). Ustawiamy parametry rysowania w kontekście graficznym, a następnie wywołujemy ogólną procedurę rysowania okręgów. Rzeczy, które musimy ustawić w tym przykładzie, to czy okrąg ma obramowanie, styl linii obramowania, kolor obramowania, czy okrąg jest wypełniony, kolor wypełnienia i wzór wypełnienia. Możesz zobaczyć powyższy kod, który robi coś podobnego do wypełniania obszaru klienta pustym, wypełnionym białym prostokątem bez obramowania. Wartości w kontekście graficznym nie są zapamiętywane między każdym wywołaniem funkcji malowania, więc za każdym razem trzeba je ustawiać (jednak są one zapamiętywane w funkcji malowania).

W powyższym kodzie widać, że wypełnienie jest włączone, a wzór wypełnienia wyłączony, więc nie musimy ustawiać ich ponownie. Musimy włączyć obramowanie, styl linii obramowania na solidny, kolor pierwszego planu obramowania na czarny i kolor wypełnienia na żółty w następujący sposób:

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

Dodaj ten kod w komentarzu w tej funkcji, gdzie mówi, aby dodać swój kod. Następnie musimy narysować okrąg, który wykonujemy w ten sposób:

mw_gl_circle(draw_info, 30, 30, 15);

To rysuje okrąg o współrzędnych 30, 30 o promieniu 15. Przebuduj kod i uruchom go ponownie, a zobaczysz okrąg w oknie, jak pokazano powyżej. Zauważysz, że okrąg i przycisk nachodzą na siebie, ale przycisk jest na górze. To jest zgodne z projektem. Kontrole są zawsze nad wszystkim, co rysujesz w obszarze klienta.

Krok 8: Dane okna

Dane okna
Dane okna

Do tej pory zaimplementowaliśmy nasz własny kod w funkcji komunikatów okna 1 (do obsługi komunikatów przychodzących) i jego funkcji malowania (do rysowania w obszarze klienta okna). Teraz nadszedł czas na połączenie tych dwóch. Pozwala wypełnić okrąg narysowany w funkcji malowania kolorem wybranym przez użytkownika za pomocą selektora kolorów po naciśnięciu przycisku. Pamiętaj, że nie wywołujemy funkcji malowania, robi to menedżer okien, więc nasza funkcja wiadomości (znająca wybrany kolor) nie może bezpośrednio wywołać funkcji malowania. Zamiast tego musimy buforować dane i poinformować menedżera okien, że wymagane jest odświeżenie. Menedżer okien wywoła następnie funkcję malowania, która może wykorzystać dane z pamięci podręcznej.

Na górze W1.c zobaczysz pustą strukturę danych i obiekt tego typu zadeklarowany przez generator kodu w następujący sposób:

struktura typedef

{ /* Dodaj tutaj członków swoich danych */ char dummy; /* Niektóre kompilatory narzekają na puste struktury; usuń to, gdy dodasz członków */ } window_W1_data_t; statyczny window_W1_data_t window_W1_data;

W tym miejscu przechowujemy nasze dane w pamięci podręcznej, dzięki czemu są one zachowywane między wywołaniami i są znane jako dane okna. Musimy tylko zapisać tutaj wybrany kolor, w ten sposób:

struktura typedef

{ /* Dodaj tutaj członków swoich danych */ mw_hal_lcd_colour_t selected_colour; } okno_W1_dane_t; statyczny window_W1_data_t window_W1_data = { MW_HAL_LCD_YELLOW };

Nadajemy mu początkowy kolor żółty. Teraz w funkcji wiadomości zmienimy nieco kod, aby zapisać wybrany kolor tutaj w ten sposób:

przypadek MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{ window_W1_data.chosen_color = wiadomość->message_data; } przerwa;

Następnie zmienimy funkcję malowania, aby używała tej wartości, gdy rysuje okrąg w ten sposób:

mw_gl_set_solid_fill_colour(window_W1_data.chosen_color);

Teraz zmieniliśmy dane, od których zależy zawartość okna, więc musimy powiadomić menedżera okien, że okno wymaga odświeżenia. Robimy to w funkcji wiadomości po odebraniu okna dialogowego OK, w następujący sposób:

mw_paint_window_client(wiadomość->uchwyt_odbiorcy);

Nie powoduje to bezpośredniego malowania okna. Jest to funkcja narzędziowa, która wysyła wiadomość do menedżera okien, że okno musi zostać przemalowane (jeśli wejdziesz w nie, zobaczysz, jak to się dzieje). W tym przypadku okno, które należy odmalować, jest samo, a uchwyt do okna znajduje się w parametrze wiadomości funkcji obsługi wiadomości.

Cały plik wygląda teraz tak, jeśli nie masz pewności, gdzie znajdują się niektóre z powyższych fragmentów kodu:

#włączać

#include "miniwin.h" #include "miniwin_user.h" #include "W1.h" typedef struct { /* Dodaj tutaj swoje składowe danych */ mw_hal_lcd_colour_t selected_colour; } okno_W1_dane_t; statyczny window_W1_data_t window_W1_data = { MW_HAL_LCD_YELLOW }; void window_W1_paint_function(mw_uchwyt_t window_handle, const mw_gl_draw_info_t *remis_info) { MW_ASSERT(rysunek_informacje != (void*)0, "Parametr wskaźnika zerowego"); /* Wypełnij obszar klienta okna jednolitym białym kolorem */ 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(uchwyt_okna).width, mw_get_window_client_rect(uchwyt_okna).wysokość); /* Dodaj tutaj kod malowania okien */ mw_gl_set_fg_colour(MW_HAL_LCD_BLACK); mw_gl_set_solid_fill_colour(window_W1_data.chosen_color); 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 *wiadomość) { MW_ASSERT(komunikat != (void*)0, "Parametr wskaźnika zerowego"); /* Następna linia zatrzymuje ostrzeżenia kompilatora, ponieważ zmienna jest obecnie nieużywana */ (void)window_W1_data; switch (message->message_id) { case MW_WINDOW_CREATED_MESSAGE: /* Dodaj tutaj dowolny kod inicjalizacji okna */ break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: /* Dodaj tutaj kod obsługi menu okna */ break; case MW_BUTTON_PRESSED_MESSAGE: if (message->sender_handle == button_B1_handle) { /* Dodaj tutaj swój kod obsługi dla tej kontrolki */ mw_create_window_dialog_colour_chooser(10, 10, "Color", MW_HAL_LCD_RED, false, message->recipient_handle); } przerwa; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: { window_W1_data.chosen_color = wiadomość->message_data; mw_paint_window_client(wiadomość->uchwyt_odbiorcy); } przerwa; default: /* Utrzymuj MISRA szczęśliwy */ break; } }

Zbuduj i biegnij ponownie, a powinieneś być w stanie ustawić kolor wypełnienia koła.

Ten przykład danych okna używa danych przechowywanych w statycznej strukturze danych w górnej części pliku źródłowego. Jest to w porządku, jeśli masz tylko jedną instancję okna, tak jak w tym przykładzie, ale jeśli masz więcej niż jedną instancję, wszystkie będą współdzielić tę samą strukturę danych. Możliwe jest posiadanie danych na instancję, dzięki czemu wiele instancji tego samego typu okna ma własne dane. Jest to wyjaśnione w dokumentacji MiniWin znajdującej się w katalogu docs. Przykład pliku używa go do wyświetlania wielu obrazów w tym samym typie okna (jak widać na głównym obrazie na samej górze tej instrukcji).

Krok 9: Ostateczna zabawa z czcionkami

Trochę ostatecznej zabawy z czcionkami
Trochę ostatecznej zabawy z czcionkami

MiniWin obsługuje renderowanie czcionek TrueType. Jeśli jest jedna rzecz, która sprawia, że interfejs użytkownika wygląda dobrze, to atrakcyjne czcionki. Ten ostatni krok pokazuje, jak renderować czcionkę TrueType w oknie MiniWin.

Istnieją dwa sposoby renderowania czcionek TrueType. Jednym z nich jest narysowanie ich bezpośrednio w obszarze roboczym, tak jak to zrobiono wcześniej dla okręgu, drugim jest dodanie kontrolki pola tekstowego do swojego okna. Robimy to drugie, ponieważ jest to łatwiejsze.

Teraz dodamy kontrolkę pola tekstowego do naszego pliku konfiguracyjnego JSON. Dodaj go do definicji okna 2, aby wyglądał tak:

lubię to:

{

"Nazwa": "W2", "Tytuł": "Okno 2", "X": 50, "Y": 65, "Szerokość": 100, "Wysokość": 80, "Obramowanie": prawda, "TitleBar": true, "Visible": true, "Minimised": false, "TextBoxes": [{ "Name": "TB1", "X": 0, "Y": 0, "Width": 115, "Height": 50, "Uzasadnienie": "Centre", "BackgroundColour": "MW_HAL_LCD_YELLOW", "ForegroundColour": "MW_HAL_LCD_BLACK", "Font": "mf_rlefont_BLKCHCRY16", "Enabled": true, "Visible": true }] }

Krótkie słowo o czcionkach TrueType w MiniWin. Czcionki są dostarczane w plikach.ttf. W menedżerach okien na większych komputerach są one renderowane na ekranie, gdy są potrzebne. Wymaga to dużej mocy obliczeniowej i pamięci i nie jest odpowiednie dla małych urządzeń. W MiniWin są one wstępnie przetwarzane na mapy bitowe i łączone w czasie kompilacji ze stałym rozmiarem i stylem czcionki (pogrubienie, kursywa itp.), tzn. musisz zdecydować, jakich czcionek w jakim rozmiarze i stylu będziesz używać podczas kompilacji. Zostało to zrobione dla dwóch przykładowych czcionek w pobranym pliku zip MiniWin. Jeśli chcesz użyć innych czcionek w innych rozmiarach i stylach, zapoznaj się z dokumentacją MiniWin w folderze docs. W MiniWin dla Windows i Linux dostępne są narzędzia do wstępnego przetwarzania plików.ttf na pliki kodu źródłowego, które można wrzucić do projektu.

I drugie szybkie słowo - większość czcionek jest chroniona prawami autorskimi, w tym te, które można znaleźć w systemie Microsoft Windows. Używaj ich do woli do użytku osobistego, ale wszystko, co publikujesz, musisz upewnić się, że licencja, z którą publikowane są czcionki, pozwala na to, tak jak w przypadku 2 czcionek zawartych w MiniWin, ale nie czcionek Microsoft!

Powrót do kodu! Generuj, upuszczaj pliki, kompiluj i uruchamiaj ponownie, jak poprzednio, a zobaczysz, że okno 2 ma teraz domyślny tekst na żółtym tle w zwariowanej czcionce. Zmieńmy tekst, edytując plik źródłowy Windows 2 W2.c.

Musimy komunikować się z właśnie utworzonym polem tekstowym, a sposób, w jaki robisz to, podobnie jak w przypadku każdej komunikacji w MiniWin, polega na wysłaniu wiadomości. Chcemy ustawić tekst w kontrolce, gdy okno jest tworzone, ale przed jego wyświetleniem, więc dodajemy kod w obsłudze komunikatów w przypadku MW_WINDOW_CREATED_MESSAGE. Jest to odbierane przez kod okna tuż przed wyświetleniem okna i jest przeznaczone do takich inicjalizacji. Generator kodu utworzył symbol zastępczy, który w funkcji obsługi wiadomości wygląda tak:

sprawa MW_WINDOW_CREATED_MESSAGE:

/* Dodaj tutaj dowolny kod inicjalizacji okna */ break;

W tym miejscu wyślemy wiadomość do kontrolki pola tekstowego z informacją, jaki tekst chcemy wyświetlić, używając funkcji mw_post_message w następujący sposób:

sprawa MW_WINDOW_CREATED_MESSAGE:

/* Dodaj tutaj dowolny kod inicjalizacji okna */ mw_post_message(MW_TEXT_BOX_SET_TEXT_MESSAGE, message->recipient_handle, text_box_TB1_handle, 0UL, "Była ciemna i burzowa noc…", MW_CONTROL_MESSAGE); przerwa;

Oto parametry:

  • MW_TEXT_BOX_SET_TEXT_MESSAGE - To jest typ wiadomości, który wysyłamy do kontrolki. Są one wymienione w miniwin.h i udokumentowane w dokumentacji.
  • message->recipient_handle - To od kogo jest wiadomość - to okno - którego uchwyt znajduje się w parametrze message przekazywanym do funkcji obsługi wiadomości.
  • text_box_TB1_handle - Do kogo wysyłamy wiadomość - uchwyt kontrolki pola tekstowego. Są one wymienione w wygenerowanym pliku miniwin_user.h.
  • 0UL - Wartość danych, w tym przypadku nic.
  • „To była ciemna i burzliwa noc…” – wartość wskaźnika – nowy tekst.
  • MW_CONTROL_MESSAGE - Typ odbiorcy będący kontrolką.

Otóż to. Przebuduj i uruchom ponownie jak zwykle, a otrzymasz pole tekstowe pokazane na powyższym obrazku.

Wysyłanie wiadomości ma fundamentalne znaczenie dla MiniWin (podobnie jak dla wszystkich menedżerów okien). Aby uzyskać więcej przykładów, spójrz na przykładowe projekty w pliku zip, a wyczerpujące wyjaśnienie przeczytaj sekcję dotyczącą komunikatów MiniWin w dokumentacji.

Krok 10: Idź dalej

Image
Image

To tyle, jeśli chodzi o podstawowe wprowadzenie do MiniWin. MiniWin potrafi o wiele więcej, niż zostało to tutaj zademonstrowane. Na przykład ekran na tablicy używany w tej instrukcji jest mały, a elementy sterujące są małe i muszą być używane z dibberem. Jednak inne przykłady i sprzęt używają większych elementów sterujących (są 2 rozmiary) na większych wyświetlaczach i można je obsługiwać palcem.

Istnieje wiele innych rodzajów kontroli niż te przedstawione tutaj. Aby uzyskać dalsze kontrolki, spójrz na różne przykładowe pliki JSON w folderze generatora kodu. W tych przykładach omówiono wszystkie typy kontrolek.

Okna mają wiele opcji. Ramka, pasek tytułu i ikony są konfigurowalne. Możesz mieć paski przewijania i obszary klienckie z przewijanym oknem, wiele wystąpień tego samego typu okna i okna mogą być nagie (tylko obszar roboczy, bez ramki lub paska tytułu), co oznacza, że są one naprawione w czasie kompilacji na miejscu na wyświetlaczu (zobacz obrazek w tej sekcji z dużymi ikonami - w rzeczywistości jest to 6 nagich okien).

MiniWin nie używa pamięci dynamicznej. Dzięki temu jest odpowiedni dla małych urządzeń z ograniczeniami i jest wymagany w przypadku niektórych projektów osadzonych. MiniWin i kod, który generuje, są również w pełni zgodne z MISRA 2012 na "wymaganym" poziomie.

Aby uzyskać więcej informacji, zajrzyj do folderu docs z dokumentacją, a także z innymi przykładowymi aplikacjami w pliku zip. Poniżej znajdują się przykłady pokazujące, jak korzystać ze wszystkich funkcji MiniWin i jak zintegrować MiniWin z FatFS i FreeRTOS.

Zalecana: