İçindekiler:

Gömülü Pencere Yöneticisi: 10 Adım
Gömülü Pencere Yöneticisi: 10 Adım

Video: Gömülü Pencere Yöneticisi: 10 Adım

Video: Gömülü Pencere Yöneticisi: 10 Adım
Video: RAM'inizin Bu Özelliğini MUTLAKA Kontrol Edin!! 👈👈 (PROGRAMSIZ) 2024, Kasım
Anonim
Gömülü Pencere Yöneticisi
Gömülü Pencere Yöneticisi
Gömülü Pencere Yöneticisi
Gömülü Pencere Yöneticisi
Gömülü Pencere Yöneticisi
Gömülü Pencere Yöneticisi
Gömülü Pencere Yöneticisi
Gömülü Pencere Yöneticisi

Bu proje, LCD panelli ve dokunmatik ekranlı gömülü bir mikro denetleyicide hareketli örtüşen pencerelere sahip bir pencere yöneticisinin nasıl uygulanacağını gösterir. Bunu yapmak için ticari olarak mevcut yazılım paketleri vardır, ancak bunlar maliyetlidir ve kapalı kaynaktır. MiniWin adı verilen bu ücretsiz ve açık kaynaklıdır. Tam uyumlu C99 ile yazılmıştır ve bir C veya C++ uygulamasında kullanılabilir. MiniWin'in hedefleri, kullanımı kolay, değiştirilmesi kolay, genişletilebilir, geniş bir donanım yelpazesine taşınabilir ve fazla kaynak aç olmamaktır.

MiniWin, pencerelerinizi yönetmek için kod sağlamanın yanı sıra, düğmeler, kaydırıcılar, ilerleme çubukları, ağaçlar vb. gibi bir kullanıcı arabirimi kontrolleri koleksiyonuna sahiptir. Farklı türlerde birden çok pencereniz veya aynı türden birden çok örneğiniz olabilir. Pencereler hareket ettirilebilir, yeniden boyutlandırılabilir, büyütülebilir, küçültülebilir, kapatılabilir - daha büyük pencere yöneticilerinde pencerelerle yaptığınız olağan şeyler. Karakter aralığı ve kenar yumuşatma özelliğine sahip TrueType yazı tipleri de çekici metin oluşturma için desteklenir (metnin düzgün görünmesini sağlar).

Her pencerede bir müşteri alanınız vardır (sınır içindeki ve üst çubuğun altındaki alanınız). Bunun üzerine bir diyalog oluşturmak için kontroller ekleyebilir veya istediğinizi çizmek için yerleşik grafik kitaplığını kullanabilirsiniz. Tüm grafik kitaplığı işlevleri pencere farkındadır. Pencerenizin nerede olduğu, neyin örtüştüğü veya küçültülmüş olup olmadığı konusunda endişelenmenize gerek yok.

Kendi pencerelerinizi oluşturmaya ek olarak, örneklenmesi çok kolay olan bazı standart diyaloglar da vardır - örneğin, onay diyalogları (sadece bir Tamam veya Evet/Hayır düğmeleri), saat/tarih ayarlayıcılar, dosya seçiciler, renk seçiciler vb.

MiniWin, standart bir Windows yöneticisi tasarım mesaj kuyruğu sistemi kullanır. Windows, mesajlar yoluyla birbirleriyle ve pencere yöneticisiyle etkileşime girebilir. İşleri doğrudan yapmak için işlevleri çağırmazsınız, kuyruğa bir mesaj eklersiniz ve pencere yöneticisi bunu sizin için yürürlüğe koyar.

MiniWin, mikro denetleyici satıcıları ST, NXP ve Renesas'ın dokunmatik ekranlı standart geliştirme panolarına taşındı. Tüm bu cihazlar için donanım sürücüleri ve örnek projeler bulunmaktadır. Ek olarak MiniWin, Windows veya Linux için oluşturulabilir, böylece yerleşik donanımınızı almadan önce kullanıcı arabirimi kodunuzu simüle edebilirsiniz.

MiniWin bir kod üretecine sahiptir. Pencerelerinizi ve kontrollerinizi, insan tarafından okunabilir bir JSON dosyası oluşturmak için basit bir şekilde belirtebilirsiniz ve kod oluşturucu dosyayı ayrıştırır ve sizin için kodu oluşturur (izlenecek çok sayıda örnek vardır). Sadece oluşturulabilen Windows veya Linux eksiksiz simülatör uygulamaları oluşturur ve MiniWin pencereleriniz çalışırken simüle edilmiş LCD ekranınız vardır. Tam olarak aynı oluşturulan kodu alabilir ve gömülü bir projeye bırakabilir ve aynı kodun daha sonra gömülü donanımınızda aynı pencereleri ve kontrolleri göstermesini sağlayabilirsiniz.

MiniWin, gömülü aygıtta işletim desteği gerektirmez. Hepsi tek bir iş parçacığında çalışır. MiniWin, gömülü bir işlemci üzerinde çalışan bir RTOS ile entegre edilebilir ve MiniWin'i FreeRTOS ile entegre eden örnekler vardır.

Bu talimat, önceden takılı bir QVGA dokunmatik ekran ile birlikte gelen ucuz STM32F429 Discovery kartını kullanarak MiniWin'in bir STM32 M4 işlemci üzerinde nasıl çalıştırılacağını gösterir. Bunlar elektronik bileşen tedarikçinizden kolayca temin edilebilir.

MiniWin, orta menzilli mikro denetleyicilerde ve üzerinde çalışır.

Gereçler

STM32F429I-DISC1 geliştirme kartı ve bir mikro USB kablosu

Ücretsiz olan STM32CubeIDE indir.

Adım 1: Kodu Alma

Kodu Alma
Kodu Alma

Öncelikle STM32CubeIDE kurulu olmalıdır. Bunu ST'nin web sitesinden alırsınız. Kayıt olmanız gerekiyor ve indirip kurmanız biraz zaman alıyor. Hepsi ücretsiz.

Bu yükleme sırasında MiniWin kaynağını indirin ve sıkıştırmasını açın. Büyük, ama sadece küçük bir kısmını kullanacaksınız. Buradaki yeşil 'Klonla veya İndir' düğmesini tıklayın…

github.com/miniwinwm/miniwinwm

ardından Zip İndir'i seçin. İçeriği açın.

Adım 2: Örnek Bir Proje Oluşturma

Örnek Proje Oluşturma
Örnek Proje Oluşturma
Örnek Proje Oluşturma
Örnek Proje Oluşturma

İlk önce örnek projelerden birini oluşturalım. İyi olana MiniWinSimple denir. STM32CubeIDE'yi başlatın ve ardından şunu yapın:

  1. Dosya|İçe Aktar'ı seçin…
  2. Genel'i açın ve Çalışma Alanında Mevcut Proje'yi seçin. Sonraki.
  3. Gözat'a tıklayın ve MiniWin'i açtığınız yere gidin. Ardından STM32CubeIDE\MiniWinSimple\STM32F429 klasörüne gidin. Klasör Seç'i tıklayın.
  4. Projede: MiniWinSimple_STM32F429'u işaretleyin ve ardından Bitir'e tıklayın.
  5. MiniWinSimple_STM32F429 projesi, Proje Gezgini'nde görünecektir. Seçin ve ardından Project|Build Project ile oluşturun.
  6. Şimdi USB kablonuzu panoya ve bilgisayarınıza takın ve Run|Debug kullanarak çalıştırın ve indirildiğinde Run|Resume öğesini seçin. İlk kez bir ekran kalibrasyon ekranı alacaksınız, bu nedenle LCD ekrandaki 3 çarpı işaretinin ortasına dokunun. Artık ekrandaki pencereyle etkileşime geçebilirsiniz.

Bir pencereyi taşımak için başlık çubuğundan sürükleyin. Bir pencereyi yeniden boyutlandırmak için başlık çubuğunun solundaki beyaz üçgen simgesini kullanın. MiniWin pencereleri, MiniWin'in kullanıldığı ekranlar çok küçük olduğu için kenarlıklar sürüklenerek yeniden boyutlandırılamaz. Bir pencereyi küçültmek, büyütmek veya kapatmak için başlık çubuğunun sağ ucundaki simgeleri kullanın (kapat devre dışı bırakılmış olabilir). Bir pencere simge durumuna küçültüldüğünde, simge durumuna küçültülmüş simgeleri hareket ettiremezsiniz. Soldan sağa doğru birikirler.

3. Adım: Kod Oluşturucuyu Çalıştırma

Kod Oluşturucuyu Çalıştırma
Kod Oluşturucuyu Çalıştırma

Şimdi örnek projeyi kendi pencerelerimizi oluşturup yeni kodu bırakarak değiştireceğiz. Bunu yapmak için kod üretecini çalıştıracağız.

  1. Bir komut istemi açın ve MiniWin'i açtığınız klasöre ve ardından Tools\CodeGen klasörüne gidin.
  2. Windows CodeGen.exe için yürütülebilir dosya zaten mevcut. Linux için make yazarak oluşturmanız gerekir. (Ayrıca, indirilmiş bir yürütülebilir dosyayı çalıştırmaktan endişeleniyorsanız ancak derleyici ve geliştirme ortamının kurulu olması gerekiyorsa, Windows için kaynaktan da oluşturabilirsiniz. Ayrıntılar için docs klasöründeki MiniWin belgelerine bakın).
  3. Bu klasörde bazı örnek JSON dosyaları bulunmaktadır. example_empty.json kullanacağız. Windows veya Linux için ayarlamak için önce düzenlemeniz gerekir. Bir düzenleyicide açın ve "TargetType" öğesini bulacağınız en üstte, "Linux" veya "Windows" değerini kod oluşturucuyu çalıştırdığınız değerle değiştirin.
  4. Şimdi komut istemine codegen example_empty.json yazın.
  5. STM32CubeIDE'de projenize gidin ve MiniWinSimple_Common klasörünü açın. Oradaki tüm dosyaları silin.
  6. JSON dosyasındaki "TargetName"i "MiniWinGen"de varsayılan olarak bıraktık, bu nedenle oluşturulan kod klasörümüzün adı budur. MiniWin'i açtığınız klasöre ve ardından MiniWinGen_Common klasörüne gidin. Şimdi tüm bu dosyaları seçin ve projenizin MiniWinSimple_Common klasöründeki STM32CubeIDE'ye sürükleyip bırakın.
  7. Şimdi projeyi STM32CubeIDE'de yeniden oluşturun ve yeniden çalıştırın ve yeni tasarım pencereniz görünecektir. Örnek_boş.json herhangi bir tanımlama yapmadığı için penceredeki düğme gitti.

Adım 4: Pencere Ekleme

Pencere Ekleme
Pencere Ekleme

Şimdi JSON yapılandırma dosyasına ikinci bir pencere ekleyeceğiz ve kodu yeniden oluşturacağız.

1. example_empty.json'u bir metin düzenleyicide açın.

2. "Windows" bölümünün altında, şu anda yalnızca bir pencereye sahip olan bir dizi pencere tanımı vardır. Bütün bunları kopyala…

{

"Ad": "W1", "Başlık": "Pencere 1", "X": 10, "Y": 15, "Genişlik": 200, "Yükseklik": 180, "Kenarlık": doğru, "Başlık Çubuğu": doğru, "Görünür": doğru, "Küçültülmüş": yanlış }

ve 2 tanımı ayıran bir virgülle tekrar yapıştırın.

3. "W1"i "W2" ve "Pencere 1"i "Pencere 2" olarak değiştirin. Ekran çözünürlüğünün 240 genişlik ve 320 yükseklik olduğunu göz önünde bulundurarak "X", "Y", "Genişlik" ve "Yükseklik" değerlerini bazı farklı değerlerle değiştirin.

4. Dosyayı kaydedin ve kod oluşturucuyu yeniden çalıştırın.

5. Dosyaları önceki adımdaki gibi kopyalayın, yeniden oluşturun ve yeniden çalıştırın. Artık ekranınızda 2 pencere olacak.

Adım 5: Kontrol Ekleme

Kontrol Ekleme
Kontrol Ekleme

Şimdi yeni pencerenize bazı kontroller ekleyeceğiz. Önceki adımdakiyle aynı dosyayı düzenleyin.

1. W1 penceresinin belirtiminde, son ayardan sonra bir virgül ekleyin ("Küçültülmüş": false) ve ardından bu metni ekleyin

"MenüBar": doğru, "MenuBarEnabled": true, "MenuItems": ["Fred", "Bert", "Pete", "Alf", "Ian"], "Düğmeler": [{ "Ad": "B1", "Etiket": "Düğme1", "X": 10, "Y": 10, "Etkin": doğru, "Görünür": doğru }]

Bu bölüm 5 öğeli bir menü çubuğu ekler ve bunu etkinleştirir (menü çubukları genel olarak devre dışı bırakılabilir, deneyin). Ayrıca etkin ve görünür bir düğme ekler (bunlar görünmez olarak oluşturulabilir ve daha sonra kodda görünür hale getirilebilir).

2. Kodu yeniden oluşturun, kopyalayın, yeniden oluşturun, hepsini eskisi gibi yeniden çalıştırın.

Adım 6: Kontrollerin Bir Şey Yapmasını Sağlamak

Kontrolleri Bir Şey Yaptırmak
Kontrolleri Bir Şey Yaptırmak

Şimdi bir şeyler yapmak için ihtiyacımız olan temel kullanıcı arayüzüne sahibiz. Bu örnekte, Pencere 1'deki düğmeye basıldığında bir renk seçici iletişim kutusu açacağız.

STM32CubeIDE'de projenize gidin ve MiniWinSimple_Common klasörünü açın ve ardından W1.c dosyasını açın (bu dosyanın adı, kod oluşturulduğunda JSON dosyasındaki pencerenin "Ad" alanına karşılık gelir).

Bu dosyada, window_W1_message_function() işlevini bulacaksınız. Şuna benziyor:

void window_W1_message_function(const mw_message_t *message){ MW_ASSERT(message != (void*)0, "Boş işaretçi parametresi"); /* Değişken şu anda kullanılmadığından sonraki satır derleyici uyarılarını durdurur */ (void)window_W1_data; switch (message->message_id) { case MW_WINDOW_CREATED_MESSAGE: /* Buraya herhangi bir pencere başlatma kodunu ekleyin */ break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: /* Pencere menüsü işleme kodunu buraya ekleyin */ break; case MW_BUTTON_PRESSED_MESSAGE: if (message->sender_handle == button_B1_handle) { /* Bu kontrol için işleyici kodunuzu buraya ekleyin */ } break; varsayılan: /* MISRA'yı mutlu et */ ara; } }

Bu, pencere yöneticisinin pencereye bir şey olduğunu bildirmesi gerektiğinde bu pencere için pencere yöneticisi tarafından çağrılır. Bu durumda, pencerenin tek düğmesine basıldığını bilmek istiyoruz. Mesaj türleri için switch ifadesinde MW_BUTTON_PRESSED_MESSAGE için bir durum göreceksiniz. Bu kod, düğmeye basıldığında çalışır. Bu pencerede sadece bir buton var daha fazla da olabilir bu yüzden hangi buton olduğu kontrol edilir. Bu durumda sadece B1 butonu olabilir (isim yine JSON dosyasındaki butonun adına karşılık gelir).

Bu nedenle, bu durum etiketinden sonra, bir renk seçici iletişim kutusu açmak için kodu ekleyin, bu şudur:

mw_create_window_dialog_colour_chooser(10, 10, "Renk", MW_HAL_LCD_RED, false, mesaj->recipient_handle);

Parametreler aşağıdaki gibidir:

  • 10, 10, iletişim kutusunun ekranındaki konumdur
  • "Renk", iletişim kutusunun başlığıdır
  • MW_HAL_LCD_RED, iletişim kutusunun başlayacağı varsayılan renktir
  • false, büyük boyutu göstermez (doğru olarak ayarlamayı deneyin ve farkı görün)
  • mesaj->alıcı tanıtıcısı bu iletişim kutusunun sahibidir, bu durumda bu penceredir. Bir pencerenin tutamacı, işlevin mesaj parametresindedir. Bu, diyalog yanıtının gönderileceği penceredir.

Kullanıcının seçtiği rengin değerini öğrenmek için pencere yöneticisi, kullanıcı iletişim kutusundaki OK düğmesine bastığında penceremize seçilen rengin bulunduğu bir mesaj gönderecektir. Bu nedenle, şuna benzeyen switch ifadesinde bu mesajı başka bir durumla da kesmemiz gerekiyor:

durum MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{ mw_hal_lcd_color_t selected_colour = mesaj->message_data; (void)choen_color; } kırmak;

Henüz seçilen renkle hiçbir şey yapmıyoruz, bu yüzden derleyici uyarısını önlemek için onu geçersiz kılıyoruz. Bu işlevin son kodu şimdi şöyle görünür:

void window_W1_message_function(const mw_message_t *mesaj)

{ MW_ASSERT(mesaj != (void*)0, "Boş işaretçi parametresi"); /* Değişken şu anda kullanılmadığından sonraki satır derleyici uyarılarını durdurur */ (void)window_W1_data; switch (message->message_id) { case MW_WINDOW_CREATED_MESSAGE: /* Buraya herhangi bir pencere başlatma kodunu ekleyin */ break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: /* Pencere menüsü işleme kodunu buraya ekleyin */ break; case MW_BUTTON_PRESSED_MESSAGE: if (message->sender_handle == button_B1_handle) { /* Bu kontrol için işleyici kodunuzu buraya ekleyin */ mw_create_window_dialog_color_chooser(10, 10, "Colour", MW_HAL_LCD_RED, false, message->re); } kırmak; vaka MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: { mw_hal_lcd_colour_t selected_colour = mesaj->message_data; (void)choen_color; } kırmak; varsayılan: /* MISRA'yı mutlu et */ ara; } }

Kodun çalıştırılması yukarıdaki resimde gösterilmiştir. Bir iletişim kutusu göründüğünde, başka bir şey yapmadan önce ona yanıt vermeniz ve onu kapatmanız gerektiğini fark edebilirsiniz. Buna modsal davranış denir. MiniWin'deki iletişim kutuları ve tümü her zaman küresel moddadır ve aynı anda yalnızca bir tanesini gösterebilirsiniz. Burada daha fazla açıklama var…

en.wikipedia.org/wiki/Modal_window

Adım 7: Pencerede Çizim

Pencerede Çizim
Pencerede Çizim

Şimdiye kadar sadece kontrolleri kullandık ve onlar kendilerini çiziyorlar. Penceremizde bazı özel çizimler yapmanın zamanı geldi. Çizebileceğiniz kısım, kenarlıkların içinde (varsa, isteğe bağlıdır), kaydırma çubuklarının içinde (tanımlanmışsa, ayrıca isteğe bağlıdır) ve başlık çubuğunun altındadır (varsa, bu da isteğe bağlıdır). Pencere terminolojisinde istemci alanı olarak adlandırılır.

MiniWin'de kullanabileceğiniz bir grafik komutları kitaplığı vardır. Hepsi pencere farkında. Bu, pencerenin görünür olup olmadığı, diğer pencereler tarafından kısmen kapatılıp kapatılmadığı, ekranın açık mı, kısmen kapalı mı yoksa tamamen kapalı mı olduğu veya çizim yaptığınız yerin koordinatının istemci alanında mı yoksa ötesinde mi olduğu konusunda endişelenmenize gerek olmadığı anlamına gelir.. Hepsi sizin için halledildi. Müşteri alanınızın dışına çizim yapamazsınız.

Pencere terminolojisinde istemci alanları üzerinde çizim yapmak boyama olarak adlandırılır ve çiziminizi yaptığınız her pencerenin bir boyama işlevi vardır. Siz boyama işlevinizi çağırmazsınız, gerektiğinde pencere yöneticisi bunu sizin için yapar. Bir pencere hareket ettirildiğinde veya üstteki başka bir pencerenin konumu veya görünürlüğü değiştiğinde gereklidir. Pencere içeriğinin bağlı olduğu bazı veriler değiştiği için pencerenizi yeniden boyamaya ihtiyacınız varsa (yani, pencere yöneticisinin bilmesi yerine yeniden boyamanın gerekli olduğunu biliyorsunuz), o zaman pencere yöneticisine yeniden boyamanın gerekli olduğunu söylersiniz ve pencereyi çağırır. boya işleviniz. Kendin aramıyorsun. (Bunların hepsi bir sonraki bölümde gösterilmiştir).

İlk önce, boyama işlevinizi bulmanız gerekir. Kod oluşturucu onu sizin için oluşturur ve önceki bölümde değiştirilen mesaj işleyici işlevinin hemen üzerindedir. Projenize gidin ve W1.c dosyasını yeniden açın.

Bu dosyada, window_W1_paint_function() işlevini bulacaksınız. Şuna benziyor:

void window_W1_paint_function(mw_handle_t window_handle, const mw_gl_draw_info_t *draw_info)

{ MW_ASSERT(draw_info != (void*)0, "Boş işaretçi parametresi"); /* Pencerenin istemci alanını düz beyazla doldur */ mw_gl_set_fill(MW_GL_FILL); mw_gl_set_solid_fill_color(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); /* Pencere boyama kodunu buraya ekleyin */ }

Bu, oluşturulan çıplak koddur ve tek yaptığı, istemci alanını düz beyazla doldurmaktır. Müşteri alanına sarı dolu bir daire çizelim. İlk önce bir grafik bağlamı kavramını anlamalıyız (başka bir pencere olayı). Çizim parametrelerini grafik bağlamında ayarlar ve ardından genel bir daire çizim rutini çağırırız. Bu örnekte ayarlamamız gereken şeyler dairenin bir bordürünün olup olmadığı, bordür çizgisi stili, bordür rengi, dairenin dolu olup olmadığı, dolgu rengi ve dolgu desenidir. İstemci alanını kenarlıksız, içi dolu beyaz bir dikdörtgenle doldurmak için benzer bir şey yapan yukarıdaki kodu görebilirsiniz. Grafik bağlamındaki değerler, boyama işlevinin her çağrısı arasında hatırlanmaz, bu nedenle değerleri her seferinde ayarlamanız gerekir (ancak boyama işleviyle hatırlanırlar).

Yukarıdaki kodda doldurmanın açık ve doldurma deseninin kapalı olduğunu görebilirsiniz, bu yüzden bunları tekrar ayarlamamıza gerek yok. Kenarlığı açık, kenarlık çizgisi stilini düz, kenarlık ön plan rengini siyah ve dolgu rengini sarı olarak şu şekilde ayarlamamız gerekiyor:

mw_gl_set_fg_color(MW_HAL_LCD_BLACK);

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

Bu kodu, kodunuzu eklemeniz gerektiğini söyleyen bu işlevdeki yoruma ekleyin. Daha sonra şu şekilde yapılmış bir daire çizmemiz gerekiyor:

mw_gl_circle(draw_info, 30, 30, 15);

Bu, yarıçapı 15 olan 30, 30 koordinatlarında bir daire çizer. Kodu yeniden oluşturun ve yeniden çalıştırın; yukarıda gösterildiği gibi pencerede bir daire göreceksiniz. Daire ve düğmenin üst üste geldiğini ancak düğmenin üstte olduğunu fark edeceksiniz. Bu tasarım gereğidir. Kontroller her zaman istemci alanında çizdiğiniz her şeyin üzerindedir.

Adım 8: Pencere Verileri

Pencere Verileri
Pencere Verileri

Şimdiye kadar, Pencere 1'in mesaj işlevinde (gelen mesajları işlemek için) ve boyama işlevinde (pencerenin istemci alanında çizim yapmak için) kendi kodumuzu uyguladık. Şimdi ikisini birbirine bağlamanın zamanı geldi. Boya fonksiyonunda çizilen daireyi, butona basıldığında renk seçici tarafından kullanıcının seçtiği renkle dolduralım. Boya fonksiyonunu bizim çağırmadığımızı, pencere yöneticisinin yaptığını unutmayın, bu yüzden mesaj fonksiyonumuz (seçilen rengi bilen) boyama fonksiyonunu doğrudan çağıramaz. Bunun yerine verileri önbelleğe almamız ve pencere yöneticisine yeniden boyamanın gerekli olduğunu bildirmemiz gerekiyor. Pencere yöneticisi daha sonra önbelleğe alınmış verileri kullanabilen boyama işlevini arayacaktır.

W1.c'nin en üstünde boş bir veri yapısı ve kod oluşturucu tarafından şu şekilde bildirilen bu türde bir nesne göreceksiniz:

typedef yapısı

{ /* Veri üyelerinizi buraya ekleyin */ char dummy; /* Bazı derleyiciler boş yapılardan şikayet ederler; üyelerinizi eklediğinizde bunu kaldırın */ } window_W1_data_t; statik window_W1_data_t window_W1_data;

Çağrılar arasında korunması için verilerimizi önbelleğe aldığımız yer burasıdır ve pencere verileri olarak bilinir. Sadece seçilen rengi burada saklamamız gerekiyor, şöyle:

typedef yapısı

{ /* Veri üyelerinizi buraya ekleyin */ mw_hal_lcd_color_t selected_colour; } window_W1_data_t; statik window_W1_data_t window_W1_data = { MW_HAL_LCD_YELLOW };

Ona bir başlangıç rengi sarı vereceğiz. Şimdi mesaj işlevinde, seçilen rengi burada şu şekilde kaydetmek için kodu biraz değiştireceğiz:

durum MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{ window_W1_data.chosen_color = mesaj->message_data; } kırmak;

Ardından, daireyi şu şekilde çizdiğinde bu değeri kullanmak için boya işlevini değiştireceğiz:

mw_gl_set_solid_fill_color(window_W1_data.chosen_color);

Şimdi pencerenin içeriğinin bağlı olduğu verileri değiştirdik, bu yüzden pencere yöneticisine pencerenin yeniden boyanması gerektiğini bildirmeliyiz. Bunu, diyaloğu OK mesajı alındığında mesaj işlevinde şöyle yaparız:

mw_paint_window_client(message->recipient_handle);

Bu, pencerenin doğrudan boyanmasına neden olmaz. Bu, pencere yöneticisine bir pencerenin yeniden boyanması gerektiğine dair bir mesaj gönderen bir yardımcı fonksiyondur (içine girerseniz bunun nasıl olduğunu görebilirsiniz). Bu durumda yeniden boyanması gereken pencerenin kendisidir ve pencerenin tutacağı, mesaj işleyici işlevinin mesaj parametresindedir.

Yukarıdaki kod parçacıklarının bazılarının nereye gittiğinden emin değilseniz, tüm dosya şimdi şöyle görünür:

#Dahil etmek

#include "miniwin.h" #include "miniwin_user.h" #include "W1.h" typedef struct { /* Veri üyelerinizi buraya ekleyin */ mw_hal_lcd_color_t selected_colour; } window_W1_data_t; statik 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, "Boş işaretçi parametresi"); /* Pencerenin istemci alanını düz beyazla doldur */ mw_gl_set_fill(MW_GL_FILL); mw_gl_set_solid_fill_color(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); /* Pencere boyama kodunu buraya ekleyin */ mw_gl_set_fg_colour(MW_HAL_LCD_BLACK); mw_gl_set_solid_fill_color(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 *message) { MW_ASSERT(message != (void*)0, "Boş işaretçi parametresi"); /* Değişken şu anda kullanılmadığından sonraki satır derleyici uyarılarını durdurur */ (void)window_W1_data; switch (message->message_id) { case MW_WINDOW_CREATED_MESSAGE: /* Buraya herhangi bir pencere başlatma kodunu ekleyin */ break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: /* Pencere menüsü işleme kodunu buraya ekleyin */ break; case MW_BUTTON_PRESSED_MESSAGE: if (message->sender_handle == button_B1_handle) { /* Bu kontrol için işleyici kodunuzu buraya ekleyin */ mw_create_window_dialog_color_chooser(10, 10, "Colour", MW_HAL_LCD_RED, false, message->re); } kırmak; durum MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: { window_W1_data.chosen_color = mesaj->message_data; mw_paint_window_client(message->recipient_handle); } kırmak; varsayılan: /* MISRA'yı mutlu et */ ara; } }

Tekrar oluşturun ve çalıştırın ve dairenin dolgu rengini ayarlayabilmelisiniz.

Bu pencere verileri örneği, kaynak dosyanın en üstünde statik bir veri yapısında depolanan verileri kullanır. Bu örnekte yaptığımız gibi, pencerenin yalnızca bir örneğine sahipseniz bu iyidir, ancak birden fazla örneğiniz varsa, hepsi aynı veri yapısını paylaşacaktır. Aynı pencere türünün birden çok örneğinin kendi verilerine sahip olması için örnek başına verilere sahip olmak mümkündür. Bu, docs dizininde bulunan MiniWin belgelerinde açıklanmıştır. Dosya örneği, aynı pencere türünde birden fazla görüntüyü göstermek için kullanır (bu talimatın en üstündeki ana görüntüde görüldüğü gibi).

9. Adım: Bazı Son Yazı Tipi Eğlencesi

Bazı Son Yazı Tipi Eğlencesi
Bazı Son Yazı Tipi Eğlencesi

MiniWin, TrueType yazı tipi oluşturmayı destekler. Kullanıcı arayüzünüzün güzel görünmesini sağlayan bir şey varsa, çekici yazı tipleridir. Bu son adım, bir MiniWin penceresinde TrueType yazı tipinin nasıl oluşturulacağını gösterir.

TrueType yazı tiplerini oluşturmanın iki yolu vardır. Biri, daha önce daire için yapıldığı gibi bunları doğrudan müşteri alanınıza çizmek, diğeri ise pencerenize bir metin kutusu kontrolü eklemek. Daha kolay olduğu için ikincisini yapıyoruz.

Şimdi JSON yapılandırma dosyamıza bir metin kutusu denetimi ekleyeceğiz. Pencere 2'nin tanımına şöyle görünecek şekilde ekleyin:

bunun gibi:

{

"Ad": "W2", "Başlık": "Pencere 2", "X": 50, "Y": 65, "Genişlik": 100, "Yükseklik": 80, "Kenarlık": doğru, "Başlık Çubuğu": true, "Visible": true, "Küçültülmüş": false, "Metin Kutuları": [{ "Ad": "TB1", "X": 0, "Y": 0, "Genişlik": 115, "Yükseklik": 50, "Gerekçe": "Merkez", "BackgroundColour": "MW_HAL_LCD_YELLOW", "ForegroundColour": "MW_HAL_LCD_BLACK", "Font": "mf_rlefont_BLKCHCRY16", "Etkin": true, "Görünür}: true }

MiniWin'deki TrueType yazı tipleri hakkında kısa bir bilgi. Yazı tipleri.ttf dosyalarında gelir. Daha büyük bilgisayarlardaki pencere yöneticilerinde, bunlar gerektiğinde ekranınıza işlenir. Bu, çok fazla işlem gücü ve bellek gerektirir ve küçük cihazlar için uygun değildir. MiniWin'de bunlar bitmap'lere önceden işlenir ve derleme zamanında sabit bir yazı tipi boyutu ve stilinde (kalın, italik vb.) bağlantılıdır, yani derleme zamanında hangi yazı tiplerini hangi boyutta ve stilde kullanacağınıza karar vermelisiniz. Bu, indirdiğiniz MiniWin zip dosyasındaki iki örnek yazı tipi için sizin için yapılmıştır. Diğer yazı tiplerini başka boyutlarda ve stillerde kullanmak istiyorsanız, docs klasöründeki MiniWin belgelerine bakın. Windows ve Linux için MiniWin'de.ttf dosyalarını projenize bırakabileceğiniz kaynak kod dosyalarında ön işlemeye yönelik araçlar vardır.

Ve ikinci bir kısa kelime - Microsoft Windows'ta bulacağınız yazı tipleri de dahil olmak üzere çoğu yazı tipi telif hakkına sahiptir. Bunları kişisel kullanım için istediğiniz zaman kullanın, ancak yayınladığınız her şey, MiniWin'de bulunan 2 yazı tipinde olduğu gibi, yazı tiplerinin yayınlandığı lisansın buna izin verdiğinden emin olmalısınız, ancak Microsoft'un yazı tiplerinde değil!

Koda geri dön! Dosyaları oluşturun, bırakın, oluşturun ve daha önce olduğu gibi yeniden çalıştırın ve Pencere 2'nin artık sarı bir arka plan üzerinde tuhaf bir yazı tipinde bazı varsayılan metinlere sahip olduğunu göreceksiniz. Pencere 2'nin W2.c kaynak dosyasını düzenleyerek metni değiştirelim.

Yeni oluşturduğumuz metin kutusu ile iletişim kurmamız gerekiyor ve bunu MiniWin'deki herhangi bir iletişim gibi yapmanın yolu ona bir mesaj göndermek. Pencere oluşturulduğunda, ancak gösterilmeden önce kontroldeki metni ayarlamak istiyoruz, bu nedenle MW_WINDOW_CREATED_MESSAGE durumunda mesaj işleyicisine kod ekliyoruz. Bu, pencerenin görüntülenmesinden hemen önce pencere kodu tarafından alınır ve bunun gibi başlatmalar için tasarlanmıştır. Kod oluşturucu, mesaj işleyici işlevinde şuna benzeyen bir yer tutucu oluşturdu:

durum MW_WINDOW_CREATED_MESSAGE:

/* Herhangi bir pencere başlatma kodunu buraya ekleyin */ break;

Burada, mw_post_message işlevini kullanarak hangi metni göstermesini istediğimizi söyleyen metin kutusu kontrolüne bir mesaj göndereceğiz:

durum MW_WINDOW_CREATED_MESSAGE:

/* Herhangi bir pencere başlatma kodunu buraya ekleyin */ mw_post_message(MW_TEXT_BOX_SET_TEXT_MESSAGE, message->recipient_handle, text_box_TB1_handle, 0UL, "Karanlık ve fırtınalı bir geceydi…", MW_CONTROL_MESSAGE); kırmak;

Bunlar parametrelerdir:

  • MW_TEXT_BOX_SET_TEXT_MESSAGE - Kontrole gönderdiğimiz mesaj tipi budur. Miniwin.h'de listelenmiştir ve belgelerde belgelenmiştir.
  • message->recipient_handle - Bu, iletinin kimden geldiğidir - bu pencere - tanıtıcısı ileti parametresinde bulunan ileti işleyici işlevine aktarılır.
  • text_box_TB1_handle - Mesajı kime gönderiyoruz - metin kutusu kontrolünün tutamacı. Bunlar, oluşturulan miniwin_user.h dosyasında listelenir.
  • 0UL - Veri değeri, bu durumda hiçbir şey yok.
  • "Karanlık ve fırtınalı bir geceydi…" - İşaretçi değeri - yeni metin.
  • MW_CONTROL_MESSAGE - Kontrol olan alıcı tipi.

Bu kadar. Her zamanki gibi yeniden oluşturun ve yeniden çalıştırın; yukarıdaki resimde gösterildiği gibi metin kutusunu göreceksiniz.

Mesaj gönderme, MiniWin için temeldir (tüm pencere yöneticileri için olduğu gibi). Daha fazla örnek için zip dosyasındaki örnek projelere bakın ve kapsamlı bir açıklama için belgelerdeki MiniWin mesajları bölümünü okuyun.

Adım 10: Daha İleri Gitmek

Image
Image

MiniWin'e bu temel giriş için bu kadar. MiniWin burada gösterilenden çok daha fazlasını yapabilir. Örneğin, bu talimatta kullanılan tahtadaki ekran küçüktür ve kontroller küçüktür ve bir dibber ile kullanılması gerekir. Bununla birlikte, diğer örnekler ve donanımlar, daha büyük ekranlarda daha büyük kontroller (2 boyut vardır) kullanır ve bunlar parmakla çalıştırılabilir.

Burada gösterilenlerden başka birçok kontrol türü vardır. Daha fazla kontrol için kod oluşturucu klasöründeki çeşitli örnek JSON dosyalarına bakın. Tüm kontrol türleri bu örneklerde ele alınmıştır.

Windows'un birçok seçeneği var. Kenarlık, başlık çubuğu ve simgelerin tümü yapılandırılabilir. Kaydırma çubuklarına ve kayan pencere istemci alanlarına sahip olabilirsiniz, aynı pencere türünün birden çok örneği ve pencereler çıplak olabilir (yalnızca bir istemci alanı, kenarlık veya başlık çubuğu yok), bu da bunların ekranda derleme zamanında yerinde sabitlendikleri anlamına gelir (bu bölümdeki büyük boyutlu simgelerle resme bakın - bunlar aslında 6 çıplak penceredir).

MiniWin dinamik bellek kullanmaz. Bu, onu küçük kısıtlı cihazlar için uygun hale getirir ve bazı gömülü projeler için bir gerekliliktir. MiniWin ve ürettiği kod da 'gerekli' seviyeye tamamen MISRA 2012 uyumludur.

Daha fazla bilgi için, belgeler için belgeler klasörüne ve ayrıca zip dosyasındaki diğer örnek uygulamalara bakın. Burada MiniWin'in tüm özelliklerinin nasıl kullanılacağını ve MiniWin'in FatFS ve FreeRTOS ile nasıl entegre edileceğini gösteren örnekler var.

Önerilen: