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

Ваш аккаунт

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

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

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

Как перехватить сообщение, но после продолжить его

9.9K
21 марта 2007 года
BelStudent
48 / / 18.03.2007
Короче, я создаю компонент на основе базового стандартного (например кнопка TButton). Мне нужно вставить несколько строчек кода в событие OnClick(), но в тоже время мне нужно оставить для использования событие OnClick() программисту-пользователю, чтобы он смог воспользоваться событием Onclick() компонента.
Передо мной возникла задача как это реализовать. Едиственная идея, которая у меня возникла, это перехватить сообщение до OnClick() и создать своё событие, но чтобы сообщение потом не остановилось, а продолжило свой путь дальше. Но как это сделать?
Или кто-то знает как по другому решить эту проблему?
3
21 марта 2007 года
Green
4.8K / / 20.01.2000
Вызывай метод базового класса:
 
Код:
class MyButton :public TButton
{
public:
   ret_val MyButton::Click() {
      .........
      return TButton::Click();
   }
};
309
22 марта 2007 года
el scorpio
1.1K / / 19.09.2006
Green
Не совсем верно - метод Click просто позволяет "нажать" кнопку программно. Посему действия пользователя будут проигнорированы
А для обратотки нажатия используется "событие". Соответственно его надо переопределить событие OnClick
Код:
class MyButton :public TButton
{
private:
  TNotifyEvent fOnClick; // Собственный обработчик события

protected:
  void __fastcall Parent_Click (TObject *Sender);
  inline void __fastcall DoClick (void)
      {if (fOnClick) fOnClick (this);}
public:
   __fastcall MyButton (TComponent* Owner): TButton (Owner)
      {TButton::OnClick = this->Parent_Click;} // Назначаем обработчик
// события базового класса
__published: // чтобы свойство отобразилось в Object Inspector
   __property TNotifyEvent OnClick = {read=FOnClick, write=FOnClick, stored=IsOnClickStored};
};

void __fastcall MyButton::Parent_Click (TObject *Sender)
{
// Обработчик события базового класса
   if (Sender == this)
   {
     ЧТО-ТО_ДЕЛАЕМ
     this->DoClick(); // Генерируем событие "нажатие"
   }
}


Нажатие кнопки ЛЮБЫМ способом вызовет событие OnClick базового класса. Это событие вызовет метод Parent_Click, который является его "обработчиком". Данный метод выполняет требуемые действия и вызывает событие OnClick ЭТОГО класса.
Единственный (и очень важный) недостаток метода - это возможность изменить OnClick базового класса, обратившись к нему, как к объекту базового класса
 
Код:
TForm1::TForm1 () // конструктор формы, лень полностью писать
{
TButton *btn = new MyButton (this);
btn->OnClick = this->btnClk;
}

В этом случае MyButton::Parent_Click НИКОГДА вызывано не будет :(
3
22 марта 2007 года
Green
4.8K / / 20.01.2000
Ну неправильно назвал метод, суть то не в названии.
Думаю, человеку с головой понятно, что я предлагал своим кодом:
 
Код:
class MyButton :public TButton
{
public:
   ret_val OnClick() {
      .........
      return TButton::OnClick();
   }
};
246
22 марта 2007 года
GIZMO
1.8K / / 30.07.2004
Цитата: Green
Ну неправильно назвал метод, суть то не в названии.
Думаю, человеку с головой понятно, что я предлагал своим кодом:
 
Код:
class MyButton :public TButton
{
public:
   ret_val OnClick() {
      .........
      return TButton::OnClick();
   }
};



мля щас сниму назад оценку:) Первый ответ был верный!

3
22 марта 2007 года
Green
4.8K / / 20.01.2000
Да и второй тоже верный...
Если нет, обоснуй, плз.
246
22 марта 2007 года
GIZMO
1.8K / / 30.07.2004
Цитата: Green
Да и второй тоже верный...
Если нет, обоснуй, плз.


1. ВСВ - это тоже С++ (между прочим...)
2. Специально в классе определен метод:
protected:
... virtual Click();
который инициирует событие.
3. Никаких махинаций с OnClick не нужно(это просто адрес обработчика если он есть, то он вызывается
TControl::Click()
{
...
if(FOnClick)
FOnClick(this) //

)
все по "русски" делать надо как это принято в С++.

3
22 марта 2007 года
Green
4.8K / / 20.01.2000
Цитата: GIZMO
1. ВСВ - это тоже С++ (между прочим...)


Интересный аргумент... к чему он?

Цитата: GIZMO

2. Специально в классе определен метод:
protected:
... virtual Click();
который инициирует событие.
3. Никаких махинаций с OnClick не нужно(это просто адрес обработчика если он есть, то он вызывается
TControl::Click()
{
...
if(FOnClick)
FOnClick(this) //

)
все по "русски" делать надо как это принято в С++.


Я билдер последний раз видел лет пять-шесть назад и уже не помню (да особо и не запоминал) какие специальные методы, в каком специальном классе определены.
Поэтому к подобным вопросам подхожу "как это принято в С++".
Если мне нужно изменить реакцию класса на некоторое событие, я переопределяю обработчик этого события. Если после новой обработки должна вызываться обработка базового класса, я вызываю её явно из своего обработчика.
Другими словами: то что пытается сделать автор топика - это медвежья услуга пользователю его класса. Пользователь должен сам вызвать (или не вызвать) метод базового класса.
Представьте, а если пользователь не захочет, чтоб метод базового класса вызывался, а если захочет, чтоб вызывалось несколько в ином порядке?
Вместо того, чтобы наворачивать сложные механизмы вокруг элементарного действия, предоставьте пользователю возможность самому решить, как ему быть, и вписать ОДНУ строчку TButton::OnClick().

246
22 марта 2007 года
GIZMO
1.8K / / 30.07.2004
Цитата: Green
Интересный аргумент... к чему он?


это я тебя подколол...

Цитата: Green

Я билдер последний раз видел лет пять-шесть назад


вот поэтому замена Click на OnClick выглядит глупо (учитывая конструкцию VCL), а в первом ответе все было четко и "как это принято в С++" и по понятиям VCL.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог