:: MVP ::
|
|
:: RSS ::
|
|
|
Сегодня мы поговорим о том, как создаются кнопки. За основу возьмем наш шаблон
(если вы не читали статью "Минимальная программа на Win API", прочтите, именно
с этим шаблоном мы будем работать). На некоторых кнопках нарисуем стандартные
иконки, на некоторых выведем текст. И конечно обработаем событие, вызываемое
нажатием на кнопку. Кроме этого, кнопки с текстом смогут иметь "фокус", который
будет оставаться после нажатия на одну из них.
Начнем с того, что для каждой кнопки создадим константу с уникальным идентификационным
номером. Объявление самих кнопок удобнее всего сделать в виде массива, это сделает
код более компактным. Также создадим переменные для работы с иконками и шрифтом.
const
// Кнопки, на которые будут выведены иконки
BTN_APPLICATION = 0;
BTN_HAND = 1;
BTN_QUESTION = 2;
BTN_EXCLAMATION = 3;
BTN_ASTERISK = 4;
BTN_WINLOGO = 5;
// Кнопки, на которые будет выведен текст
BTN_TEXT_0 = 6;
BTN_TEXT_1 = 7;
BTN_TEXT_2 = 8;
var
Buttons: array[0..8] of HWND;
Icon: HICON;
Font: HFONT;
|
Кнопка, по своей сути, немногим отличается от главной формы приложения (это
самостоятельное окно, имеющее "родителя", и обладающее своим собственным
дескриптором). По этому для ее создания воспользуемся уже знакомой функцией
CreateWindowEx. Посмотрим, как создается кнопка с иконкой.
Buttons[0] := CreateWindowEx( WS_EX_STATICEDGE, 'Button', nil, BS_ICON or WS_VISIBLE or WS_CHILD,
10, 15, 40, 40, Wnd, BTN_APPLICATION, hInstance, nil );
// Получаем описание нужной иконки
Icon := LoadIcon( 0, IDI_APPLICATION );
// Вставляем полученную иконку в кнопку
SendMessage( Buttons[0], BM_SETIMAGE, IMAGE_ICON, Icon );
|
Второй параметр функции CreateWindowEx говорит о том, что мы создаем именно кнопку.
Определяя стиль кнопки, мы указываем, что она имеет родителя (WS_CHILD, дескриптор
родителя указывается в 9-ом параметре) и будет отображать иконку (BS_ICON). С
остальными параметрами мы уже знакомы. Функция LoadIcon загружает указанную иконку
в наше приложение. Если первый параметр 0 (как в нашем случае), это значит, что мы
работаем со стандартными системными значками (их константы указаны в модуле Windows).
Загрузив иконку, назначаем ее кнопке, послав соответствующее сообщение. Остальные
кнопки создаются по аналогии.
Теперь поговорим о кнопках с текстом.
Buttons[6] := CreateWindowEx( WS_EX_STATICEDGE, 'Button', 'Button1', WS_VISIBLE or WS_CHILD,
10, 70, 90, 40, Wnd, BTN_TEXT_0, hInstance, nil );
Font := GetStockObject( ANSI_VAR_FONT );
SendMessage( Buttons[6], WM_SETFONT, Font, 0 );
Buttons[7] := CreateWindowEx( WS_EX_STATICEDGE, 'Button', 'Button2', WS_VISIBLE or WS_CHILD,
110, 70, 90, 40, Wnd, BTN_TEXT_1, hInstance, nil );
Font := GetStockObject( ANSI_FIXED_FONT );
SendMessage( Buttons[7], WM_SETFONT, Font, 0 );
Buttons[8] := CreateWindowEx( WS_EX_STATICEDGE, 'Button', 'Button3',
BS_DEFPUSHBUTTON or WS_VISIBLE or WS_CHILD,
210, 70, 90, 40, Wnd, BTN_TEXT_2, hInstance, nil );
|
Основное отличие от создания предыдущих кнопок заключается в том, что в 3-ем параметре
вместо nil пишется заголовок кнопки. Обратите внимание, в описании стиля отсутствует
константа BS_ICON. В принципе этого достаточно для того, чтобы отобразить надпись на
кнопке (посмотрите на создание последней кнопки - Buttons[8]). Однако мы можем кое-что
сделать с текстом, а именно, изменить стиль шрифта. Делается это с помощью функции
GetStockObject, параметром которой и задается необходимый нам стиль.
Обратим внимание на то, что последняя кнопка выглядит не совсем так, как остальные.
Добиться такого результата можно, используя константу BS_DEFPUSHBUTTON при задании
стиля.
Теперь посмотрим, как следует обрабатывать событие, полученное от нажатия кнопки.
function WindowProc( Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM ): LRESULT; stdcall;
begin
case Msg of
WM_DESTROY: begin
PostQuitMessage( 0 );
Result := 0;
Exit;
end;
// Обработка сообщений от кнопок
WM_COMMAND:
case LoWord( wParam ) of
BTN_APPLICATION: MessageBox( Wnd, 'IDI_APPLICATION', 'Константа:', MB_OK );
BTN_HAND: MessageBox( Wnd, 'IDI_HAND', 'Константа:', MB_OK );
BTN_QUESTION: MessageBox( Wnd, 'IDI_QUESTION', 'Константа:', MB_OK );
BTN_EXCLAMATION: MessageBox( Wnd, 'IDI_EXCLAMATION', 'Константа:', MB_OK );
BTN_ASTERISK: MessageBox( Wnd, 'IDI_ASTERISK', 'Константа:', MB_OK );
BTN_WINLOGO: MessageBox( Wnd, 'IDI_WINLOGO', 'Константа:', MB_OK );
BTN_TEXT_0: begin
MessageBox( Wnd, 'Button1', 'Кнопка:', MB_OK );
SetFocus( Buttons[6] );
end;
BTN_TEXT_1: begin
MessageBox( Wnd, 'Button2', 'Кнопка:', MB_OK );
SetFocus( Buttons[7] );
end;
BTN_TEXT_2: begin
MessageBox( Wnd, 'Button3', 'Кнопка:', MB_OK );
SetFocus( Buttons[8] );
end;
end;
else
Result := DefWindowProc( Wnd, Msg, wParam, lParam );
end;
end;
|
Как видим, нам нужно обработать сообщение WM_COMMAND. Параметр wParam хранит
уникальный идентификатор кнопки, которая вызвала это событие. Сравниваем его
с определенными в самом начале константами, идентифицируем кнопку, и выполняем
связанный с ней код.
И последнее на сегодня. В нашей программе кнопки с текстом должны иметь фокус.
Для этого, после выполнения кода, связанного с кнопкой, вызываем процедуру SetFocus.
Теперь посмотрим, как это работает. После того, как мы уберем сообщение, вызванное
нажатием на одну из трех нижних кнопок, мы увидим на ней пунктирный прямоугольник,
нарисованный рядом с бордюром. Это и есть результат работы процедуры SetFocus.
Теперь, нажав на клавишу "пробел", мы заставим эту кнопку сработать.
На этом все. Успехов в программировании.
.: Пример к данной статье :.
|
При использовании материала - ссылка на сайт обязательна
|
|