Как перехватить сообщение, но после продолжить его
Передо мной возникла задача как это реализовать. Едиственная идея, которая у меня возникла, это перехватить сообщение до OnClick() и создать своё событие, но чтобы сообщение потом не остановилось, а продолжило свой путь дальше. Но как это сделать?
Или кто-то знает как по другому решить эту проблему?
{
public:
ret_val MyButton::Click() {
.........
return TButton::Click();
}
};
Не совсем верно - метод Click просто позволяет "нажать" кнопку программно. Посему действия пользователя будут проигнорированы
А для обратотки нажатия используется "событие". Соответственно его надо переопределить событие OnClick
{
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 базового класса, обратившись к нему, как к объекту базового класса
{
TButton *btn = new MyButton (this);
btn->OnClick = this->btnClk;
}
В этом случае MyButton::Parent_Click НИКОГДА вызывано не будет :(
Думаю, человеку с головой понятно, что я предлагал своим кодом:
{
public:
ret_val OnClick() {
.........
return TButton::OnClick();
}
};
Думаю, человеку с головой понятно, что я предлагал своим кодом:
{
public:
ret_val OnClick() {
.........
return TButton::OnClick();
}
};
мля щас сниму назад оценку:) Первый ответ был верный!
Если нет, обоснуй, плз.
Если нет, обоснуй, плз.
1. ВСВ - это тоже С++ (между прочим...)
2. Специально в классе определен метод:
protected:
... virtual Click();
который инициирует событие.
3. Никаких махинаций с OnClick не нужно(это просто адрес обработчика если он есть, то он вызывается
TControl::Click()
{
...
if(FOnClick)
FOnClick(this) //
)
все по "русски" делать надо как это принято в С++.
Интересный аргумент... к чему он?
2. Специально в классе определен метод:
protected:
... virtual Click();
который инициирует событие.
3. Никаких махинаций с OnClick не нужно(это просто адрес обработчика если он есть, то он вызывается
TControl::Click()
{
...
if(FOnClick)
FOnClick(this) //
)
все по "русски" делать надо как это принято в С++.
Я билдер последний раз видел лет пять-шесть назад и уже не помню (да особо и не запоминал) какие специальные методы, в каком специальном классе определены.
Поэтому к подобным вопросам подхожу "как это принято в С++".
Если мне нужно изменить реакцию класса на некоторое событие, я переопределяю обработчик этого события. Если после новой обработки должна вызываться обработка базового класса, я вызываю её явно из своего обработчика.
Другими словами: то что пытается сделать автор топика - это медвежья услуга пользователю его класса. Пользователь должен сам вызвать (или не вызвать) метод базового класса.
Представьте, а если пользователь не захочет, чтоб метод базового класса вызывался, а если захочет, чтоб вызывалось несколько в ином порядке?
Вместо того, чтобы наворачивать сложные механизмы вокруг элементарного действия, предоставьте пользователю возможность самому решить, как ему быть, и вписать ОДНУ строчку TButton::OnClick().