Перед тем, как начать рассказ о кнопках, хочу предостеречь читателя. Дело в том, что можно использовать кнопки и в обычных окнах. Но они, как и большинство элементов управления, проектировались для использования именно в диалоговых окнах. Использование кнопок в обычных окнах не рекомендуется, ибо это увеличивает риск того, что программа будет работать неправильно.
Кнопка - это имитация на экране обычной кнопки или переключателя. В этом разделе под кнопками я также подразумеваю не только PushButons (обычные нажимаемые кнопки), но и Check Boxes (обычно это небольшие квадратики, в которых можно установить или не установить пометку) и Radio Buttons (небольшие кружочки, В ОДНОМ из которых стоит точка). Пользователь может установить курсор мыши на кнопку, щелкнуть клавишей мыши - и кнопка пошлет диалоговому окну сообщение WM_COMMAND. То же произойдет и в случае, если пользователь сначала выберет кнопку клавишей Tab, а потом нажмет Enter.
В параметрах сообщения WM_COMMAND содержится информация, которой достаточно, чтобы диалоговое окно узнало, от какой кнопки пришло сообщение, какое действие требуется выполнить, и таким образом пользователь инициировал выдачу сообщения.
При этом необходимо отметить, что обычная кнопка (ее называют PushButton) не помнит того, что с ней делали, т.е. она на короткое время становится нажатой, а затем возвращается в исходное состояние. Можно нажать кнопку десять раз подряд, и все десять раз она пошлет диалоговому окну одно и то же сообщение, если, конечно, кнопка не сделана запрещенной. CheckBox помнит о том, что он находится в одном из двух состояний - установленом или не установленном, некоторые CheckBox'ы могут находиться еще и в неопределенном состоянии.
Говорит о состоянии одной RadioButton бессмысленно. Дело в том, что RadioButton'ы предназначены для осуществления выбора одного из нескольких взаимоисключаемых вариантов, поэтому можно говорить о группе (иногда говорят кластере) RadioButton'ов. В частности, для объединения RadioButton'ов в кластеры служит такой элемент управления, как группа (GroupBox). Обычно группы используются для группирования органов управления только для улучшения дизайна диалоговых окон. Что же касается RadioButton'ов, то без обрамляющей группы существование кластера не имеет смысла.
Формат описания кнопок в окне диалога достаточно прост:
CONTROL "Заголовок", ButtonID, class, styles, X, Y, Width, HeightX, Y, Width, Height - это все ясно. Все то же самое, что и при описании непосредственно диалогового окна. "Заголовок" - надпись на кнопке или рядом с кнопкой. ButtonID - идентификатор кнопки, т.е. значение, которое посылается диалоговому окну при нажатии кнопки в качестве LOWORD(wParam). Через HIWORD(wParam) диалоговое окно получает код нотификации, т.е. код того действия, которое произвел пользователь. Примерами действия пользователя могут служить нажатие клавиши Enter, двойной щелчек правой или левой клавишей мыши и так далее. А источник, т.е. хэндл инициировавшего сообщение окна, сообщения содержится в lParam (я напомню, что если сообщение приходит от меню, то lParam всегда равен 0, а если от акселератора - 1). Все легко и просто. Сложности начинаются при рассмотрении класса, определяющегося полем class, типа кнопки и стиля кнопки, которые определяются параметром style.
Для кнопок, вне зависимости от того, PushButton ли это, RadioButton или CheckBox, класс всегда определяется как "button".
Читатель, наверное, уже привык к тому, что ответы на большинство вопросов можно найти в файлах заголовках и файлах помощи Win32. Поэтому и сейчас, как всегда, смотрим в заголовочный файл winuser.h, выбираем оттуда стили кнопок, которые начинаются с букв BS_, и сводим их в таблицу. Надоело изучать эти таблицы? Ничего, тяжело в учении - легко в бою! © А.В. Суворов, "Наука побеждать".
Флаг | Значение | Эффект |
BS_PUSHBUTTON | 0x00000000L | Создается обычная кнопка |
BS_DEFPUSHBUTTON | 0x00000001L | Создается обычная кнопка, которая срабатывает при нажатии "Enter" даже тогда, когда не выбрана |
BS_CHECKBOX | 0x00000002L | Создается CheckBox, при нажатии состояние автоматически не изменяется, забота об этом ложится на программу |
BS_AUTOCHECKBOX | 0x00000003L | Создается CheckBox, который автоматически меняет свое состояние при нажатии |
BS_RADIOBUTTON | 0x00000004L | Создается Radio Button, автоматически состояние не меняется |
BS_3STATE | 0x00000005L | То же, что и BS_CHECKBOX, но имеет три состояния - включенное, отключенное и неопределенное, автоматически состояние не меняет |
BS_AUTO3STATE | 0x00000006L | То же, что и предыдущее, но состояние меняется автоматически |
BS_GROUPBOX | 0x00000007L | Группа |
BS_USERBUTTON | 0x00000008L | Устаревший стиль, необходимо использовать BS_OWNERDRAW |
BS_AUTORADIOBUTTON | 0x00000009L | То же, что и RadioButton, но при нажатии состояние меняется автоматически |
BS_OWNERDRAW | 0x0000000BL | За прорисовку кнопки отвечает программа, а не система |
BS_LEFTTEXT | 0x00000020L | Текст помещается слева от RadioButton'а или CheckBox'а, то же, что и BS_RIGHTBUTTON |
BS_TEXT | 0x00000000L | Внутри или рядом с кнопкой отображается текст |
BS_ICON | 0x00000040L | Внутри кнопки или рядом с кнопкой отображается иконка |
BS_BITMAP | 0x00000080L | Внутри кнопки или рядом с кнопкой отображается bitmap |
BS_LEFT | 0x00000100L | Размещает текст у левого края прямоугольника, выделенного для размещения кнопки |
BS_RIGHT | 0x00000200L | Размещает текст у правого края прямоугольника, выделенного для размещения кнопки |
BS_CENTER | 0x00000300L | Размещает текст по горизонтали в центре прямоугольника, выделенного для размещения кнопки |
BS_TOP | 0x00000400L | Размещает текст у верхнего края прямоугольника, выделенного для размещения кнопки |
BS_BOTTOM | 0x00000800L | Размещает текст у нижнего края прямоугольника, выделенного для размещения кнопки |
BS_VCENTER | 0x00000C00L | Размещает текст по вертикали в центре прямоугольника, выделенного для размещения кнопки |
BS_PUSHLIKE | 0x00001000L | Делает CheckBox или RadioButton внешне похожими на PushButton |
BS_MULTILINE | 0x00002000L | При необходимости текст разбивается на несколько строк |
BS_NOTIFY | 0x00003000L | Разрешает посылку родительскому окну нотификационных сообщений BN_DBLCLK, BN_KILLFOCUS и BN_SETFOCUS |
BS_FLAT | 0x00008000L | Не добавляется имитация трехмерности изображения элемента управления |
BS_RIGHTBUTTON | 0x00000020L | RadioButton или CheckBox размещаются справа от надписи (то же, что и BS_LEFTTEXT) |