Перейти к содержимому

MENU320 — строка меню

MENU320 — строка меню с выпадающими списками для приложений, использующих WIN320. Полоса заголовков вдоль верхней границы экрана, выпадающие списки с шорткатами, разделителями, отметками-переключателями, отключёнными пунктами и вложенными подменю.

Это не DLL. Модуль линкуется прямо в приложение и целиком построен на публичном интерфейсе WIN320: он собирает обычные окна и контролы WIN320 в памяти приложения и вызывает библиотеку через тот же libman. Менять или пересобирать WIN320.DLL не нужно. Такое устройство выбрано осознанно: образ WIN320 занимает ровно одно 16-КБ окно, и места для контрола меню в нём уже нет, а вызывать одну DLL из другой libman не умеет.

include "win320.inc"
include "menu320.def.inc"
include "menu320.inc" ; сам подключает common/fontlayout.inc
; WIN320 уже загружена и инициализирована приложением
ld hl,(dll_handle)
ld ix,menu_arena ; рабочая память модуля
ld bc,menu_arena_end-menu_arena
call menu_init
jr nz,failed
ld ix,menu_bar
call menu_draw_bar ; нарисовать полосу заголовков
jr nz,failed
ld ix,menu_bar
ld a,0 ; открыть первый заголовок
call menu_run ; модальный цикл меню
ld a,(menu_command) ; выбранная команда; 0 — отменено

Разбор: menu_init получает хэндл загруженной WIN320 и арену — кусок памяти приложения, в котором модуль строит окна и контролы WIN320. menu_draw_bar рисует полосу заголовков; она остаётся на экране постоянно. menu_run открывает меню и работает модально: обслуживает мышь, клавиатуру и подменю сам, а по возврату кладёт код выбранного пункта в menu_command (0 — пользователь отменил выбор). В A передаётся индекс заголовка, который нужно раскрыть, либо #FF — только активировать полосу.

Меню — статические данные, никакого кода строить не нужно:

menu_bar: dw 0,0,320 : db 12,2 : dw bar_refs
bar_refs: dw txt_file, pop_file ; заголовок + его список
dw txt_view, pop_view
pop_file: db 3,0 : dw rows_file ; 3 строки
rows_file: db 0, CMD_INFO : dw txt_info, txt_altent
db MI_SEPARATOR,0 : dw 0,0
db 0, CMD_EXIT : dw txt_exit, txt_f10

Полоса (menu_bar) задаёт геометрию и список пар «текст заголовка — выпадающий список». Каждая строка списка — флаги (MI_SEPARATOR, отключённый пункт, отметка, подменю), код команды и два текста: подпись и подпись шortката у правого края. Команда и возвращается из menu_run.

Полный пример — examples/menudemo.asm: четыре списка с шорткатами, разделителями, переключателями, отключённым пунктом и подменю поверх обычного окна WIN320.

  • WIN320 ABI 2.0 — загруженная приложением (рекомендуется в WIN3). Версии 1.x не подходят: у них другой размер структуры окна.
  • Установленная палитра: сразу после загрузки WIN320 вызвать WIN_STYLE с WIN_STYLE_PALETTE|WIN_STYLE_CLEAR — без этого всё рисуется чёрным.
  • Backstore через win_set_backstore: каждый открытый список — это модальное окно WIN320 с сохранением фона; список 120×110 занимает почти целую 16-КБ страницу.
  • Арена: 38 + 38·N байт на полосу с N заголовками плюс 20 + 78·M байт на каждый одновременно открытый список из M строк.
  • После загрузки нового шрифта (win_load_font) вызвать menu_refresh_font — модуль кэширует таблицу ширин символов.
  • Каталог libs/common в путях включений ассемблера.
Окно терминала
make -C menu320 demo # build/MENUDEMO.EXE — демо для железа/эмулятора
make -C menu320 test # host- и z80-тесты

Модуль компактный: около 4,2 КБ кода и 0,6 КБ данных (цифру контролирует автоматический тест). C- и Pascal-биндинги пока не готовы — сейчас модуль подключается из ассемблерных проектов.