Встроенный оконный менеджер: 10 шагов
Встроенный оконный менеджер: 10 шагов
Anonim
Встроенный оконный менеджер
Встроенный оконный менеджер
Встроенный оконный менеджер
Встроенный оконный менеджер
Встроенный оконный менеджер
Встроенный оконный менеджер
Встроенный оконный менеджер
Встроенный оконный менеджер

В этом проекте показано, как реализовать оконный менеджер с перемещаемыми перекрывающимися окнами на встроенном микроконтроллере с ЖК-панелью и сенсорным экраном. Для этого существуют коммерчески доступные пакеты программного обеспечения, но они стоят денег и имеют закрытый исходный код. Этот, называемый MiniWin, является бесплатным и имеет открытый исходный код. Он написан на полностью совместимом C99 и может использоваться в приложении C или C ++. Цели MiniWin - быть простым в использовании, легко модифицируемым, расширяемым, переносимым на широкий спектр оборудования и не слишком требовательным к ресурсам.

Помимо предоставления кода для управления вашими окнами, MiniWin имеет набор элементов управления пользовательского интерфейса - кнопок, ползунков, индикаторов выполнения, деревьев и т. Д. У вас может быть несколько окон разных типов или несколько экземпляров одного и того же типа. Окна можно перемещать, изменять их размер, увеличивать, свертывать, закрывать - все, что вы обычно делаете с окнами в более крупных оконных менеджерах. Шрифты TrueType с кернингом и сглаживанием (придает тексту гладкий вид) также поддерживаются для привлекательного рендеринга текста.

В каждом окне у вас есть клиентская область (ваше пространство внутри границы и под верхней панелью). Здесь вы можете добавить элементы управления, чтобы создать диалог, или вы можете использовать встроенную графическую библиотеку, чтобы рисовать все, что захотите. Все функции графической библиотеки работают с окнами. Вам не нужно беспокоиться о том, где находится ваше окно, что перекрывает его или свернуто ли оно.

В дополнение к созданию ваших собственных окон, есть также некоторые стандартные диалоговые окна, которые очень легко создать - например, диалоговые окна подтверждения (просто кнопки ОК или Да / Нет), средства установки времени / даты, средства выбора файлов, средства выбора цвета и т. Д.

MiniWin использует стандартную систему очередей сообщений оконного менеджера. Windows может взаимодействовать друг с другом и с оконным менеджером через сообщения. Вы не вызываете функции, чтобы делать что-то напрямую, вы добавляете сообщение в очередь, и оконный менеджер вводит его в действие за вас.

MiniWin был перенесен на стандартные платы разработки с сенсорными дисплеями от производителей микроконтроллеров ST, NXP и Renesas. Для всех этих устройств есть драйверы оборудования и примеры проектов. Кроме того, MiniWin может быть построен для Windows или Linux, чтобы вы могли моделировать код пользовательского интерфейса до того, как приобретете встроенное оборудование.

MiniWin имеет генератор кода. Вы можете указать свои окна и элементы управления в простом для создания удобочитаемом файле JSON, а генератор кода проанализирует файл и создаст для вас код (есть множество примеров для подражания). Он создает готовые приложения-симуляторы для Windows или Linux, которые можно просто построить, и есть ваш смоделированный ЖК-дисплей с работающими окнами MiniWin. Вы можете взять точно такой же сгенерированный код и поместить его во встраиваемый проект, и через несколько мгновений тот же код будет отображать те же окна и элементы управления на встроенном оборудовании.

MiniWin не требует операционной поддержки на встроенном устройстве. Все это выполняется в одном потоке. MiniWin можно интегрировать с ОСРВ, работающей на встроенном процессоре, и есть примеры интеграции MiniWin с FreeRTOS.

В этом руководстве показано, как запустить MiniWin на процессоре STM32 M4 с помощью дешевой платы STM32F429 Discovery, которая поставляется с уже подключенным сенсорным дисплеем QVGA. Их легко получить у поставщика электронных компонентов.

MiniWin работает на микроконтроллерах среднего уровня и выше.

Запасы

Плата разработки STM32F429I-DISC1 и кабель micro USB

STM32CubeIDE скачать бесплатно.

Шаг 1. Получение кода

Получение кода
Получение кода

Прежде всего вам необходимо установить STM32CubeIDE. Вы получите это с веб-сайта ST. Вы должны зарегистрироваться, и его загрузка и установка займет некоторое время. Все это бесплатно.

Во время установки загрузите исходный код MiniWin и разархивируйте его. Он большой, но вы будете использовать только небольшую его часть. Нажмите здесь зеленую кнопку "Клонировать или скачать"…

github.com/miniwinwm/miniwinwm

затем выберите Download Zip. Разархивируйте содержимое.

Шаг 2: создание примера проекта

Создание примера проекта
Создание примера проекта
Создание примера проекта
Создание примера проекта

Сначала создадим один из примеров проектов. Хороший называется MiniWinSimple. Запустите STM32CubeIDE, затем сделайте следующее:

  1. Выберите Файл | Импорт…
  2. Откройте «Общие» и выберите «Существующий проект в рабочей области». Следующий.
  3. Нажмите «Обзор» и перейдите туда, где вы разархивировали MiniWin. Затем перейдите в папку STM32CubeIDE / MiniWinSimple / STM32F429. Щелкните Выбрать папку.
  4. В Project: отметьте MiniWinSimple_STM32F429, затем нажмите Finish.
  5. Проект MiniWinSimple_STM32F429 появится в обозревателе проектов. Выберите его, затем создайте с помощью Project | Build Project.
  6. Теперь подключите USB-кабель к плате и компьютеру и запустите его, используя Run | Debug, а когда он будет загружен, выберите Run | Resume. В первый раз вы получите отображение калибровки экрана, поэтому коснитесь центра трех крестиков на ЖК-дисплее. Теперь вы можете взаимодействовать с окном на дисплее.

Чтобы переместить окно, перетащите его за строку заголовка. Чтобы изменить размер окна, используйте значок белого треугольника слева от строки заголовка. Размер окон MiniWin нельзя изменить, перетаскивая границы, поскольку дисплеи, на которых используется MiniWin, слишком малы. Чтобы свернуть, развернуть или закрыть окно, используйте значки в правом конце строки заголовка (закрытие может быть отключено). Когда окно свернуто, вы не можете перемещать свернутые значки. Они нарастают снизу слева направо.

Шаг 3: Запуск генератора кода

Запуск генератора кода
Запуск генератора кода

Теперь мы изменим пример проекта, сгенерировав несколько собственных окон и вставив в них новый код. Для этого мы запустим генератор кода.

  1. Откройте командную строку и перейдите в папку, в которую вы распаковали MiniWin, а затем в папку Tools / CodeGen.
  2. Исполняемый файл для Windows CodeGen.exe уже доступен. Для Linux вам нужно собрать его, набрав make. (Вы также можете собрать его из исходного кода для Windows, если вы беспокоитесь о запуске загруженного исполняемого файла, но вам нужны установленные компилятор и среда разработки. Подробности см. В документации MiniWin в папке docs).
  3. В этой папке есть несколько примеров файлов JSON. Мы будем использовать example_empty.json. Вам необходимо сначала отредактировать его, чтобы настроить для Windows или Linux. Откройте его в редакторе и вверху, где вы найдете «TargetType», измените значение «Linux» или «Windows» на то, на чем вы запускаете генератор кода.
  4. Теперь введите codegen example_empty.json в командной строке.
  5. Перейдите в свой проект в STM32CubeIDE и откройте папку MiniWinSimple_Common. Удалите там все файлы.
  6. Мы оставили «TargetName» в файле JSON по умолчанию на «MiniWinGen», так что это имя нашей папки сгенерированного кода. Перейдите в папку, в которую вы разархивировали MiniWin, а затем в папку MiniWinGen_Common. Теперь выберите все эти файлы и перетащите их в STM32CubeIDE в папке MiniWinSimple_Common вашего проекта.
  7. Теперь перестройте и перезапустите проект в STM32CubeIDE, и появится ваше новое окно дизайна. Кнопка в окне исчезла, потому что example_empty.json ее не определяет.

Шаг 4: добавление окна

Добавление окна
Добавление окна

Теперь мы добавим второе окно в файл конфигурации JSON и повторно сгенерируем код.

1. Откройте example_empty.json в текстовом редакторе.

2. В разделе «Windows» находится массив определений окон, который в настоящее время имеет только одно окно. Скопируйте все это…

{

«Имя»: «W1», «Заголовок»: «Окно 1», «X»: 10, «Y»: 15, «Ширина»: 200, «Высота»: 180, «Граница»: true, «Заголовок»: true, "Visible": true, "Minimized": false}

и вставьте его снова, разделив два определения запятой.

3. Измените «W1» на «W2» и «Окно 1» на «Окно 2». Измените «X», «Y», «Ширина» и «Высота» на другие значения, помня, что разрешение экрана составляет 240 в ширину на 320 в высоту.

4. Сохраните файл и снова запустите генератор кода.

5. Скопируйте файлы, как на предыдущем шаге, перестройте и запустите заново. Теперь у вас будет 2 окна на вашем дисплее.

Шаг 5: Добавление элемента управления

Добавление элемента управления
Добавление элемента управления

Теперь мы добавим некоторые элементы управления в ваше новое окно. Отредактируйте тот же файл, что и на предыдущем шаге.

1. В спецификации для окна W1 добавьте запятую после последней настройки («Свернуто»: false), затем добавьте этот текст.

"MenuBar": правда, "MenuBarEnabled": true, "MenuItems": ["Фред", "Берт", "Пит", "Альф", "Ян"], "Кнопки": [{"Имя": "B1", "Ярлык": «Button1», «X»: 10, «Y»: 10, «Enabled»: true, «Visible»: true}]

Этот раздел добавляет строку меню с 5 пунктами и включает ее (панели меню можно отключить глобально, попробуйте). Он также добавляет кнопку, которая активна и видима (их можно сделать невидимыми, а затем сделать видимыми в коде).

2. Восстановите код, скопируйте его, перестройте, перезапустите все, как прежде.

Шаг 6. Заставляем элементы управления что-то делать

Заставить элементы управления что-то делать
Заставить элементы управления что-то делать

Теперь у нас есть базовый пользовательский интерфейс, необходимый для того, чтобы он что-то делал. В этом примере мы откроем диалоговое окно выбора цвета при нажатии кнопки в Окне 1.

Перейдите в свой проект в STM32CubeIDE и откройте папку MiniWinSimple_Common, а затем откройте файл W1.c (имя этого файла соответствует полю «Имя» окна в файле JSON, когда код был сгенерирован).

В этом файле вы найдете функцию window_W1_message_function (). Это выглядит так:

void window_W1_message_function (const mw_message_t * message) {MW_ASSERT (message! = (void *) 0, «Параметр нулевого указателя»); / * Следующая строка останавливает предупреждения компилятора, поскольку переменная в настоящее время не используется * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Добавьте сюда любой код инициализации окна * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Добавьте сюда код обработки меню окна * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Добавьте сюда код обработчика для этого элемента управления * /} break; по умолчанию: / * Сделайте MISRA счастливым * / break; }}

Это вызывается диспетчером окон для этого окна всякий раз, когда диспетчер окон должен сообщить окну о том, что что-то произошло. В этом случае нам интересно знать, что была нажата единственная кнопка окна. В операторе switch для типов сообщений вы увидите регистр для MW_BUTTON_PRESSED_MESSAGE. Этот код запускается при нажатии кнопки. В этом окне всего одна кнопка, но может быть и больше, поэтому проверяется, какая это кнопка. В данном случае это могла быть только кнопка B1 (имя снова соответствует имени кнопки в файле JSON).

Итак, после этой метки случая добавьте код, чтобы открыть диалоговое окно выбора цвета, которое выглядит следующим образом:

mw_create_window_dialog_colour_chooser (10, 10, «Цвет», MW_HAL_LCD_RED, false, message-> recipient_handle);

Параметры следующие:

  • 10, 10 - место на экране диалога
  • «Цвет» - это заголовок диалога.
  • MW_HAL_LCD_RED - цвет по умолчанию, с которого начнется диалог
  • false означает, что не отображается большой размер (попробуйте установить для него значение true, и вы увидите разницу)
  • сообщение-> дескриптор получателя - это тот, кто владеет этим диалоговым окном, в данном случае это это окно. Дескриптор окна находится в параметре сообщения функции. Это окно, в которое будет отправлен ответ диалога.

Чтобы узнать значение цвета, выбранный пользователем оконный менеджер отправит нашему окну сообщение с выбранным цветом, когда пользователь нажмет кнопку ОК в диалоговом окне. Поэтому нам нужно перехватить и это сообщение с помощью другого случая в операторе switch, который выглядит следующим образом:

case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{mw_hal_lcd_colour_t selected_colour = message-> message_data; (недействительно) selected_colour; } перерыв;

Мы пока ничего не делаем с выбранным цветом, поэтому просто приводим его к void, чтобы предотвратить предупреждение компилятора. Окончательный код этой функции теперь выглядит так:

void window_W1_message_function (const mw_message_t * сообщение)

{MW_ASSERT (message! = (Void *) 0, «Параметр нулевого указателя»); / * Следующая строка останавливает предупреждения компилятора, поскольку переменная в настоящее время не используется * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Добавьте сюда любой код инициализации окна * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Добавьте сюда код обработки меню окна * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Добавьте сюда код обработчика для этого элемента управления * / mw_create_window_dialog_colour_chooser (10, 10, "Color", MW_HAL_LCD_RED, false, message->; } перерыв; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {mw_hal_lcd_colour_t selected_colour = message-> message_data; (недействительно) selected_colour; } перерыв; по умолчанию: / * Сделайте MISRA счастливым * / break; }}

Запуск кода показан на изображении выше. Вы можете заметить, что когда отображается диалоговое окно, вам нужно ответить на него и закрыть его, прежде чем делать что-либо еще. Это называется модальным поведением. Диалоги в MiniWin и все они всегда глобально модальны, и вы можете иметь только один показ одновременно. Здесь есть больше объяснений …

en.wikipedia.org/wiki/Modal_window

Шаг 7: Рисование в окне

Рисование в окне
Рисование в окне

До сих пор мы использовали только элементы управления, и они сами рисуются. Пришло время нарисовать в нашем окне какой-нибудь нестандартный рисунок. Часть, на которой вы можете рисовать, находится внутри границ (если они есть, они не являются обязательными), внутри полос прокрутки (если они определены, также необязательно) и под строкой заголовка (если таковая есть, это тоже необязательно). В терминологии окон это называется клиентской областью.

В MiniWin есть библиотека графических команд, которые вы можете использовать. Все они осведомлены об окнах. Это означает, что вам не нужно беспокоиться о том, видно ли окно, частично закрыто другими окнами, включено, частично или полностью вне экрана, или если координата того, где вы рисуете, находится в клиентской области или за ее пределами.. Обо всем позаботились за вас. Вы не можете рисовать за пределами своей клиентской области.

Рисование в клиентских областях в терминологии Windows называется рисованием, и каждое окно имеет функцию рисования, в которой вы рисуете. Вы не вызываете свою функцию рисования, оконный менеджер делает это за вас, когда это необходимо. Это необходимо, когда окно перемещается, или когда другое окно сверху меняет свое положение или видимость. Если вам нужно перерисовать окно из-за того, что некоторые данные, от которых зависит содержимое окна, изменились (т.е. вы знаете, что требуется перерисовка, а не диспетчер окон), то вы сообщаете диспетчеру окон, что требуется перерисовка, и он вызывает ваша функция рисования. Вы не называете это сами. (Все это демонстрируется в следующем разделе).

Во-первых, вам нужно найти свою функцию рисования. Генератор кода создает его за вас, и он находится прямо над функцией обработчика сообщений, измененной в предыдущем разделе. Перейдите в свой проект и снова откройте файл W1.c.

В этом файле вы найдете функцию window_W1_paint_function (). Это выглядит так:

void window_W1_paint_function (mw_handle_t window_handle, const mw_gl_draw_info_t * draw_info)

{MW_ASSERT (draw_info! = (Void *) 0, «Параметр нулевого указателя»); / * Заливка клиентской области окна сплошным белым * / 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); / * Добавьте сюда код отрисовки окна * /}

Это чистый, как сгенерированный код, и все, что он делает, это заполняет клиентскую область сплошным белым цветом. Нарисуем желтый заполненный круг в клиентской области. Сначала мы должны понять концепцию графического контекста (еще одна вещь, связанная с Windows). Мы устанавливаем параметры рисования в графическом контексте, а затем вызываем обычную процедуру рисования круга. В этом примере нам нужно задать следующие параметры: наличие у круга границы, стиль линии границы, цвет границы, заливка круга, цвет заливки и узор заливки. Вы можете увидеть приведенный выше код, который делает нечто подобное для заполнения клиентской области сплошным белым прямоугольником без полей. Значения в графическом контексте не запоминаются между каждым вызовом функции рисования, поэтому вам необходимо каждый раз устанавливать значения (хотя они запоминаются с помощью функции рисования).

В приведенном выше коде вы можете видеть, что заливка включена, а узор заливки отключен, поэтому нам не нужно устанавливать их снова. Нам нужно установить границу, стиль линии границы - сплошной, цвет переднего плана - черный, а цвет заливки - желтый, как это:

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

Добавьте этот код в комментарий в этой функции, где говорится о добавлении вашего кода. Далее нам нужно нарисовать круг, который делается так:

mw_gl_circle (draw_info, 30, 30, 15);

Это рисует круг с координатами 30, 30 и радиусом 15. Перестройте код и запустите его повторно, и вы увидите круг в окне, как показано выше. Вы заметите, что круг и кнопка перекрываются, но кнопка находится сверху. Это сделано намеренно. Элементы управления всегда находятся поверх всего, что вы рисуете в клиентской области.

Шаг 8: данные окна

Данные окна
Данные окна

До сих пор мы реализовали наш собственный код в функции сообщения окна 1 (для обработки входящих сообщений) и его функции рисования (для рисования в клиентской области окна). Пришло время связать их. Давайте заполним круг, нарисованный в функции рисования, цветом, который пользователь выбирает с помощью средства выбора цвета при нажатии кнопки. Помните, что мы не вызываем функцию рисования, это делает оконный менеджер, поэтому наша функция сообщения (которая знает выбранный цвет) не может вызывать функцию рисования непосредственно сама. Вместо этого нам нужно кэшировать данные и сообщить диспетчеру окон, что требуется перерисовка. После этого оконный менеджер вызовет функцию рисования, которая может использовать кэшированные данные.

В верхней части W1.c вы увидите пустую структуру данных и объект этого типа, объявленный генератором кода следующим образом:

typedef struct

{/ * Добавьте сюда свои данные * / char dummy; / * Некоторые компиляторы жалуются на пустые структуры; удалите это при добавлении участников * /} window_W1_data_t; статическое окно_W1_data_t window_W1_data;

Здесь мы кэшируем наши данные, чтобы они сохранялись при вызовах и назывались данными окна. Здесь нам нужно сохранить только выбранный цвет, например:

typedef struct

{/ * Добавьте сюда свои элементы данных * / mw_hal_lcd_colour_t selected_colour; } window_W1_data_t; статическое окно_W1_data_t window_W1_data = {MW_HAL_LCD_YELLOW};

Придадим ему начальный желтый цвет. Теперь в функции сообщения мы немного изменим код, чтобы сохранить выбранный цвет вот так:

case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE:

{window_W1_data.chosen_colour = message-> message_data; } перерыв;

Затем мы изменим функцию рисования, чтобы использовать это значение, когда она рисует круг следующим образом:

mw_gl_set_solid_fill_colour (window_W1_data.chosen_colour);

Теперь мы изменили данные, от которых зависит содержимое окна, поэтому нам нужно сообщить диспетчеру окон, что окно требует перерисовки. Мы делаем это в функции сообщения, когда получено диалоговое сообщение ОК, например:

mw_paint_window_client (сообщение-> обработчик_получателя);

Это не приводит к прямому окрашиванию окна. Это служебная функция, которая отправляет сообщение диспетчеру окон о том, что окно необходимо перекрасить (если вы войдете в него, вы увидите, как это происходит). Окно, которое необходимо перекрасить в этом случае, - это само окно, а дескриптор окна находится в параметре сообщения функции обработчика сообщений.

Теперь весь файл выглядит следующим образом, если вы не знаете, куда идут некоторые из приведенных выше фрагментов кода:

#включают

#include "miniwin.h" #include "miniwin_user.h" #include "W1.h" typedef struct {/ * Добавьте сюда свои элементы данных * / mw_hal_lcd_colour_t selected_colour; } window_W1_data_t; статическое окно_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, «Параметр нулевого указателя»); / * Заливка клиентской области окна сплошным белым * / 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); / * Добавьте сюда код рисования окна * / 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, «Параметр нулевого указателя»); / * Следующая строка останавливает предупреждения компилятора, поскольку переменная в настоящее время не используется * / (void) window_W1_data; switch (message-> message_id) {case MW_WINDOW_CREATED_MESSAGE: / * Добавьте сюда любой код инициализации окна * / break; case MW_MENU_BAR_ITEM_PRESSED_MESSAGE: / * Добавьте сюда код обработки меню окна * / break; case MW_BUTTON_PRESSED_MESSAGE: if (message-> sender_handle == button_B1_handle) {/ * Добавьте сюда код обработчика для этого элемента управления * / mw_create_window_dialog_colour_chooser (10, 10, "Color", MW_HAL_LCD_RED, false, message->; } перерыв; case MW_DIALOG_COLOUR_CHOOSER_OK_MESSAGE: {window_W1_data.chosen_colour = message-> message_data; mw_paint_window_client (сообщение-> обработчик_получателя); } перерыв; по умолчанию: / * Сделайте MISRA счастливым * / break; }}

Создайте и запустите снова, и вы сможете установить цвет заливки круга.

В этом примере данных окна используются данные, которые хранятся в статической структуре данных в верхней части исходного файла. Это нормально, если у вас есть только один экземпляр окна, как мы делаем в этом примере, но если у вас более одного экземпляра, все они будут иметь одну и ту же структуру данных. Возможно иметь данные для каждого экземпляра, поэтому несколько экземпляров одного и того же типа окна имеют свои собственные данные. Это объясняется в документации MiniWin, находящейся в каталоге docs. В примере файла он используется для отображения нескольких изображений в одном и том же типе окна (как показано на основном изображении в самом верху этой инструкции).

Шаг 9: немного финального забавного шрифта

Немного финального забавного шрифта
Немного финального забавного шрифта

MiniWin поддерживает рендеринг шрифтов TrueType. Если есть одна вещь, которая делает ваш пользовательский интерфейс привлекательным, так это привлекательные шрифты. Этот последний шаг показывает, как визуализировать шрифт TrueType в окне MiniWin.

Есть два способа визуализации шрифтов TrueType. Один - нарисовать их прямо в вашей клиентской области, как это было сделано для круга ранее, другой - добавить элемент управления текстовым полем в ваше окно. Мы делаем последнее, так как это проще.

Теперь мы добавим элемент управления текстовым полем в наш файл конфигурации JSON. Добавьте его в определение окна 2, чтобы оно выглядело так:

нравится:

{

«Имя»: «W2», «Заголовок»: «Окно 2», «X»: 50, «Y»: 65, «Ширина»: 100, «Высота»: 80, «Граница»: true, «Заголовок»: true, «Visible»: true, «Minimized»: false, «TextBoxes»: [{«Name»: «TB1», «X»: 0, «Y»: 0, «Width»: 115, «Height»: 50, «Обоснование»: «Центр», «BackgroundColour»: «MW_HAL_LCD_YELLOW», «ForegroundColour»: «MW_HAL_LCD_BLACK», «Font»: «mf_rlefont_BLKCHCRY16», «Enabled»: true, «Visible»: true}]}

Несколько слов о шрифтах TrueType в MiniWin. Шрифты входят в файлы.ttf. В оконных менеджерах на больших компьютерах они отображаются на вашем дисплее, когда они необходимы. Это требует большой вычислительной мощности и памяти и не подходит для небольших устройств. В MiniWin они предварительно обрабатываются в растровые изображения и связываются во время компиляции с фиксированным размером и стилем шрифта (жирным, курсивом и т. Д.), То есть вы должны решить, какие шрифты какого размера и стиля вы собираетесь использовать во время компиляции. Это было сделано для вас для двух примеров шрифтов в загруженном вами zip-файле MiniWin. Если вы хотите использовать другие шрифты других размеров и стилей, см. Документацию MiniWin в папке docs. В MiniWin для Windows и Linux есть инструменты для предварительной обработки файлов.ttf в файлы исходного кода, которые вы можете добавить в свой проект.

И второе короткое слово - большинство шрифтов защищены авторским правом, включая те, которые вы найдете в Microsoft Windows. Используйте их по своему желанию для личного использования, но все, что вы публикуете, вы должны убедиться, что лицензия, с которой публикуются шрифты, разрешает это, как в случае с двумя шрифтами, включенными в MiniWin, но не шрифтами Microsoft!

Вернемся к коду! Создавайте, отбрасывайте файлы, создавайте и перезапускайте, как раньше, и вы увидите, что в окне 2 теперь есть текст по умолчанию на желтом фоне с причудливым шрифтом. Давайте изменим текст, отредактировав исходный файл Windows 2 W2.c.

Нам нужно взаимодействовать с текстовым полем, которое мы только что создали, и вы делаете это, как и любое общение в MiniWin, путем отправки ему сообщения. Мы хотим установить текст в элементе управления при создании окна, но до его отображения, поэтому мы добавляем код в обработчик сообщений в случае MW_WINDOW_CREATED_MESSAGE. Он принимается кодом окна непосредственно перед отображением окна и предназначен для таких инициализаций. Генератор кода создал заполнитель, который в функции обработчика сообщений выглядит следующим образом:

case MW_WINDOW_CREATED_MESSAGE:

/ * Добавьте сюда любой код инициализации окна * / break;

Здесь мы собираемся отправить сообщение в элемент управления текстовым полем, сообщая ему, какой текст мы хотим, чтобы он отображался, используя функцию mw_post_message, например:

case MW_WINDOW_CREATED_MESSAGE:

/ * Добавьте сюда любой код инициализации окна * / mw_post_message (MW_TEXT_BOX_SET_TEXT_MESSAGE, message-> recipient_handle, text_box_TB1_handle, 0UL, «Это была темная и бурная ночь…», MW_CONTROL_MESSAGE); перерыв;

Это параметры:

  • MW_TEXT_BOX_SET_TEXT_MESSAGE - это тип сообщения, которое мы отправляем элементу управления. Они перечислены в miniwin.h и задокументированы в документации.
  • message-> recipient_handle - это то, от кого пришло сообщение - это окно, дескриптор которого находится в параметре сообщения, переданном в функцию обработчика сообщений.
  • text_box_TB1_handle - Кому мы отправляем сообщение - дескриптор элемента управления текстовым полем. Они перечислены в созданном файле miniwin_user.h.
  • 0UL - значение данных, в данном случае ничего.
  • «Была темная и бурная ночь…» - значение указателя - новый текст.
  • MW_CONTROL_MESSAGE - Тип получателя, который является элементом управления.

Вот и все. Перестройте и запустите как обычно, и вы увидите текстовое поле, как на изображении выше.

Публикация сообщений является основой MiniWin (как и всех оконных менеджеров). Дополнительные примеры см. В примерах проектов в zip-файле, а подробное объяснение - в разделе, посвященном сообщениям MiniWin в документации.

Шаг 10: Идем дальше

Image
Image

На этом основное введение в MiniWin. MiniWin может намного больше, чем было продемонстрировано здесь. Например, экран на доске, использованный в этом руководстве, небольшой, а элементы управления маленькие, и их нужно использовать с диббером. Однако другие примеры и оборудование используют более крупные элементы управления (есть 2 размера) на больших дисплеях, и ими можно управлять пальцем.

Есть много других типов контроля, кроме продемонстрированных здесь. Дополнительные элементы управления можно найти в различных примерах файлов JSON в папке генератора кода. В этих примерах рассмотрены все типы элементов управления.

У Windows много вариантов. Граница, строка заголовка и значки настраиваются. У вас могут быть полосы прокрутки и клиентские области окна прокрутки, несколько экземпляров окна одного и того же типа, и окна могут быть открытыми (только клиентская область, без рамки или строки заголовка), что означает, что они фиксируются во время компиляции на месте на дисплее (см. изображение в этом разделе с большими значками размера - на самом деле это 6 окон без окон).

MiniWin не использует динамическую память. Это делает его подходящим для небольших устройств с ограниченными возможностями и является требованием для некоторых встраиваемых проектов. MiniWin и код, который он генерирует, также полностью соответствуют MISRA 2012 до «необходимого» уровня.

Для получения дополнительной информации просмотрите документацию в папке docs, а также другие примеры приложений в zip-файле. Здесь приведены примеры, показывающие, как использовать все функции MiniWin и как интегрировать MiniWin с FatFS и FreeRTOS.

Рекомендуемые: