Здравствуйте, Alex.Che, Вы писали:
AC>Предлагаю подискутировать на тему насущной необходимости AC>требовать именно метод класса, для обработчика события, AC>как это сделано в VCL.
Предлагаю для начала подискутировать на тему "с какого перепоя обработчиком события стал требоваться метод класса, хотя всегда требовался метод объекта".
AC>Поднимите мне веки. Не вижу такой жуткой необходимости.
Дело за малым — напишите компилятор, который избавит нас от этого ограничения. Я — так вижу вполне достаточное количество реализационных проблем, которые не возникли благодаря столь суровому ограничению.
Привет, Softwarer!
Вы пишешь 21 ноября 2005:
AC>> Поднимите мне веки. Не вижу такой жуткой необходимости.
S> Дело за малым — напишите компилятор, который избавит нас от этого ограничения.
При чем тут компилятор?!
Почему нельзя было вместо
type TNotifyEvent = procedure (Sender: TObject) of object;
Здравствуйте, Alex.Che, Вы писали:
AC>Здравствуйте, ВСЕ !
AC>Предлагаю подискутировать на тему насущной необходимости AC>требовать именно метод класса, для обработчика события, AC>как это сделано в VCL.
AC>Поднимите мне веки. Не вижу такой жуткой необходимости.
не видишь — не используй
сам считаю, что все это для удобства мышкой тыкать сделанно.
пишу например так:
m_reportTree.OnNodeCanExpand := BehaviorOneExpanded(nil).OnNodeCanExpand;
...............
BehaviorOneExpanded = class(TCustomTree)
public
procedure OnNodeCanExpand(Sender: TCustomTree; Node: TNodeHandle;
Action: TActionType; var CanAction: boolean);
end;
procedure BehaviorOneExpanded.OnNodeCanExpand(Sender: TCustomTree;
Node: TNodeHandle; Action: TActionType; var CanAction: boolean);
var
tmp: TNodeHandle;
vt: IVirtualTree;
begin
vt := TreeUtils.VT(sender.Manager);
tmp := vt.FirstChild(vt.Parent(Node));
while Assigned(tmp) do
begin
if (tmp <> node) and ((sender.NodeState[tmp] and VNS_EXPANDED) = VNS_EXPANDED) then
sender.NodeState[tmp] := sender.NodeState[tmp] xor VNS_EXPANDED;
tmp := vt.NextSibling(tmp);
end;
vt := nil;
end;
как мы видим, Self нам не нужен, а значит один раз прописав поведение я могу использовать его в любом другом месте программы или в другом приложении. причем базовый класс не раздувается до монстроидальных размеров и копи-пейст не рулит
AC>>> Поднимите мне веки. Не вижу такой жуткой необходимости.
S>> Дело за малым — напишите компилятор, который избавит нас от этого ограничения.
AC>При чем тут компилятор?! AC>Почему нельзя было вместо AC>
type TNotifyEvent = procedure (Sender: TObject) of object;
AC>написать просто: AC>
type TNotifyEvent = procedure (Sender: TObject);
AC>Ы?
потому что довольно таки часто всетаки требуется:
type TNotifyEvent = procedure (Context: Pointer; Sender: TObject);
и кстати, довольно редко хотелось бы, чтобы это была форма
чаще что-то другое, что мы и подставляем.... например:
m_reportTree.OnNodeSliceInfo := BehaviorMenu(menu).OnNodeSliceInfo;
.............
BehaviorMenu = class
public
procedure OnNodeSliceInfo(Sender: TCustomTree; Node: TNodeHandle; var State: cardinal);
end;
.............
procedure BehaviorMenu.OnNodeSliceInfo(Sender: TCustomTree; Node: TNodeHandle;
var State: cardinal);
var
menu: TXmlMenu;
groupNode: TXmlNode;
begin
menu := TXmlMenu(self);
.................
end;
Привет, Leonid!
Вы пишешь 22 ноября 2005:
AC>> Поднимите мне веки. Не вижу такой жуткой необходимости.
LT> Жуткой необходимости нет. LT> Просто удобней, т.к. обработчики обычно из других классов.
LT> Ну, а для удовлетворения иных потребностей никто не препятствует LT> использованию хоть регулярной процедуры.
Спасибо.
Собственно, это и хотелось услышать.
Потребность использовать процедуру, но не метод, иногда возникает,
при написании неких общих модулей, имплементируемых в несколько проектов.
Стандартные компоненты VCL, для подключения обработчика события,
"требуют", дабы непременно был создан какой-либо объект, "содержащий" нужный метод.
Но независимо от того, создан оный объект, или же нет,
код метода все равно наличествует в приложении.
Но, не имея "живого" объекта (пусть трижды ненужного),
невозможно корректно воспользоваться сим кодом.
Почему, собственно, и ворчу...
Здравствуйте, Alex.Che, Вы писали:
S>> Например, потому что в результате отвалится считывание из dfm, S>> которое надо будет непонятно как крепить.
AC>Да что ты?!
Представь себе. Впрочем, с интересом увижу пример кода, опровергающий мои слова.
AC>Вопросов больше не имею.(С)
Хорошо. Тогда только поправлю очевидные ошибки.
AC> Стандартные компоненты VCL, для подключения обработчика события, "требуют", дабы непременно был создан какой-либо объект, "содержащий" нужный метод.
Не так.
Но независимо от того, создан оный объект, или же нет,
код метода все равно наличествует в приложении.
Но, не имея "живого" объекта (пусть трижды ненужного),
невозможно корректно воспользоваться сим кодом.
Не так. Либо Вы путаете понятие объекта (как созданного экземпляра, представителя класса с самим классом), либо не так.
Привет, Softwarer!
Вы пишешь 22 ноября 2005:
S>>> Например, потому что в результате отвалится считывание из dfm, S>>> которое надо будет непонятно как крепить.
AC>> Да что ты?!
S> Представь себе. Впрочем, с интересом увижу пример кода, опровергающий мои слова.
Привет, Leonid!
Вы пишешь 22 ноября 2005:
AC>> Но, не имея "живого" объекта (пусть трижды ненужного), AC>> невозможно корректно воспользоваться сим кодом.
LT> Почему невозможно? Ты, видимо, забыл. LT> В свое время Vladimir Titov показывал массу подобных примеров.
Клёво!
Я этого раньше не видел.
Спасибо.
--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re[5]: Обработчики событий и методы класса.
От:
Аноним
Дата:
22.11.05 12:04
Оценка:
Причина проста — в случае, когда функция обратного вызова декларирована как указатель на метод класса,
вызвать из него обычную функцию не вызывает большого труда (даже если придётся сделать лишний класс для этого).
В противном же случае, когда ф-я обратного вызова декларирована как указатель на обычную ф-ю,
а требуется вызвать метод класса, то без серьёзного хака типа MakeObjectInstance такая проблема
не решается вообще.
Потом, если ты не хочешь создавать объект, ты всегда можешь назначить обработчиком
событий классовые методы класса:
TDummy = class
class procedure EventHandler(Sender: TObject);
end;
Здравствуйте, Аноним, Вы писали:
А>Причина проста — в случае, когда функция обратного вызова декларирована как указатель на метод класса, А>вызвать из него обычную функцию не вызывает большого труда (даже если придётся сделать лишний класс для этого).
А>В противном же случае, когда ф-я обратного вызова декларирована как указатель на обычную ф-ю, А>а требуется вызвать метод класса, то без серьёзного хака типа MakeObjectInstance такая проблема А>не решается вообще.
А>Потом, если ты не хочешь создавать объект, ты всегда можешь назначить обработчиком А>событий классовые методы класса:
А>TDummy = class А> class procedure EventHandler(Sender: TObject); А>end;
А>Smth.OnSomeEvent := TDummy.EventHandler;
Вот всем и ответ на изначальный вопрос! И не надо <b>таких</b>
Привет, "человек без имени"!
Вы пишешь 22 ноября 2005:
> Причина проста — в случае, когда функция обратного вызова декларирована как указатель на метод класса, > вызвать из него обычную функцию не вызывает большого труда (даже если придётся сделать лишний класс для этого).
> В противном же случае, когда ф-я обратного вызова декларирована как указатель на обычную ф-ю, > а требуется вызвать метод класса, то без серьёзного хака типа MakeObjectInstance такая проблема > не решается вообще.
Не уверен, что правильно понял этот абзац. Поясни.
Имеется в виду, что внутри регулярной процедуры (не метода),
если не предпринимать доп.шагов, недоступен Self ?
> Потом, если ты не хочешь создавать объект, ты всегда можешь назначить обработчиком > событий классовые методы класса:
> TDummy = class > class procedure EventHandler(Sender: TObject); > end;
> Smth.OnSomeEvent := TDummy.EventHandler;
Можно.
Но вопрос был именно о "насущной необходимости...".
Ответ на него я (думаю) получил.
Здравствуйте, Аноним, Вы писали:
А>В противном же случае, когда ф-я обратного вызова декларирована как указатель на обычную ф-ю, А>а требуется вызвать метод класса, то без серьёзного хака типа MakeObjectInstance такая проблема А>не решается вообще.
Это совсем другая песня, сложенная из-за необъектности Win32.
Прототипы этих функций уже определены, и туда просто не всунуть лишний параметр.
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT> Это совсем другая песня, сложенная из-за необъектности Win32. LT> Прототипы этих функций уже определены, и туда просто не всунуть лишний параметр.
Дык примерно это и предлагается — убрать "объектный" параметр. Ну и начнутся примеры в духе моего любимого хака: