Пропустить навигацию.
Главная

Использование компонент типа TEdit (BCB и Delphi)

Компоненты типа TEdit используются для ввода и/или вывода однострочных символьных сообщений. Их возможности и набор свойств в значительной мере повторяют соответствующие возможности и свойства объекта TextBox, работающего в одностроковом режиме. Главным свойством этих компонент также является свойство Text, которое в BCB имеет тип AnsiString, а в Delphi — тип String.

Первое, не очень существенное отличие объектов Edit от TextBox заключается в возможности автоматически подстраивать размеры окна ввода/вывода под длину сообщения Text. Это происходит в том случае, если свойству AutoSize присвоено значение True. За размеры формы при этом никто выходить не собирается — более длинные строки приходится прокручивать влево или вправо с помощью клавиш управления курсором.

Вторая особенность окон типа TEdit состоит в возможности выделить сообщение, находящееся в окне в момент получения им фокуса. Для этой цели появилось новое свойство AutoSelect. По умолчанию его значением является False, и для выделения текста или его фрагмента необходимо прибегнуть к установке значений свойств SelStart (первая позиция выделенного текста) и SelLength (длина выделенного текста). При AutoSelect=True выделение текста, находящегося в окне происходит автоматически.

Ограничение на длину вводимого или выводимого сообщения по-прежнему устанавливается значением свойства MaxLength. Однако строки такой длины как 32 или 64 Кбайт здесь не употребляются. Блуждания по строкам такой длины лишено смысла.

Ограничение доступа пользователя к содержимому окна вывода здесь устанавливается свойством с более привычным названием — ReadOnly.

Формат и названия обработчиков событий, наиболее активно используемых при вводе/выводе текстовых сообщений, немного отличается от аналогичных процедур VB:

  • Enter(Sender) — событие, возникающее в момент активизации окна;
  • Exit(Sender) — событие, возникающее в момент потери фокуса;
  • KeyDown(Sender, Key,Shift) — событие, возникающее в момент движения нажатой клавиши вниз;
  • KeyPress(Sender, Key) — событие, возникающее при удержании нажатой клавиши;
  • KeyUp(Sendr, Key,Shift) — событие, возникающее при отпускании нажатой клавиши;
  • Change(Sender) — событие, возникающее при изменении, добавлении или удалении очередного символа в поле ввода.

Параметр Sender, появившийся в этих процедурах, является указателем на объект, пославший соответствующее сообщение. Параметр Key в обработчиках событий KeyDown и KeyUp имеет тип Word, тогда как событие KeyPress передает однобайтовый код Key типа char. Параметр Shift, передаваемый событиями клавиатуры, представляет собой множество, которое может быть пустым или содержать от одного до трех значений — ssShift, ssAlt и ssCtrl, — в зависимости от сочетания управляющих клавиш, нажатых одновременно с клавишей Key.

Передача фокуса окну ввода производится путем обращения к методу SetFocus.

Напомним, что задача первого приложения заключалась в приеме кода клавиши <F2> в любой комбинации с управляющими клавишами <Alt>, <Ctrl> и <Shift>. Нажатия любых других клавиш должны игнорироваться. Для реализации последнего ограничения воспользуемся свойством формы KeyPreview, которое позволяет перехватить сообщение клавиатуры, проанализировать код нажатой клавиши и запретить дальнейшую передачу информации фактическому адресату.

Небольшое отличие в обработчике события FormKeyPress между BCB и Delphi связано с типом параметра Key. В Си с данными типа char можно работать как с числами — поэтому значение Key можно сравнивать с числовым клавиатурным кодом клавиши <F2>. В Паскале такая операция привела бы к ошибке из-за несовпадения типов, поэтому числовой код 113 пришлось преобразовать в символ с помощью функции Chr. Аналогичный прием пришлось применить в Паскале и для засылки нулевого кода в переменную Key.

Более существенная разница между программами обработчиков события EditKeyDown заключается в анализе значения параметра <Shift>. Тип его значения TShiftState определен как множество, содержащее несколько значений, соответствующих битовым значениям в шкале состояния управляющих клавиш клавиатуры (<Alt>, <Ctrl>, <Shift>) и мыши. Если для Паскаля тип данных Set был родным, и для анализа вхождения значения в текущий набор множества существовала операция in, то в BCB такой тип данных появился недавно. И вместо операции in приходится прибегать к методу Contains. Он выдает логическое значение True, если аргумент содержится в проверяемом объекте.

Приложение 3_07 (BCB). Анализ клавиатурного кода.

void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)

{ // Запрет приема кодов клавиш, отличных от F2

if(Key != VK_F2) Key=0;

Caption=””; // Очистка заголовка формы

}

//------------------------------------------------------------------

void __fastcall TForm1::Edit1KeyDown(TObject *Sender, WORD &Key,

TShiftState Shift)

{ AnsiString msg="Вы нажали F2 ";

if(Key==VK_F2) //Если нажата клавиша F2

{ msg=(Shift.Contains(ssAlt))? msg+"+Alt":msg;

msg=(Shift.Contains(ssCtrl))? msg+"+Ctrl":msg;

msg=(Shift.Contains(ssShift))? msg+"+Shift":msg;

Caption=msg;

}

else Caption=""; // Очистка заголовка формы

}

Приложение 3_08 (Delphi). Анализ клавиатурного кода.

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

begin

Key:=Chr(0);

end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

var

msg:String;

begin

msg:='';

if Key=VK_F2 then

begin

msg:='Вы нажали F2 ';

if ssAlt in Shift then msg:=msg+'+ Alt ';

if ssCtrl in Shift then msg:=msg+'+ Ctrl ';

if ssShift in Shift then msg:=msg+'+ Shift';

end;

Caption:=msg;

end;

Приложение 3_09 (BCB). Прием и подтверждение приема сообщения

void __fastcall TForm1::Input1KeyDown(TObject *Sender, WORD &Key,

TShiftState Shift)

{

if(Key==13)

{ Label1->Caption=Input1->Text;

Input1->Text="";

Input1->SetFocus();

}

}

Приложение 3_10 (Delphi). Прием и подтверждение приема сообщения

procedure TForm1.Input1KeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if Key=13 then begin

Label1.Caption:=Input1.Text;

Input1.Text:='';

Input1.SetFocus;

end;

end;

Приложение 3_11 (BCB). Предварительная цензура сообщений клавиатуры

void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)

{

Key=0;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Edit1KeyDown(TObject *Sender, WORD &Key,

TShiftState Shift)

{

AnsiString msg="Вы нажали F2 ";

if(Key==VK_F2)

{ if(Shift.Contains(ssAlt)) msg += " + Alt ";

if(Shift.Contains(ssCtrl)) msg += " + Ctrl ";

if(Shift.Contains(ssShift))msg += " + Shift ";

Edit1->Text=msg;

}

}

Приложение 3_12 (Delphi). Предварительная цензура сообщений клавиатуры.

Не забудьте установить свойство формы KeyPreview=True.

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

begin

Key:=Chr(0);

end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

var

msg:string;

begin

if Key=VK_F2 then begin

msg:='Вы нажали F2 ';

if ssAlt in Shift then msg:=msg+'+ Alt ';

if ssCtrl in Shift then msg:=msg+'+ Ctrl ';

if ssShift in Shift then msg:=msg+'+ Shift';

Edit1.Text:=msg;

end;

end;

Приложение 3_13 (BCB). Прием сообщений в разных окнах

void __fastcall TForm1::FormActivate(TObject *Sender)

{

Edit1->SetFocus(); //Передача фокуса окну Edit1

}

void __fastcall TForm1::Edit1KeyUp(TObject *Sender, WORD &Key,

TShiftState Shift)

{

if(Key==13) // Если нажата клавиша Enter

{ Label1->Caption=Edit1->Text; // Перенос принятого сообщения

Edit2->Text=""; // Очистка окна Edit2

Edit2->SetFocus(); // Активизация окна Edit2

}

}

//-----------------------------------------------------------------

void __fastcall TForm1::Edit2KeyUp(TObject *Sender, WORD &Key,

TShiftState Shift)

{ if(Key==13) // Если нажата клавиша Enter

{ Label2->Caption=Edit2->Text; // Перенос принятого сообщения

Edit1->Text=""; // Очистка окна Edit2

Edit1->SetFocus(); // Активизация окна Edit1

}

}

//-----------------------------------------------------------------------

void __fastcall TForm1::Edit1Exit(TObject *Sender)

{//Обработка ситуации "Потеря фокуса"

Label1->Caption=Edit1->Text;

Edit2->Text="";

}

//-----------------------------------------------------------------------

void __fastcall TForm1::Edit2Exit(TObject *Sender)

{//Обработка ситуации "Потеря фокуса"

Label2->Caption=Edit2->Text;

Edit1->Text="";

}

//-----------------------------------------------------------------------

Приложение 3_14 (Delphi). Прием сообщений в разных окнах

procedure TForm1.FormActivate(Sender: TObject);

begin

Edit2.SetFocus { Передача фокуса окну Edit2 }

end;

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if Key=13 then begin { Если нажата клавиша Enter }

Label1.Caption:=Edit1.Text; { Перенос принятого сообщения }

Edit2.Text:=''; { Очистка окна Edit2 }

Edit2.SetFocus; { Активизация окна Edit2 }

end;

end;

procedure TForm1.Edit2KeyUp(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if Key=13 then begin { Если нажата клавиша Enter }

Label2.Caption:=Edit2.Text; { Перенос принятого сообщения }

Edit1.Text:=''; { Очистка окна Edit2 }

Edit1.SetFocus; { Активизация окна Edit1 }

end;

procedure TForm1.Edit1Exit(Sender: TObject);

begin

Label1.Caption:=Edit1.Text;

Edit2.Text:='';

end;

procedure TForm1.Edit2Exit(Sender: TObject);

begin

Label2.Caption:=Edit2.Text;

Edit1.Text:='';

end;

Приложение 3_15 (VB). Индикатор клавиатуры

Описываемое ниже приложение отображает большую часть клавиатуры (рис. 3.8.).

Обработка строк

Рис. 3.8.Клавиатура с усеченным набором клавиш

Во время его работы вы можете нажать любую клавишу в сочетании с управляющими клавишами <Shift>, <Ctrl> и <Alt>. При этом нажатые клавиши подсвечиваются (точнее — надписи на них выделяются жирным шрифтом), а в двух тестовых окнах отображаются код ASCII и клавиатурный код, соответствующие нажатой комбинации. Для правильной работы приложения переключите клавиатуру в режим набора английских букв. На рис. 3.9. вид главной формы в момент нажатия клавиши «A».

Обработка строк

Рис. 3.9. Фрагмент работы приложения.

Это приложение демонстрирует возможность объединения однородных объектов (в нашем случае таковыми являются командные кнопки) в массив. Преследуются при этом две цели. Во-первых, для однотипных событий, инициаторами которых являются элементы массива, используются общие обработчики. Во-вторых, индексы, присваиваемые объектам, могут оказаться полезными при решении конкретных задач.

Что надо сделать для того, чтобы командные кнопки, имитирующие клавиши клавиатуры, стали группой? Во-первых, надо поместить на форму контейнер. В нашем примере выбран простейший элемент — Frame (Рамка). Заменим значение свойства Caption, вписываемое в разрыв рамки, на слово «Клавиатура». Во-вторых, у первой же кнопки, помещаемой внутрь рамки, сформируем значение свойства Index. По умолчанию в соответствующей строке окна свойств ничего нет, но как только мы впишем туда какое-то числовое значение, VB понимает, что такая кнопка причисляется к группе. Обычно индексы начинают отсчитывать от 0, автоматически увеличивая их значение на 1. Но в нашем случае удобнее в качестве индекса выбрать клавиатурный код клавиши. Это имеет и свои минусы, т.к. клавиатурные коды не образуют сплошного числового интервала. Поэтому при появлении индекса, не относящегося к выбранным клавишам, возможно возникновение аварийных ситуаций (индекс есть, а соответствующего элемента массива нет). Например, нажатие клавиши, не включенной в выбранное подмножество, вызовет сообщение об ошибке.

Несмотря на то, что при нажатии любой клавиши генерируется всего 3 события и для их обработки вполне достаточно приводимых ниже программ, объем приложения превышает 50 Кбайт. Объясняется это довольно просто — в нашем приложении присутствует более 70 командных кнопок. А для каждой из них нужно определить габариты и место в контейнере (Height, Width, Left, Top), заголовок (Caption), индекс (Index), шрифт и его параметры (Font), признак доступности (Enabled). Вот из этого и складывается объем проекта, хотя большинство его составных частей носит единообразный характер. Единственное исключение из этой схемы составляют особые клавиши, выступающие парами — <Shift>, <Ctrl> и <Alt>. Клавиатурный код правой и левой клавиши каждой из этих пар одинаков, но у двух разных элементов массива индексы совпадать не могут. Поэтому мы искусственно назначим правым клавишам код левых клавиш, увеличенный на 1000. Ниже приведен фрагмент проекта, соответствующий описанию командной кнопки с надписью «A»:

Begin VB.CommandButton Command

Caption = "A"

Enabled = 0 'False

BeginProperty Font

Name = "MS Sans Serif"

Size = 8.25

Charset = 204

Weight = 400

Underline = 0 'False

Italic = 0 'False

Strikethrough = 0 'False

EndProperty

Height = 315

Index = 65

Left = 1200

TabIndex = 49

TabStop = 0 'False

Top = 1920

Width = 315

End

В предыдущем приложении достаточно подробно объяснено, как формируются биты параметра Shift (не путать с клавишей <Shift>), передаваемые процедурам KeyDown и KeyUp. В обработчиках соответствующих событий большую часть программы занимают строки, которые устанавливают или сбрасывают значения свойств Enabled и FontBold у системных клавиш.

...........................

Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer)

Command(KeyCode).Enabled = True

Command(KeyCode).FontBold = True

Text2.Text = KeyCode

If Shift And 1 Then

Command(16).Enabled = True:

Command(1016).Enabled = True:

Command(16).FontBold = True:

Command(1016).FontBold = True

End If

If Shift And 2 Then

Command(17).Enabled = True:

Command(1017).Enabled = True:

Command(17).FontBold = True:

Command(1017).FontBold = True

End If

If Shift And 4 Then

Command(18).Enabled = True:

Command(1018).Enabled = True:

Command(18).FontBold = True:

Command(1018).FontBold = True

End If

End Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)

Text1.Text = KeyAscii

End Sub

Private Sub Text1_KeyUp(KeyCode As Integer, Shift As Integer)

Command(KeyCode).FontBold = False

Command(KeyCode).Enabled = False

Command(9).FontBold = False

Command(9).Enabled = False

Text1.Text = ""

Text2.Text = ""

If Shift = 0 Then

Command(16).Enabled = False:

Command(1016).Enabled = False:

Command(16).FontBold = False:

Command(1016).FontBold = False

Command(17).Enabled = False:

Command(1017).Enabled = False:

Command(17).FontBold = False:

Command(1017).FontBold = False

Command(18).Enabled = False:

Command(1018).Enabled = False:

Command(18).FontBold = False:

Command(1018).FontBold = False

End If

End Sub