
Меню с иконками на Ассемблере
Сегодня разберем кастомизацию такого элемента интерфейса, как выпадающее меню. Без меню обходится мало какое современное приложение, но вот работа с меню стандартными средствами обычно ограничивается установкой флага чекбокса, затенением неактивных пунктов или отрисовкой субменю. Попытка разнообразить меню, например, своими иконками, приводит к очень печальному результату. Ситуацию особо не спасают ни собственные битмапы, ни подгрузка изображений из списка ImageList. Очень странно, что на протяжении многих лет разработчики Windows так и не сделали инструментов "из коробки", чтобы можно было легко и комфортно работать с менюшками. К счастью, в системе есть "потайной ход", с помощью которого можно кастомизировать меню так, как вам захочется. Для своих проектов я постарался сделать как можно более универсальный инструмент для работы с меню и сейчас я с вами им поделюсь.Начнем создание собственных элементов интерфейса с того, что для каждого настраиваемого меню резервируется структура с данными следующего формата:
Code (Assembler) : Убрать нумерацию
- struct MYMENU
- hMenu dd ?
- itemWidth dd ?
- itemHeight dd ?
- hasIcons db ?
- ends
Code (Assembler) : Убрать нумерацию
- menus dd Menu1
- dd Menu2
- dd ?
- Menu1 MYMENU
- Menu2 MYMENU
Если вы хотите использовать значения размеров меню, соответствующие стандартным, то для этих целей описываются две константы с дефолтными значениями, определенными опытным путем. Еще одна константа используется в качестве идентификатора заголовков. Естественно, вы можете заменить их на ваши значения:
Code (Assembler) : Убрать нумерацию
- DEFAULT_ITEM_WIDTH = 80
- DEFAULT_ITEM_HEIGHT = 18
- DEFAULT_HEADER_ID = 9999
Code (Assembler) : Убрать нумерацию
- ICONS_COUNT = 100
- hIcons rd ICONS_COUNT*2
На этом можно заканчивать с теорией и переходить непосредственно к программированию. Начнем с создания меню. Обычно это делается на этапе инициализации окна. Создадим два меню с разными характеристиками.
Code (Assembler) : Убрать нумерацию
- ; Очистить память под массив иконок
- invoke RtlZeroMemory