- Кнопки и меню
- Командные и инструментальные кнопки
- Специальные кнопки
- Специфика обработки событий кнопок
- Создание главного меню приложения
- Работа с Редактором Меню в среде VB
- Пример создания оболочки меню в среде VB
- Пример создания оболочки меню в среде BCB
- Создание всплывающих меню в VB
- Создание всплывающих меню в BCB и Delphi
- Нестандартное меню
Специфика обработки событий кнопок
Опубликовано admin в Втр, 02/09/2010 - 23:20
Выше упоминалось, что главным событием основных кнопок, на которое должен реагировать соответствующий обработчик, является щелчок мышью по кнопке (Click в VB, OnClick в BCB и Delphi). По времени событию Click предшествует переход фокуса к кнопке. В среде Visual Basic такая ситуация вызывает событие GotFocus, в средах BCB и Delphi аналогичное событие называется OnEnter. Когда кнопка теряет фокус, возникает событие LostFocus (в VB) или OnExit (в BCB и Delphi). Каждое из перечисленных выше событий передает сообщение выбранной кнопке (точнее — обработчику соответствующего события этой кнопки), не содержащее никаких параметров.
Однако одновременно с выбором кнопки и возникновением одного из трех упомянутых событий пользователь может нажать какую-нибудь клавишу или сочетание клавиш на клавиатуре. В этой ситуации последовательно возникают события KeyDown, KeyPress и KeyUp, которые адресуются кнопке, находящейся в фокусе. В этих сообщениях обработчики событий получают код нажатой клавиши и битовую шкалу с комбинацией одновременно нажатых управляющих клавиш <Alt>, <Ctrl> и <Shift>.
Приложение 5_09 (VB).
Довольно часто кнопки объединяют в группы с целью упрощения обработки однотипных событий. Рассмотрим в качестве примера VB-приложения наборную панель микрокалькулятора, где будут реализованы только две функции — сброс окна операнда и набор целочисленного значения с помощью цифровых кнопок (рис. 5.14).

Рис. 5.14. Окно VB-приложения
Для формирования окна поместим рамку (Frame1), разместим на ней 10 командных кнопок (Command1, Command2, …). Выровняем их размеры и заменим стандартные заголовки на цифры от 0 до 9. Кнопки уже сгруппированы, но это выражается лишь в том, что перемещение рамки автоматически сдвигает и ее содержимое. Чтобы достичь большего, попробуем заменить значения свойств Name у всех кнопок на одно и то же имя, например, на Cif. Для первой кнопки такая замена проходит без замечаний. На второй — система предупредит нас о существовании объекта с таким же именем:

Рис. 5.15. Запрос подтверждения на создание массива компонент
Так как мы действительно хотим создать массив кнопок, что облегчит процедуру написания обработчика событий, то отвечаем утвердительно, и дальнейшее переименование проходит без замечаний. Переименование разумно вести в порядке возрастания цифр, соответствующих надписям на кнопках. Дело в том, что появления массива с кнопками порождает у каждой кнопки новое свойство — Index. Совпадение индекса кнопки с ее надписью также поможет нам упростить структуру обработчика события Click, который в случае массива будет обслуживать одновременно все кнопки:
Private Sub Cif_Click(Index As Integer)
If Len(Text1.Text)=0 And Index=0 Then Exit Sub
Text1.Text=Text1.Text & Chr(Asc(0) + Index)
End Sub
Обратите внимание на то, что теперь сообщение о щелчке передает индекс кнопки и этого достаточно, чтобы присоединить выделенную цифру к содержимому окна ввода. Первая строка обработчика не допускает набора нуля в качестве старшей цифры числа.
Еще одна кнопка Command11 с надписью <Сброс> предназначена для очистки окна ввода:
Private Sub Command11_Click()
Text1.Text = ""
End Sub
Приложение 5_10 (BCB).
Создадим аналогичный проект в среде BCB. Для объединения кнопок разместим на форме объект GroupBox и положим на него одну кнопку типа TButton. Подберем разумные размеры выделенной кнопки и скопируем ее в Clipboard командой Copy из меню Edit (копировать можно не только выделенные фрагменты текста, но и выделенные объекты). Затем вставим скопированный объект и, зажав клавишу Ctrl, стрелками перемещения курсора отбуксируем кнопку на свое место. Повторим эти операции для каждой цифровой кнопки и заменим их заголовки (Caption) соответствующими цифрами. В качестве строки, предназначенной для индикации набираемого числа, придется выбрать объект Label. Более подходящее окно ввода Edit, к сожалению, не умеет прижимать текст к правой границе. Чтобы поле метки не потерялось на сером фоне формы, поменяем цвет метки (Color = clBtnHeighlight). Запретим метке подгонять свою ширину под размер текста (AutoSize=false) и установим правый прижим (Alignment=taRightJustify).
Для написания общего обработчика события OnClick на Си потребуется некоторая хитрость. Во-первых, надо выделить все цифровые кнопки и на закладке Events в Инспекторе Объектов щелкнуть по событию OnClick. Это позволит приписать всем кнопкам общую процедуру. Во-вторых, обработчик события получит указатель на объект Sender, пославший сообщение. Но этот указатель имеет обобщенный тип TObject. Поэтому нельзя напрямую обратиться за свойством Sender->Caption. Придется завести указатель типа TButton и выполнить приведение типа параметра Sender с помощью функции static_cast:
void __fastcall TForm1::Button10Click(TObject *Sender)
{//Прием цифры и отображение числа
AnsiString k;
TButton *pb=static_cast<TButton *>(Sender);
K = pb->Caption;
if(!(Label1->Caption == "" && k == '0'))
Label1->Caption = Label1->Caption + k;
}
//-----------------------------------------------------------
void __fastcall TForm1::Button11Click(TObject *Sender)
{//Сброс числа
Label1->Caption="";
}
//-----------------------------------------------------------
В приведенном примере для анализа нажатой кнопки было использовано свойство Caption, имеющее тип AnsiString. Такие данные удобно сравнивать, присоединять к другим текстовым величинам. В другой задаче более полезным могло оказаться целочисленное свойство Tag. По умолчанию его значение равно 0, но мы можем присвоить для каждой кнопки соответствующее значение.
Приложение 5_11 (Delphi).
Разработка аналогичного проекта в среде Delphi тоже связана с преобразованием типа данных для параметра Sender. Однако в Паскале это преобразование сделано существенно проще и не требует применения дополнительного указателя:
procedure TForm1.Button10Click(Sender: TObject);
begin
with Sender As TButton do
begin
if not((Label1.Caption='')and(Caption ='0')) then
Label1.Caption:=Label1.Caption + Caption;
end
end;
procedure TForm1.Button11Click(Sender: TObject);
begin
Label1.Caption:='';
end;
