Кнопки, которые рисует родительское окно
Если вас не удовлетворяет внешний вид стандартных кнопок (или других стандартных органов управления, созданных на базе класса "button"), вы можете при создании кнопки указать стиль BS_OWNERDRAW. Этот стиль несовместим с остальными стилями кнопок.
Если вы создали кнопку со стилем BS_OWNERDRAW, она будет работать аналогично кнопкам других стилей, но процедура рисования кнопки возлагается на родительское окно. При этом оно может нарисовать кнопку с использованием пиктограмм (с помощью функции DrawIcon), графических изображений bitmap или любым другим способом.
Обычно кнопки BS_OWNERDRAW используют при отображении наборов инструментальных средств, называемых Toolbar. Примером такого набора может служить набор кнопок с пиктограммами, предназначенных для запуска команд в текстовом процессоре Microsoft Word for Windows (рис. 2.4).
Рис. 2.4. Кнопки с пиктограммами
Кнопка BS_OWNERDRAW, как и кнопка BS_PUSHBUTTON, посылает в родительское окно сообщение WM_COMMAND с кодом извещения BN_CLICKED. Дополнительно такая кнопка посылает в родительское окно сообщение WM_DRAWITEM, которое говорит о том, что надо нарисовать орган управления в том или ином состоянии.
Обработчик сообщения WM_DRAWITEM должен вернуть значение TRUE.
Параметр wParam сообщения WM_DRAWITEM содержит идентификатор органа управления, пославшего сообщение WM_DRAWITEM (для органа управления типа меню этот параметр равен 0).
Параметр lParam содержит дальний указатель на структуру типа DRAWITEMSTRUCT, описанную в файле windows.h:
typedef struct tagDRAWITEMSTRUCT { UINT CtlType; UINT CtlID; UINT itemID; UINT itemAction; UINT itemState; HWND hwndItem; HDC hDC; RECT rcItem; DWORD itemData; } DRAWITEMSTRUCT;
В файле windows.h определены также ближний и дальний указатели на эту структуру:
typedef DRAWITEMSTRUCT NEAR* PDRAWITEMSTRUCT; typedef DRAWITEMSTRUCT FAR* LPDRAWITEMSTRUCT;
Анализируя поля структуры DRAWITEMSTRUCT, родительское окно может определить тип и идентификатор органа управления, требующего перерисовки, а также состояние, в котором необходимо изобразить данный орган управления (включен, выключен, получил фокус ввода, неактивен, выбран для использования).
Приведем назначение отдельных полей структуры DRAWITEMSTRUCT.
Имя поля | Описание |
CtlType | Тип органа управления. Может принимать следующие значения: ODT_BUTTONODT_BUTTON - кнопка; ODT_COMBOBOXODT_COMBOBOX - орган COMBOBOX (рассмотрим позже); ODT_LISTBOXODT_LISTBOX - орган LISTBOX (рассмотрим позже); ODT_MENUODT_MENU - меню |
CtlID | Идентификатор органа управления. Не используется для меню |
itemID | Идентификатор строки для органов COMBOBOX, LISTBOX или меню |
itemAction | Действия, которые необходимо выполнить при изображении органа управления. Определен в виде отдельных битовых флагов: ODA_DRAWENTIREODA_DRAWENTIRE - требуется перерисовать весь орган управления; ODA_FOCUSODA_FOCUS - этот бит устанавливается в 1, если орган управления получил или потерял фокус ввода, новое состояние органа управления можно узнать, проанализировав содержимое поля itemState; ODA_SELECTODA_SELECT - изменилось состояние органа управления (он стал включенным, выключенным или неактивным), для уточнения состояния необходимо использовать поле itemState |
itemState | Вид, в котором необходимо изобразить орган управления. Определен в виде отдельных битовых флагов: ODS_CHECKEDODS_CHECKED - выбрана строка меню (этот бит используется только для меню); ODS_DISABLEDODS_DISABLED - орган управления неактивен; ODS_FOCUSODS_FOCUS - орган управления получил фокус ввода; ODS_GRAYEDODS_GRAYED - строка меню должна быть изображена серым цветом (этот бит используется только для меню); ODS_SELECTEDODS_SELECTED - орган управления выбран |
hwndItem | Для кнопок, органов управления COMBOBOX и LISTBOX это поле содержит идентификатор окна. Для меню это поле содержит идентификатор меню |
hDC | Контекст устройства, который необходимо использовать для рисования органа управления |
rcItem | Прямоугольные границы органа управления, внутри которого его необходимо нарисовать |
itemData | Используется только для органов управления COMBOBOX и LISTBOX |