Создание выпадающего списка (Combobox) с иконками
Ранее я рассказывал, как сделать простой комбобокс. Сейчас давайте усовершенствуем его, а точнее дополним строки списка иконками. Я уже делал подобное с меню, тут принцип точно такой же. К стилям комбобокса в ресурсах добавляется CBS_OWNERDRAWFIXED, что в дальнейшем позволит нам самостоятельно обрабатывать процесс отрисовки каждой строки выпадающего списка. Теорию и принцип работы вы можете почитать по приведенной ссылке, повторяться я не буду. В обработчик окна, в котором находится комбобокс, добавляется реакция на два события - это WM_MEASUREITEM, которое приходит перед отрисовкой строки, и WM_DRAWITEM, при котором мы будем рисовать эту строку.Code (Assembler) : Убрать нумерацию
- cmp [msg],WM_MEASUREITEM
- je wm_measure
- cmp [msg],WM_DRAWITEM
- je wm_drawitem
Code (Assembler) : Убрать нумерацию
- wm_measure:
- ; Отрисовываем строку комбобокса?
- mov ebx,[lparam]
- cmp [ebx+MEASUREITEMSTRUCT.CtlType],ODT_COMBOBOX
- jne processed
- ; Высота строки комбобокса с учетом размера иконки
- mov [ebx+MEASUREITEMSTRUCT.itemHeight],26
- jmp processed
Переходим к основному пользовательскому обработчику - отрисовке строки выпадающего списка. Здесь в структуре DRAWITEMSTRUCT, на которую ссылается параметр lParam, приходят данные, непосредственно относящиеся к рисованию строки. Также первым делом проверяем, что на отрисовку передана именно строка комбобокса, при необходимости убеждаемся, что она принадлежит нужному списку, а затем начинаем художества.
Code (Assembler) : Убрать нумерацию
- wm_drawitem:
- ; Отрисовываем строку комбобокса?
- mov ebx,[lparam]
- cmp [ebx+DRAWITEMSTRUCT.CtlType],ODT_COMBOBOX
- jne processed
- ; Это выделенная или обычная строка?
- test [ebx+DRAWITEMSTRUCT.itemState],ODS_SELECTED
- jnz selected_text
- ; Обычная строка
- invoke GetSysColorBrush,COLOR_WINDOW
- lea ecx,[ebx+DRAWITEMSTRUCT.rcItem]
- invoke FillRect,[ebx+DRAWITEMSTRUCT.hDC],ecx,eax
- invoke GetSysColor,COLOR_WINDOW
- invoke SetBkColor,[ebx+DRAWITEMSTRUCT.hDC],eax
- invoke GetSysColor,COLOR_WINDOWTEXT
- invoke SetTextColor, [ebx+DRAWITEMSTRUCT.hDC],eax
- jmp @f
- selected_text:
- ; Выделенная строка
- invoke GetSysColorBrush,COLOR_HIGHLIGHT
- lea ecx,[ebx+DRAWITEMSTRUCT.rcItem]
- invoke FillRect,[ebx+DRAWITEMSTRUCT.hDC],ecx,eax
- invoke GetSysColor,COLOR_HIGHLIGHT
- invoke SetBkColor,[ebx+DRAWITEMSTRUCT.hDC],eax
- invoke GetSysColor,COLOR_HIGHLIGHTTEXT
- invoke SetTextColor, [ebx+DRAWITEMSTRUCT.hDC],eax
- @@:
- invoke SetBkMode,[ebx+DRAWITEMSTRUCT.hDC],TRANSPARENT
- ; Отступ для рисования текста
- mov [ebx+DRAWITEMSTRUCT.rcItem.left],26
- ; Текст в строке комбобокса
- invoke SendMessage,[ebx+DRAWITEMSTRUCT.hwndItem],\
- CB_GETLBTEXT,[ebx+DRAWITEMSTRUCT.itemID],buff
- ; EAX = длина строки
- lea ecx,[ebx+DRAWITEMSTRUCT.rcItem]
- invoke DrawText,[ebx+DRAWITEMSTRUCT.hDC],\
- buff,eax,ecx,DT_SINGLELINE+DT_VCENTER+DT_LEFT
- ; Иконка по индексу строки комбобокса
- invoke GetModuleHandle,0
- mov ecx,[ebx+DRAWITEMSTRUCT.itemID]
- inc ecx
- invoke LoadIcon,eax,ecx
- mov ecx,[ebx+DRAWITEMSTRUCT.rcItem.bottom]
- sub ecx,[ebx+DRAWITEMSTRUCT.rcItem.top]
- sub ecx,16
- shr ecx,1
- add [ebx+DRAWITEMSTRUCT.rcItem.top],ecx
- mov [ebx+DRAWITEMSTRUCT.rcItem.left],6
- invoke DrawIconEx,[ebx+DRAWITEMSTRUCT.hDC],\
- [ebx+DRAWITEMSTRUCT.rcItem.left],\
- [ebx+DRAWITEMSTRUCT.rcItem.top],\
- eax,16,16,NULL,NULL,DI_NORMAL+DI_COMPAT
- jmp processed
Выпадающий список с иконками
Вот и все, как видите, в создании красивых выпадающих списков с иконками нет ничего сложного. Обработка событий самого списка остается без изменений, я специально оставил ее такой же, как она была в старом примере.
В приложении пример программы с исходным текстом, которая отрисовывает выпадающий список с иконками и обрабатывает выбор элементов.
Просмотров: 1665 | Комментариев: 2
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(23.08.2019 в 01:38):
Все, теперь эта говносистема совместима с примером. Архив с исходником обновлены. Алексей, спасибо!
Алексей
(22.08.2019 в 21:11):
Что то под win 10 (х64) криво работает, заводишь, а она завершает свой процесс спустя пару секунд.
Добавить комментарий
Заполните форму для добавления комментария