Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

События в простом классе (не в компоненте)

518
02 апреля 2007 года
Andreika
101 / / 14.02.2003
Можно ли создавать события в обычном классе, который объявлен в модуле, а не в компоненте VCL?
То есть, если я пишу компонент, то ясное дело, могу создавать в нем события. А вот если у меня просто класс, который мной написан и совершенно не нужно лепить его на форму в виде контрольчика. Можно ли для класса, который просто объявлен в модуле, описать событие, или что-то подобное событию, чтобы класс генерировал его в самые разные моменты времени, а основная программа могла обработать это событие?
309
02 апреля 2007 года
el scorpio
1.1K / / 19.09.2006
Да.
Создаётся тип, аналогичный событию TNotifyEvent (обязательно со словом __closure). Только нужно изменить тип указателя Sender класс создаваемых объектов (или базовый)
Код:
class TMyClass; //Предварительное объявление класса
typedef void __fastcall (__closure *TMyEvent) (TMyClass* Sender);

class TMyClass // Реализация класса
{
private:
   TMyEvent fMyEvent; // Событие

protected:
   virtual void DoMyEvent (void) // Генератор
   {if (fMyEvent) fMyEvent (this);}
};
518
02 апреля 2007 года
Andreika
101 / / 14.02.2003
Цитата: el scorpio
Да.
Создаётся тип, аналогичный событию TNotifyEvent (обязательно со словом __closure). Только нужно изменить тип указателя Sender класс создаваемых объектов (или базовый)
 
Код:
class TMyClass; //Предварительное объявление класса
typedef void __fastcall (__closure *TMyEvent) (TMyClass* Sender);



Если можно поподробнее, что значит "аналогичный TNotifyEvent". Как именно надо реализовать класс событий TMyEvent?

10
02 апреля 2007 года
Freeman
3.2K / / 06.03.2004
Цитата: Andreika
Можно ли создавать события в обычном классе, который объявлен в модуле, а не в компоненте VCL?


Такое в VCL сплошь и рядом. Посмотри, например, как сделано в TStringList.

309
03 апреля 2007 года
el scorpio
1.1K / / 19.09.2006
Стандартный тип событий VCL (TNotifyEvent) объявлен так
typedef void __fastcall (__closure *TNotifyEvent)(TObject* Sender); где
__closure - слово, означающее, что объект этого типа - структура с двумя полями (адрес объекта, адрес метода)
Sender - параметр метода - указатель на объект, сгенерировавший событие. Здесь он имеет тип TObject - базовый класс для всех VCL объектов.
В зависимости от параметров события, назначается его обработчик - метод другого объекта. Если генератором события будут объекты, не производные от TObject, значит нужно объявить другой тип события (по образу и подобию TNotifyEvent), используя в качестве Sender указатель на объект своего класса.
14K
03 апреля 2007 года
viva
27 / / 07.04.2006
События можно создавать любого типа не только через TNotifyEvent
Вот простенький пример другого типа (можно с Sender-ом, можно без-здесь без)

Header класса
Код:
typedef void __fastcall (__closure *TEventInfoMessage)(AnsiString Info,int Count);
class MyClass
{
private:
  TEventInfoMessage FOnEventInfoMessage;
protected:
  virtual void __fastcall EventInfoMessage(AnsiString Info,int Count);
public:
  ...
  void __fastcall ReadAll();
  __property TEventInfoMessage
             onEventInfoMessage={read=FOnEventInfoMessage,write=FOnEventInfoMessage};
};

Cpp класса
Код:
void __fastcall MyClass::EventInfoMessage(AnsiString Info,int Count)
{
  if(FOnEventInfoMessage) FOnEventInfoMessage(Info,Count);
}
void __fastcall MyClass::ReadAll()
{
  ...
  while(...)
  {
    ...
    EventInfoMessage(Info,Count);
    ...
  }
}

Cpp главной формы
Код:
void __fastcall TMainForm::FormActivate(TObject *Sender)
{
  MyClass *myobject=new MyClass();
  myobject->onEventInfoMessage=EventInfoMessage;
  myobject->ReadAll();
}
void __fastcall TMainForm::EventInfoMessage(AnsiString Info,int Count)
{
  if(Info != "") Edit1->Text=Info;
  Edit2->Text=AnsiString(Count);
  MainForm->Update();
  Application->ProcessMessages();
}
309
03 апреля 2007 года
el scorpio
1.1K / / 19.09.2006
viva
Sender как указатель на объект-"генератор" - параметр необязательный, но такое бывает редко.
Разработка событий предполагает, что обработчик будет использовать адрес "генератора". Например, метод обрабатывает события нескольких компонентов, обращаясь к Sender.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог