Материал: 3574

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

if (Key != 0) FModified = true; TEdit::KeyPress (Key);

}

Эта функция сначала заменяет недопустимые символы нулевыми. Если символ допустимый, то задается значение true полю свойства FModified. В

конце вызывается метод KeyPress родительского класса.

Можете скомпилировать и протестировать полученный компонент.

Удобно воспользоваться для параллельной разработки компонента и его теста Менеджером Проектов, включив в группу проекта пакет My.bpi и

приложение Test. Форма содержит компонент EditLetNum, кнопку Button с

надписью Clear (при ее нажатии выполняется метод Clear), метку Labe1, в

которой отображается значейие свойства Modified компонента

EditLetNum1, и три индикатора типа TCheckBox. Два из них (назовите их

CBNum и CBLet) указывают допустимость ввода цифр и букв. О третьем речь пойдет в следующем разделе.

Обработчик события OnCreate формы может иметь вид: void __fastcall TForml::FormCreate(TObject *Sender)

{

if (EditLetNuml->Modified) Label1->Caption = "Modified = true";

else Label1->Caption = "Modified = false";

}

Этот обработчик заносит в метку Label1 сообщение о текущем значении свойства Modified.

В обработчике события OnKeyUp компонента EditLetNum напишите оператор:

FormCreate(Sender);

Этот оператор вызывает тот же приведенный выше обработчик события

OnCreate формы для отображения текущего значения Modified.

Обработчик события OnClick индикатора CBNum может иметь вид:

EditLetNum1->EnableNum = CBNum->Checked;

CBLet->Checked = EditLetNum1->EnableLet;

EditLetNum1->SetFocus();

Первый оператор этого обработчика устанавливает значение параметра

EnableNum в зависимости от состояния индикатора CBNum. Второй оператор устанавливает состояние индикатора CBLet равным значению параметра EnableLet. Это надо, поскольку если, например, сбрасывается в false значение параметра EnableNum, а значение параметра EnableLet в

этот момент тоже было равно false, то компонент EditLetNum1 установит значение EnableLet равным true. И надо, чтобы это новое значение отобразилось в индикаторе CBLet.

Аналогично может выглядеть обработчик события OnClick индикатора

CBLet:

EditLetNum1->EnableLet = CBLet->Checked;

CBNum->Checked = EditLetNum1->EnableNum;

EditLetNum1->SetFocus();

В обработчике события OnClick кнопки Clear напишите: EditLetNum1->Clear();

FormCreate(Sender);

Эти операторы проверят работу введенного вами метода Clear и

отобразят на экране изменение значения свойства Modified.

Оттранслируйте компонент. В вашем тестовом приложении установите свойства EnableNum и EnableLet в соответствии с тем, какие исходные установки индикаторов CBNum и CBLet вы задали.

Активизируйте в окне Менеджера Проектов вершину вашего тестового приложения, запустите его на выполнение m проверьте в работе при различных значениях свойств EnableNum и EnableLet.

Если в написанных файлах вашего нового компонента что-то не в порядке, вам может захотеться ввести в файл реализации компонента какие-то точки прерывания. В Windows 2000/ХР и NT проблем не

возникнет. При запуске теста на выполнение точки прерывания, введен-

ные в файл компонента, окажутся недоступными. А если вы активизируете в окне Менеджера Проектов вершину пакета и попробуете выполнить его, то получите сообщение: «Cannot debug project unless a host application is defined. Use Run | Parameters… dialog box». Это означает, что вы сначала с помощью команды Run | Parameters должны определить хост

— тестирующее приложение. Выполните эту команду, предварительно активизировав в окне Менеджера Проектов вершину пакета. Перед вами откроется диалог. В верхнем окошке вы должны указать файл тестирующего приложения. Для этого можете воспользоваться кнопкой:

поиска Browse. Кнопка Load позволяет вам загрузить тестирующее приложение и начать его выполнение по шагам. Затем можете запускать выполнение обычной командой Run | Run (F9). Впрочем, после того, как вы один раз задали хост для пакета в окне, вы можете в дальнейшем запускать пакет на выполнение обычным образом.

В нашем примере требуется ввести событие OnClear, происходящее в момент очистки окна методом Clear. В C++Builder событие — это просто специально свойство, являющееся указателем функции. Тип обобщенного указателя на функцию, которой передается один параметр типа

TComponent (обычно this), - TNotifyEvent. Подобный тип используется в

C++Builder для событий типа OnClick и многих других, которые передают в обработчик только один параметр — TObject *Sender. Подойдет этот тип и нам для события OnClear.

В этом случае объявления нашего события могут иметь вид: private:

iTNotifyEvent FOnClear;

__published:

__property TNotifyEvent OnClear = (read=FOnClear, write=FOnClear} ;

Эти объявления создают поле FOnClear типа TNotifyEvent,

соответствующее событию. А само событие объявляется точно так же, как любое свойство. Только в read и write записываются не функции чтения и записи, а само поле.

Остается только вызвать в нужный момент обработчик события пользователя, если пользователь его предусмотрел. Проверка, имеется ли обработчик пользователя, осуществляется проверкой соответствующего события как булевой величины, возвращающей true, если пользователь предусмотрел свой обработчик. В нашем случае эта проверка и вызов обработчика пользователя осуществляется добавлением в начало написанной ранее процедуры метода Clear оператора:

if (OnClear) OnClear(this);

который вызывает обработчик пользователя OnClear.

Внесите указанные изменения в файлы компонента, откомпилируйте их, выделите на форме тестового приложения компонент EditLetNum1 и

посмотрите страницу событий в Инспекторе Объектов. Вы увидите, что в списке его событий появилось событие OnClear. Дважды щелкните на его правом окне и вы увидите в тексте модуля заготовку для обработчика этого события:

void __fastcall TForm1::EditLetNum1Clear(TObject *Sender)

{

}

Внесите в этот обработчик какой-нибудь оператор, который бы отображал на экране факт свершения этого события, например:

ShowMessage("Событие OnClear");

Проверьте ваше тестовое приложение в работе.

Мы рассмотрели простейший вариант задания события типа

TNotifyEvent. Попробуем несколько усложнить это событие. Пусть мы будем передавать в это событие параметр CanClear, который по

умолчанию равен true, что будет означать разрешение очистить текст окна редактирования. Но предоставим пользователю возможность в своем обработчике события задать этому параметру значение false, что будет означать отказ от очистки.

Чтобы решить эту задачу, вам надо объявить новый тип события. Это объявление делается с помощью ключевого слова __closure. Пусть,

например, вы хотите дать вводимому новому типу событий имя TClear.

Тогда объявление указателя на этот тип может иметь вид: typedef void __fastcall (__closure *TClear)

(System::TObject *Sender, bool& CanClear);

Приведенный код объявляет указатель на функцию, принимающую два параметра: традиционный для всех обработчиков параметр Sender и булев параметр CanClear, который пользователь сможет изменять.

Приведенное выше объявление типа должно помещаться перед описанием класса. Тогда в объявлениях свойства и его поля надо ссылаться на этот тип, следующим образом изменив соответствующие операторы:

private:

TClear FOnClear;

__property TClear OnClear = {read=FOnClear, write=FOnClear};

Осталось изменить метод Clear так, чтобы в нем учитывался новый параметр CanClear:

void fastcall TEditLetNum::Clear()

{