Mục lục:

Trình quản lý cửa sổ được nhúng: 10 bước
Trình quản lý cửa sổ được nhúng: 10 bước

Video: Trình quản lý cửa sổ được nhúng: 10 bước

Video: Trình quản lý cửa sổ được nhúng: 10 bước
Video: Quản lý Vận Hành Kém - Ném Tiền Qua Cửa Sổ | Minh Khôi Official 2024, Tháng bảy
Anonim
Trình quản lý cửa sổ được nhúng
Trình quản lý cửa sổ được nhúng
Trình quản lý cửa sổ được nhúng
Trình quản lý cửa sổ được nhúng
Trình quản lý cửa sổ được nhúng
Trình quản lý cửa sổ được nhúng
Trình quản lý cửa sổ được nhúng
Trình quản lý cửa sổ được nhúng

Dự án này cho thấy cách triển khai trình quản lý cửa sổ với các cửa sổ chồng lên nhau có thể di chuyển được trên một bộ điều khiển vi mô được nhúng với bảng điều khiển LCD và màn hình cảm ứng. Có những gói phần mềm thương mại có sẵn để làm điều này nhưng chúng tốn tiền và là mã nguồn đóng. Cái này, được gọi là MiniWin, là mã nguồn mở và miễn phí. Nó được viết bằng C99 hoàn toàn tuân thủ và có thể được sử dụng trong ứng dụng C hoặc C ++. Mục tiêu của MiniWin là dễ sử dụng, dễ sửa đổi, có thể mở rộng, di động với nhiều loại phần cứng và không quá ngốn tài nguyên.

Cũng như cung cấp mã để quản lý các cửa sổ của bạn, MiniWin có một bộ sưu tập các điều khiển giao diện người dùng - nút, thanh trượt, thanh tiến trình, cây, v.v. Bạn có thể có nhiều cửa sổ thuộc các loại khác nhau hoặc nhiều phiên bản của cùng một loại. Windows có thể được di chuyển xung quanh, thay đổi kích thước, tối đa hóa, thu nhỏ, đóng - tất cả những điều thông thường bạn làm với các cửa sổ trong trình quản lý cửa sổ lớn hơn. Phông chữ TrueType với kerning và khử răng cưa (làm cho văn bản trông mượt mà) cũng được hỗ trợ để kết xuất văn bản hấp dẫn.

Trong mỗi cửa sổ, bạn có một khu vực khách hàng (không gian của bạn bên trong đường viền và bên dưới thanh trên cùng). Trên này, bạn có thể thêm các điều khiển để tạo hộp thoại hoặc bạn có thể sử dụng thư viện đồ họa tích hợp để vẽ bất cứ thứ gì bạn muốn. Tất cả các chức năng của thư viện đồ họa đều nhận biết cửa sổ. Bạn không phải lo lắng về vị trí cửa sổ của mình, những gì chồng chéo lên nó hoặc nó có được thu nhỏ hay không.

Ngoài việc tạo cửa sổ của riêng bạn, còn có một số hộp thoại tiêu chuẩn đi kèm rất dễ tạo - ví dụ: hộp thoại xác nhận (chỉ là nút OK hoặc Yes / No), bộ định thời gian / ngày, bộ chọn tệp, bộ chọn màu, v.v.

MiniWin sử dụng hệ thống hàng đợi tin nhắn thiết kế trình quản lý cửa sổ tiêu chuẩn. Windows có thể tương tác với nhau và trình quản lý cửa sổ thông qua tin nhắn. Bạn không gọi các hàm để thực hiện mọi việc một cách trực tiếp, bạn thêm một thông báo vào hàng đợi và trình quản lý cửa sổ sẽ thực hiện nó cho bạn.

MiniWin đã được chuyển sang bảng phát triển tiêu chuẩn với màn hình cảm ứng từ các nhà cung cấp bộ điều khiển vi mô ST, NXP và Renesas. Có các trình điều khiển phần cứng và các dự án ví dụ cho tất cả các thiết bị này. Ngoài ra, MiniWin có thể được xây dựng cho Windows hoặc Linux để bạn có thể mô phỏng mã giao diện người dùng của mình trước khi nhận phần cứng nhúng.

MiniWin có một trình tạo mã. Bạn có thể chỉ định các cửa sổ và điều khiển của mình trong một tệp JSON đơn giản để con người có thể đọc được và trình tạo mã phân tích cú pháp tệp và tạo mã cho bạn (có rất nhiều ví dụ để làm theo). Nó tạo ra các ứng dụng giả lập hoàn chỉnh Windows hoặc Linux có thể được xây dựng và có màn hình LCD mô phỏng của bạn với các cửa sổ MiniWin của bạn đang hoạt động. Bạn có thể lấy chính xác cùng một mã được tạo và thả nó vào một dự án được nhúng và có cùng một mã hiển thị cùng các cửa sổ và điều khiển ngay sau đó trên phần cứng được nhúng của bạn.

MiniWin không yêu cầu hỗ trợ hoạt động trên thiết bị nhúng. Tất cả đều chạy trong một chủ đề duy nhất. MiniWin có thể được tích hợp với RTOS chạy trên bộ xử lý nhúng và có những ví dụ tích hợp MiniWin với FreeRTOS.

Tài liệu hướng dẫn này hướng dẫn cách khởi động và chạy MiniWin trên bộ xử lý STM32 M4 bằng bo mạch STM32F429 Discovery giá rẻ đi kèm với màn hình cảm ứng QVGA đã được đính kèm. Chúng dễ dàng có sẵn từ nhà cung cấp linh kiện điện tử của bạn.

MiniWin chạy trên bộ điều khiển vi mô tầm trung trở lên.

Quân nhu

Bảng phát triển STM32F429I-DISC1 và một cáp micro USB

Tải xuống STM32CubeIDE miễn phí.

Bước 1: Lấy mã

Lấy mã
Lấy mã

Trước hết, bạn cần cài đặt STM32CubeIDE. Bạn nhận được điều đó từ trang web của ST. Bạn phải đăng ký và phải mất một lúc để tải xuống và cài đặt nó. Tất cả đều miễn phí.

Trong khi cài đặt, hãy tải xuống nguồn MiniWin và giải nén nó. Nó lớn, nhưng bạn sẽ chỉ sử dụng một phần nhỏ của nó. Nhấp vào nút 'Sao chép hoặc Tải xuống' màu xanh lục tại đây…

github.com/miniwinwm/miniwinwm

sau đó chọn Tải xuống Zip. Giải nén nội dung.

Bước 2: Xây dựng một dự án mẫu

Xây dựng một dự án mẫu
Xây dựng một dự án mẫu
Xây dựng một dự án mẫu
Xây dựng một dự án mẫu

Đầu tiên, hãy xây dựng một trong những dự án mẫu. Một cái hay được gọi là MiniWinSimple. Khởi động STM32CubeIDE sau đó thực hiện việc này:

  1. Chọn tệp | Nhập…
  2. Mở Chung và chọn Dự án hiện có vào Không gian làm việc. Kế tiếp.
  3. Nhấp vào Duyệt qua và điều hướng đến nơi bạn đã giải nén MiniWin. Sau đó vào thư mục STM32CubeIDE / MiniWinSimple / STM32F429. Nhấp vào Chọn thư mục.
  4. Trong Project: đánh dấu vào MiniWinSimple_STM32F429 rồi nhấp vào Kết thúc.
  5. Dự án MiniWinSimple_STM32F429 sẽ xuất hiện trong Project Explorer của bạn. Chọn nó sau đó xây dựng nó với Project | Build Project.
  6. Bây giờ hãy cắm cáp USB của bạn vào bo mạch và máy tính của bạn và chạy nó bằng Run | Debug và khi nó được tải xuống, hãy chọn Run | Resume. Bạn sẽ nhận được màn hình hiệu chỉnh màn hình lần đầu tiên, vì vậy hãy chạm vào tâm của 3 dấu thập trên màn hình LCD. Bây giờ bạn có thể tương tác với cửa sổ trên màn hình.

Để di chuyển một cửa sổ, hãy kéo nó bằng thanh tiêu đề của nó. Để thay đổi kích thước cửa sổ, hãy sử dụng biểu tượng hình tam giác màu trắng ở bên trái thanh tiêu đề. Không thể thay đổi kích thước cửa sổ MiniWin bằng cách kéo viền vì màn hình MiniWin được sử dụng quá nhỏ. Để thu nhỏ, phóng to hoặc đóng cửa sổ, hãy sử dụng các biểu tượng ở đầu bên phải của thanh tiêu đề (tính năng đóng có thể bị tắt). Khi một cửa sổ được thu nhỏ, bạn không thể di chuyển các biểu tượng được thu nhỏ xung quanh. Chúng tăng dần từ dưới cùng bên trái sang bên phải.

Bước 3: Chạy Trình tạo mã

Chạy Trình tạo mã
Chạy Trình tạo mã

Bây giờ chúng ta sẽ thay đổi dự án mẫu bằng cách tạo một số cửa sổ của riêng chúng ta và thả mã mới vào. Để làm điều này, chúng ta sẽ chạy trình tạo mã.

  1. Mở dấu nhắc lệnh và đi tới thư mục bạn đã giải nén MiniWin rồi đến thư mục Tools / CodeGen.
  2. Tệp thực thi cho Windows CodeGen.exe đã có sẵn. Đối với Linux, bạn phải xây dựng nó bằng cách gõ lệnh make. (Bạn cũng có thể xây dựng nó từ nguồn dành cho Windows nếu bạn lo lắng về việc chạy tệp thực thi đã tải xuống nhưng bạn cần cài đặt trình biên dịch và môi trường phát triển. Xem tài liệu MiniWin trong thư mục docs để biết chi tiết).
  3. Trong thư mục này là một số tệp JSON mẫu. Chúng tôi sẽ sử dụng example_empty.json. Bạn cần chỉnh sửa nó trước để thiết lập nó cho Windows hoặc Linux. Mở nó trong trình chỉnh sửa và ở trên cùng, bạn sẽ thấy "TargetType" thay đổi giá trị "Linux" hoặc "Windows" thành giá trị bạn đang chạy trình tạo mã.
  4. Bây giờ gõ codegen example_empty.json trong dấu nhắc lệnh.
  5. Đi tới dự án của bạn trong STM32CubeIDE và mở thư mục MiniWinSimple_Common. Xóa tất cả các tệp trong đó.
  6. Chúng tôi đã để "TargetName" trong tệp JSON làm mặc định tại "MiniWinGen", vì vậy đó là tên của thư mục mã đã tạo của chúng tôi. Chuyển đến thư mục mà bạn đã giải nén MiniWin và sau đó là thư mục MiniWinGen_Common. Bây giờ chọn tất cả các tệp này và kéo và thả sau đó vào STM32CubeIDE trong thư mục MiniWinSimple_Common của dự án của bạn.
  7. Bây giờ xây dựng lại và chạy lại dự án trong STM32CubeIDE và cửa sổ thiết kế mới của bạn sẽ xuất hiện. Nút trong cửa sổ đã biến mất vì example_empty.json không xác định bất kỳ nút nào.

Bước 4: Thêm cửa sổ

Thêm một cửa sổ
Thêm một cửa sổ

Bây giờ chúng tôi sẽ thêm cửa sổ thứ hai vào tệp cấu hình JSON và tạo lại mã.

1. Mở example_empty.json trong trình soạn thảo văn bản.

2. Trong phần "Windows" có một loạt các định nghĩa cửa sổ hiện chỉ có một cửa sổ. Sao chép tất cả điều này…

{

"Tên": "W1", "Tiêu đề": "Cửa sổ 1", "X": 10, "Y": 15, "Chiều rộng": 200, "Chiều cao": 180, "Đường viền": true, "Thanh tiêu đề": true, "Visible": true, "Minimized": false}

và dán lại bằng dấu phẩy ngăn cách 2 định nghĩa.

3. Thay đổi "W1" thành "W2" và "Window 1" thành "Window 2". Thay đổi "X", "Y", "Width" và "Height" thành một số giá trị khác nhau, lưu ý độ phân giải màn hình là 240 rộng x 320 cao.

4. Lưu tệp và chạy lại trình tạo mã.

5. Sao chép các tập tin như trong bước trước, xây dựng lại và chạy lại. Bây giờ bạn sẽ có 2 cửa sổ trên màn hình của mình.

Bước 5: Thêm điều khiển

Thêm điều khiển
Thêm điều khiển

Bây giờ chúng tôi sẽ thêm một số điều khiển vào cửa sổ mới của bạn. Chỉnh sửa tệp tương tự như trong bước trước.

1. Trong thông số kỹ thuật cho cửa sổ W1, hãy thêm dấu phẩy sau cài đặt cuối cùng ("Minimized": false) sau đó thêm văn bản này

"MenuBar": true, "MenuBarEnabled": true, "MenuItems": ["Fred", "Bert", "Pete", "Alf", "Ian"], "Buttons": [{"Name": "B1", "Label": "Button1", "X": 10, "Y": 10, "Đã bật": true, "Hiển thị": true}]

Phần này thêm một thanh menu với 5 mục và bật nó lên (thanh menu có thể bị vô hiệu hóa trên toàn cầu, hãy thử nó). Nó cũng thêm một nút được bật và hiển thị (chúng có thể được tạo ẩn và sau đó hiển thị trong mã sau này).

2. Tạo lại mã, sao chép mã, xây dựng lại, chạy lại tất cả như trước.

Bước 6: Làm cho các điều khiển làm điều gì đó

Làm cho các điều khiển làm điều gì đó
Làm cho các điều khiển làm điều gì đó

Bây giờ chúng ta có giao diện người dùng cơ bản mà chúng ta cần để làm cho nó hoạt động. Đối với ví dụ này, chúng tôi sẽ bật lên hộp thoại chọn màu khi nhấn nút trong Cửa sổ 1.

Đi tới dự án của bạn trong STM32CubeIDE và mở thư mục MiniWinSimple_Common rồi mở tệp W1.c (tên của tệp này tương ứng với trường "Tên" của cửa sổ trong tệp JSON khi mã được tạo).

Trong tệp này, bạn sẽ tìm thấy hàm window_W1_message_ Chức năng (). Nó trông như thế này:

void window_W1_message_ Chức năng (const mw_message_t * message) {MW_ASSERT (message! = (void *) 0, "Null pointer parameter"); / * Dòng tiếp theo dừng cảnh báo trình biên dịch vì biến hiện không được sử dụng * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Thêm bất kỳ mã khởi tạo cửa sổ nào tại đây * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Thêm mã xử lý menu cửa sổ tại đây * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Thêm mã xử lý của bạn cho điều khiển này tại đây * /} break; default: / * Giữ cho MISRA vui vẻ * / break; }}

Điều này được gọi bởi trình quản lý cửa sổ cho cửa sổ này bất cứ khi nào trình quản lý cửa sổ cần cho cửa sổ biết rằng điều gì đó đã xảy ra. Trong trường hợp này, chúng tôi muốn biết rằng nút duy nhất của cửa sổ đã được nhấn. Trong câu lệnh chuyển đổi cho các loại tin nhắn, bạn sẽ thấy một trường hợp cho MW_BUTTON_PRESSED_MESSAGE. Mã này chạy khi nút đã được nhấn. Chỉ có một nút trong cửa sổ này, nhưng có thể có nhiều nút hơn, vì vậy hãy kiểm tra xem đó là nút nào. Trong trường hợp này, nó chỉ có thể là nút B1 (tên tương ứng với tên của nút trong tệp JSON một lần nữa).

Vì vậy, sau nhãn trường hợp này, hãy thêm mã để bật lên hộp thoại chọn màu, đó là:

mw_create_window_dialog_colour_chooser (10, 10, "Màu", MW_HAL_LCD_RED, false, message-> receiver_handle);

Các thông số như sau:

  • 10, 10 là vị trí trên màn hình của hộp thoại
  • "Màu" là tiêu đề của hộp thoại
  • MW_HAL_LCD_RED là màu mặc định mà hộp thoại sẽ bắt đầu với
  • false nghĩa là không hiển thị kích thước lớn (hãy thử đặt nó thành true và xem sự khác biệt)
  • message-> tay cầm người nhận là người sở hữu hộp thoại này, trong trường hợp này là cửa sổ này. Xử lý của một cửa sổ nằm trong tham số thông báo của hàm. Đây là cửa sổ phản hồi hộp thoại sẽ được gửi đến.

Để tìm ra giá trị của màu mà người dùng đã chọn, trình quản lý cửa sổ sẽ gửi cho cửa sổ của chúng ta một thông báo có màu đã chọn khi người dùng nhấn nút OK trong hộp thoại. Do đó, chúng ta cũng cần chặn thông báo này bằng một trường hợp khác trong câu lệnh switch trông giống như sau:

trường hợp MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{mw_hal_lcd_colour_t selected_colour = message-> message_data; (vô hiệu) màu sắc được chọn; } nghỉ;

Chúng tôi chưa làm bất cứ điều gì với màu đã chọn vì vậy chỉ cần chuyển nó thành vô hiệu để ngăn cảnh báo trình biên dịch. Mã cuối cùng của hàm này bây giờ trông giống như sau:

void window_W1_message_ Chức năng (thông báo const mw_message_t *)

{MW_ASSERT (message! = (Void *) 0, "Tham số con trỏ rỗng"); / * Dòng tiếp theo dừng cảnh báo trình biên dịch vì biến hiện không được sử dụng * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Thêm bất kỳ mã khởi tạo cửa sổ nào tại đây * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Thêm mã xử lý menu cửa sổ tại đây * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Thêm mã xử lý của bạn cho điều khiển này tại đây * / mw_create_window_dialog_colour_chooser (10, 10, "Màu", MW_HAL_LCD_RED, false, message-> người nhận_handle); } nghỉ; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {mw_hal_lcd_colour_t selected_colour = message-> message_data; (vô hiệu) màu sắc được chọn; } nghỉ; default: / * Giữ cho MISRA vui vẻ * / break; }}

Chạy mã được hiển thị trong hình trên. Bạn có thể nhận thấy rằng khi một hộp thoại hiển thị, bạn phải trả lời nó và loại bỏ nó trước khi bạn làm bất cứ điều gì khác. Đây được gọi là hành vi phương thức. Hộp thoại trong MiniWin và tất cả luôn theo phương thức toàn cầu và bạn chỉ có thể hiển thị một hộp thoại tại một thời điểm. Có nhiều lời giải thích hơn ở đây…

en.wikipedia.org/wiki/Modal_window

Bước 7: Vẽ trong cửa sổ

Vẽ trong cửa sổ
Vẽ trong cửa sổ

Cho đến nay, chúng tôi chỉ sử dụng các điều khiển và chúng tự vẽ. Đã đến lúc thực hiện một số bản vẽ tùy chỉnh trên cửa sổ của chúng tôi. Phần bạn có thể vẽ ở bên trong các đường viền (nếu có, chúng là tùy chọn), bên trong thanh cuộn (nếu được xác định, cũng là tùy chọn) và bên dưới thanh tiêu đề (nếu có thì cũng là tùy chọn). Nó được gọi là khu vực khách hàng trong thuật ngữ cửa sổ.

Có một thư viện các lệnh đồ họa trong MiniWin mà bạn có thể sử dụng. Họ đều nhận biết được cửa sổ. Điều đó có nghĩa là bạn không phải lo lắng về việc nếu cửa sổ có thể nhìn thấy, một phần bị che khuất bởi các cửa sổ khác, bật, tắt một phần hoặc hoàn toàn khỏi màn hình, hoặc nếu tọa độ của nơi bạn đang vẽ nằm trên khu vực khách hàng hoặc xa hơn nó.. Tất cả đều được chăm sóc cho bạn. Bạn không thể vẽ bên ngoài khu vực khách hàng của mình.

Thuật ngữ vẽ trên các khu vực khách hàng trong windows được gọi là vẽ và mọi cửa sổ đều có chức năng sơn để bạn thực hiện việc vẽ của mình. Bạn không gọi chức năng sơn của mình, trình quản lý cửa sổ sẽ thực hiện điều đó cho bạn khi cần thiết. Nó cần thiết khi một cửa sổ được di chuyển hoặc một cửa sổ khác trên cùng bị thay đổi vị trí hoặc khả năng hiển thị. Nếu bạn cần sơn lại cửa sổ của mình vì một số dữ liệu mà nội dung của cửa sổ phụ thuộc vào đã thay đổi (tức là bạn biết rằng cần sơn lại chứ không phải trình quản lý cửa sổ biết), thì bạn nói với người quản lý cửa sổ rằng cần sơn lại và nó sẽ gọi chức năng sơn của bạn. Bạn không gọi nó cho chính mình. (Tất cả điều này được chứng minh trong phần tiếp theo).

Đầu tiên, bạn cần tìm chức năng sơn của mình. Trình tạo mã tạo nó cho bạn và nó nằm ngay phía trên chức năng xử lý thông báo đã được sửa đổi trong phần trước. Đi tới dự án của bạn và mở lại tệp W1.c.

Trong tệp này, bạn sẽ tìm thấy hàm window_W1_paint_ Chức năng (). Nó trông như thế này:

void window_W1_paint_ Chức năng (mw_handle_t window_handle, const mw_gl_draw_info_t * draw_info)

{MW_ASSERT (draw_info! = (Void *) 0, "Tham số con trỏ rỗng"); / * Tô vùng máy khách của cửa sổ bằng màu trắng đặc * / 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); / * Thêm mã sơn cửa sổ cho bạn tại đây * /}

Đây là mã được tạo trần và tất cả những gì nó làm là tô màu trắng đồng nhất cho khu vực khách hàng. Hãy vẽ một vòng tròn màu vàng trên khu vực khách hàng. Đầu tiên chúng ta phải hiểu khái niệm về bối cảnh đồ họa (một điều khác của windows). Chúng tôi thiết lập các thông số bản vẽ trong ngữ cảnh đồ họa và sau đó gọi một quy trình vẽ vòng tròn chung. Những thứ chúng ta phải đặt trong ví dụ này là hình tròn có đường viền không, kiểu đường viền, màu đường viền, hình tròn có được tô hay không, màu tô và mẫu tô. Bạn có thể thấy đoạn mã ở trên thực hiện một cái gì đó tương tự để lấp đầy khu vực khách hàng bằng một hình chữ nhật màu trắng đặc không viền. Các giá trị trong ngữ cảnh đồ họa không được nhớ giữa mỗi lần gọi hàm paint, vì vậy bạn phải thiết lập các giá trị mỗi lần (mặc dù chúng được ghi nhớ với hàm paint).

Trong đoạn mã trên, bạn có thể thấy rằng điền vào đang bật và mẫu điền đã tắt, vì vậy chúng ta không cần thiết lập lại chúng. Chúng ta cần đặt đường viền trên, kiểu đường viền thành đồng nhất, màu nền trước của đường viền thành màu đen và màu tô thành màu vàng như sau:

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

Thêm mã này tại nhận xét trong chức năng này, nơi nó cho biết thêm mã của bạn. Tiếp theo, chúng ta cần vẽ một vòng tròn được thực hiện như sau:

mw_gl_circle (draw_info, 30, 30, 15);

Thao tác này vẽ một vòng tròn tại tọa độ 30, 30 với bán kính 15. Xây dựng lại mã và chạy lại nó và bạn sẽ thấy một vòng tròn trong cửa sổ như hình trên. Bạn sẽ nhận thấy rằng vòng tròn và nút chồng lên nhau nhưng nút ở trên cùng. Đây là do thiết kế. Kiểm soát luôn nằm trên bất kỳ thứ gì bạn vẽ trên khu vực khách hàng.

Bước 8: Dữ liệu cửa sổ

Dữ liệu cửa sổ
Dữ liệu cửa sổ

Cho đến nay, chúng tôi đã triển khai mã của riêng mình trong chức năng thông báo của Window 1 (để xử lý các thông báo đến) và chức năng sơn của nó (để vẽ trên vùng khách của cửa sổ). Bây giờ là lúc để liên kết hai. Cho phép tô màu vòng tròn được vẽ trong chức năng sơn bằng màu mà người dùng chọn bằng trình chọn màu khi nhấn nút. Hãy nhớ rằng chúng ta không gọi hàm sơn, trình quản lý cửa sổ thực hiện điều đó, vì vậy hàm thông báo của chúng ta (biết màu đã chọn) không thể gọi trực tiếp hàm sơn. Thay vào đó, chúng ta cần lưu trữ dữ liệu vào bộ nhớ cache và cho trình quản lý cửa sổ biết rằng cần phải sơn lại. Trình quản lý cửa sổ sau đó sẽ gọi hàm paint có thể sử dụng dữ liệu đã lưu trong bộ nhớ cache.

Ở đầu W1.c, bạn sẽ thấy một cấu trúc dữ liệu trống và một đối tượng kiểu này được khai báo bởi trình tạo mã như thế này:

typedef struct

{/ * Thêm thành viên dữ liệu của bạn tại đây * / char dummy; / * Một số trình biên dịch phàn nàn về cấu trúc trống; loại bỏ điều này khi bạn thêm thành viên của mình * /} window_W1_data_t; static window_W1_data_t window_W1_data;

Đây là nơi chúng tôi lưu dữ liệu của mình vào bộ nhớ cache để dữ liệu được lưu giữ trong các cuộc gọi và được gọi là dữ liệu cửa sổ. Chúng tôi chỉ cần lưu trữ màu đã chọn ở đây, như sau:

typedef struct

{/ * Thêm thành viên dữ liệu của bạn tại đây * / mw_hal_lcd_colour_t selected_colour; } window_W1_data_t; static window_W1_data_t window_W1_data = {MW_HAL_LCD_YELLOW};

Chúng tôi sẽ cung cấp cho nó một màu bắt đầu là màu vàng. Bây giờ trong chức năng tin nhắn, chúng tôi sẽ thay đổi mã một chút để lưu màu đã chọn ở đây như sau:

trường hợp MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{window_W1_data.chosen_colour = message-> message_data; } nghỉ;

Sau đó, chúng ta sẽ thay đổi hàm paint để sử dụng giá trị này khi nó vẽ hình tròn như thế này:

mw_gl_set_solid_fill_colour (window_W1_data.chosen_colour);

Bây giờ chúng ta đã thay đổi dữ liệu mà nội dung của cửa sổ phụ thuộc vào, vì vậy chúng ta cần cho người quản lý cửa sổ biết rằng cửa sổ cần sơn lại. Chúng tôi làm điều đó trong chức năng thông báo khi hộp thoại OK nhận được thông báo, như sau:

mw_paint_window_client (tin nhắn-> người nhận);

Điều này không làm cho cửa sổ bị sơn trực tiếp. Nó là một chức năng tiện ích gửi một thông báo đến trình quản lý cửa sổ rằng một cửa sổ cần được sơn lại (nếu bạn bước vào đó, bạn có thể thấy điều này xảy ra như thế nào). Cửa sổ cần được sơn lại trong trường hợp này là chính nó và phần xử lý của cửa sổ nằm trong tham số thông báo của hàm xử lý thông báo.

Toàn bộ tệp bây giờ trông giống như thế này nếu bạn không chắc chắn một số đoạn mã ở trên đi đâu:

#bao gồm

#include "miniwin.h" #include "miniwin_user.h" #include "W1.h" typedef struct {/ * Thêm thành viên dữ liệu của bạn tại đây * / 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_ Chức năng (mw_handle_t window_handle, const mw_gl_draw_info_t * draw_info) {MW_ASSERT (draw_info! = (void *) 0, "Tham số con trỏ rỗng"); / * Tô vùng máy khách của cửa sổ bằng màu trắng đặc * / 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); / * Thêm mã vẽ cửa sổ cho bạn tại đây * / 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_ Chức năng (const mw_message_t * message) {MW_ASSERT (message! = (void *) 0, "Null pointer parameter"); / * Dòng tiếp theo dừng cảnh báo trình biên dịch vì biến hiện không được sử dụng * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Thêm bất kỳ mã khởi tạo cửa sổ nào tại đây * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Thêm mã xử lý menu cửa sổ tại đây * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Thêm mã xử lý của bạn cho điều khiển này tại đây * / mw_create_window_dialog_colour_chooser (10, 10, "Màu", MW_HAL_LCD_RED, false, message-> người nhận_handle); } nghỉ; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {window_W1_data.chosen_colour = message-> message_data; mw_paint_window_client (tin nhắn-> người nhận); } nghỉ; default: / * Giữ cho MISRA vui vẻ * / break; }}

Xây dựng và chạy lại và bạn sẽ có thể đặt màu tô của hình tròn.

Ví dụ về dữ liệu cửa sổ này sử dụng dữ liệu được lưu trữ trong cấu trúc dữ liệu tĩnh ở trên cùng của tệp nguồn. Điều này là tốt nếu bạn chỉ có một phiên bản của cửa sổ, như chúng ta làm trong ví dụ này, nhưng nếu bạn có nhiều phiên bản thì tất cả chúng sẽ chia sẻ cùng một cấu trúc dữ liệu. Có thể có dữ liệu cho mỗi phiên bản để nhiều phiên bản của cùng một loại cửa sổ có dữ liệu riêng của chúng. Điều này được giải thích trong tài liệu MiniWin có trong thư mục tài liệu. Ví dụ về tệp sử dụng nó để hiển thị nhiều hình ảnh trong cùng một loại cửa sổ (như được thấy trong hình ảnh chính ở phía trên cùng của hướng dẫn này).

Bước 9: Một số phông chữ thú vị cuối cùng

Một số phông chữ cuối cùng thú vị
Một số phông chữ cuối cùng thú vị

MiniWin hỗ trợ kết xuất phông chữ TrueType. Nếu có một thứ làm cho giao diện người dùng của bạn trông đẹp thì đó là phông chữ hấp dẫn. Bước cuối cùng này cho thấy cách hiển thị phông chữ TrueType trong cửa sổ MiniWin.

Có hai cách hiển thị phông chữ TrueType. Một là vẽ chúng trực tiếp trên khu vực khách hàng của bạn như đã được thực hiện cho vòng kết nối trước đó, hai là thêm điều khiển hộp văn bản vào cửa sổ của bạn. Chúng tôi đang làm phần sau vì nó dễ dàng hơn.

Bây giờ chúng ta sẽ thêm điều khiển hộp văn bản vào tệp cấu hình JSON của chúng ta. Thêm nó vào định nghĩa của Window 2 để nó trông giống như sau:

như thế này:

{

"Tên": "W2", "Tiêu đề": "Cửa sổ 2", "X": 50, "Y": 65, "Chiều rộng": 100, "Chiều cao": 80, "Đường viền": true, "Thanh tiêu đề": true, "Visible": true, "Minimized": false, "TextBox": [{"Name": "TB1", "X": 0, "Y": 0, "Width": 115, "Height": 50, "Biện minh": "Trung tâm", "Màu nền": "MW_HAL_LCD_YELLOW", "Màu nền trước": "MW_HAL_LCD_BLACK", "Phông chữ": "mf_rlefont_BLKCHCRY16", "Đã bật": true, "Hiển thị": true}]}

Giới thiệu sơ lược về phông chữ TrueType trong MiniWin. Phông chữ có trong tệp.ttf. Trong trình quản lý cửa sổ trên các máy tính lớn hơn, chúng được hiển thị trên màn hình của bạn khi cần thiết. Điều này tốn nhiều sức mạnh xử lý và bộ nhớ và không phù hợp với các thiết bị nhỏ. Trong MiniWin, chúng được xử lý trước thành bitmap và được liên kết tại thời điểm biên dịch ở kích thước và kiểu phông chữ cố định (đậm, nghiêng, v.v.), tức là bạn phải quyết định phông chữ nào ở kích thước và kiểu bạn sẽ sử dụng tại thời điểm biên dịch. Điều này đã được thực hiện cho bạn đối với hai phông chữ ví dụ trong tệp nén MiniWin mà bạn đã tải xuống. Nếu bạn muốn sử dụng các phông chữ khác ở các kích thước và kiểu khác, hãy xem tài liệu MiniWin trong thư mục tài liệu. Có các công cụ trong MiniWin dành cho Windows và Linux để xử lý trước tệp.ttf thành tệp mã nguồn mà bạn có thể thả vào dự án của mình.

Và một từ nhanh thứ hai - hầu hết các phông chữ đều có bản quyền, bao gồm cả những phông chữ bạn sẽ tìm thấy trong Microsoft Windows. Sử dụng chúng theo ý muốn cho mục đích cá nhân, nhưng bất cứ điều gì bạn xuất bản bạn phải đảm bảo rằng giấy phép mà phông chữ được xuất bản cho phép điều đó, như trường hợp của 2 phông chữ có trong MiniWin, nhưng không phải phông chữ của Microsoft!

Quay lại mã! Tạo, thả tệp, xây dựng và chạy lại như trước và bạn sẽ thấy Window 2 hiện có một số văn bản mặc định trên nền màu vàng với phông chữ lập dị. Cho phép thay đổi văn bản bằng cách chỉnh sửa tệp nguồn của Window 2 là W2.c.

Chúng tôi cần giao tiếp với hộp văn bản mà chúng tôi vừa tạo và cách bạn làm điều đó giống như bất kỳ giao tiếp nào trong MiniWin là gửi tin nhắn cho nó. Chúng tôi muốn đặt văn bản trong điều khiển khi cửa sổ được tạo nhưng trước khi nó được hiển thị, vì vậy chúng tôi thêm mã vào trình xử lý thông báo trong trường hợp MW_WINDOW_CREATED_MESSAGE. Điều này được nhận bởi mã cửa sổ ngay trước khi cửa sổ được hiển thị và dành cho những lần khởi tạo như thế này. Trình tạo mã đã tạo một trình giữ chỗ trông giống như thế này trong chức năng xử lý thư:

trường hợp MW_WINDOW_CREATED_MESSAGE:

/ * Thêm bất kỳ mã khởi tạo cửa sổ nào tại đây * / break;

Ở đây, chúng tôi sẽ đăng một thông báo lên điều khiển hộp văn bản cho nó biết chúng tôi muốn nó hiển thị văn bản nào bằng cách sử dụng hàm mw_post_message như sau:

trường hợp MW_WINDOW_CREATED_MESSAGE:

/ * Thêm bất kỳ mã khởi tạo cửa sổ nào tại đây * / mw_post_message (MW_TEXT_BOX_SET_TEXT_MESSAGE, message-> receiver_handle, text_box_TB1_handle, 0UL, "Hai là một đêm tối và giông bão…", MW_CONTROL_MESSAGE); nghỉ;

Đây là các thông số:

  • MW_TEXT_BOX_SET_TEXT_MESSAGE - Đây là loại thông báo mà chúng tôi đang gửi tới bộ điều khiển. Chúng được liệt kê trong miniwin.h và được ghi lại trong tài liệu.
  • message-> receiver_handle - Đây là thư đến từ ai - cửa sổ này - xử lý của nó nằm trong tham số thông báo được truyền vào hàm xử lý thông báo.
  • text_box_TB1_handle - Chúng tôi đang gửi tin nhắn cho ai - tay cầm của điều khiển hộp văn bản. Chúng được liệt kê trong tệp miniwin_user.h đã tạo.
  • 0UL - Giá trị dữ liệu, không có gì trong trường hợp này.
  • "Hai lần một đêm tối và giông bão …" - Giá trị con trỏ - văn bản mới.
  • MW_CONTROL_MESSAGE - Loại người nhận là điều khiển.

Đó là nó. Xây dựng lại và chạy lại như bình thường và bạn sẽ nhận được hộp văn bản hiển thị như trong hình trên.

Đăng tin nhắn là điều cơ bản đối với MiniWin (đối với tất cả các trình quản lý cửa sổ). Để biết thêm ví dụ, hãy xem các dự án ví dụ trong tệp zip và để có giải thích toàn diện, hãy đọc phần về thông báo MiniWin trong tài liệu.

Bước 10: Tiến xa hơn

Image
Image

Đó là phần giới thiệu cơ bản về MiniWin này. MiniWin có thể làm được nhiều hơn những gì đã được chứng minh ở đây. Ví dụ: màn hình trên bảng được sử dụng trong hướng dẫn này nhỏ và các nút điều khiển cũng nhỏ và cần được sử dụng bằng máy cắt. Tuy nhiên, các ví dụ và phần cứng khác sử dụng các điều khiển lớn hơn (có 2 kích thước) trên màn hình lớn hơn và chúng có thể được thao tác bằng ngón tay.

Có nhiều loại kiểm soát khác với những loại được trình bày ở đây. Để có các điều khiển khác, hãy xem các tệp JSON mẫu khác nhau trong thư mục trình tạo mã. Tất cả các loại điều khiển được đề cập trong các ví dụ này.

Windows có rất nhiều tùy chọn. Đường viền, thanh tiêu đề và các biểu tượng đều có thể định cấu hình. Bạn có thể có các thanh cuộn và các vùng khách cửa sổ cuộn, nhiều phiên bản của cùng một loại cửa sổ và các cửa sổ có thể ở trạng thái trống (chỉ một vùng khách, không có đường viền hoặc thanh tiêu đề) có nghĩa là chúng được cố định tại thời điểm biên dịch tại chỗ trên màn hình (xem hình ảnh trong phần này với các biểu tượng kích thước lớn - đây thực sự là 6 cửa sổ trần).

MiniWin không sử dụng bộ nhớ động. Điều này làm cho nó phù hợp với các thiết bị hạn chế nhỏ và là một yêu cầu đối với một số dự án nhúng. MiniWin và mã mà nó tạo ra cũng hoàn toàn tuân thủ MISRA 2012 ở mức 'yêu cầu'.

Để biết thêm thông tin, hãy xem trong thư mục tài liệu để biết tài liệu và các ứng dụng mẫu khác trong tệp zip. Ở đây có các ví dụ cho thấy cách sử dụng tất cả các tính năng của MiniWin và cách tích hợp MiniWin với FatFS và FreeRTOS.

Đề xuất: