Обработчики событий и методы класса.
От: Alex.Che  
Дата: 21.11.05 14:41
Оценка:
Здравствуйте, ВСЕ !

Предлагаю подискутировать на тему насущной необходимости
требовать именно метод класса, для обработчика события,
как это сделано в VCL.

Поднимите мне веки. Не вижу такой жуткой необходимости.

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re: Обработчики событий и методы класса.
От: Softwarer http://softwarer.ru
Дата: 21.11.05 14:47
Оценка: 1 (1)
Здравствуйте, Alex.Che, Вы писали:

AC>Предлагаю подискутировать на тему насущной необходимости

AC>требовать именно метод класса, для обработчика события,
AC>как это сделано в VCL.

Предлагаю для начала подискутировать на тему "с какого перепоя обработчиком события стал требоваться метод класса, хотя всегда требовался метод объекта".

AC>Поднимите мне веки. Не вижу такой жуткой необходимости.


Дело за малым — напишите компилятор, который избавит нас от этого ограничения. Я — так вижу вполне достаточное количество реализационных проблем, которые не возникли благодаря столь суровому ограничению.
Re[2]: Обработчики событий и методы класса.
От: Alex.Che  
Дата: 21.11.05 14:52
Оценка:
Привет, Softwarer!
Вы пишешь 21 ноября 2005:

AC>> Поднимите мне веки. Не вижу такой жуткой необходимости.


S> Дело за малым — напишите компилятор, который избавит нас от этого ограничения.


При чем тут компилятор?!
Почему нельзя было вместо
type TNotifyEvent = procedure (Sender: TObject) of object;

написать просто:
type TNotifyEvent = procedure (Sender: TObject);

Ы?

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re: Обработчики событий и методы класса.
От: Oleg A. Bachin Украина  
Дата: 21.11.05 14:54
Оценка:
Здравствуйте, 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 нам не нужен, а значит один раз прописав поведение я могу использовать его в любом другом месте программы или в другом приложении. причем базовый класс не раздувается до монстроидальных размеров и копи-пейст не рулит
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Best regards,
Oleg A. Bachin
Re[3]: Обработчики событий и методы класса.
От: Oleg A. Bachin Украина  
Дата: 21.11.05 14:59
Оценка:
Здравствуйте, Alex.Che, Вы писали:


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;
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Best regards,
Oleg A. Bachin
Re[3]: Обработчики событий и методы класса.
От: Softwarer http://softwarer.ru
Дата: 21.11.05 15:10
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>Почему нельзя было вместо

AC>
type TNotifyEvent = procedure (Sender: TObject) of object;

AC>написать просто:
AC>
type TNotifyEvent = procedure (Sender: TObject);


Например, потому что в результате отвалится считывание из dfm, которое надо будет непонятно как крепить.

Например, потому что object нужен гораздо чаще, чем не нужен, и в названном вами варианте программа утонет в идиотском коде типа

procedure btnOkClick ( Sender : TObject ) ;
begin
  (( Sender as TButton ).Owner as TForm ).Close ;
end ;
Re[4]: Обработчики событий и методы класса.
От: Alex.Che  
Дата: 22.11.05 07:54
Оценка:
Привет, Softwarer!
Вы пишешь 21 ноября 2005:

AC>> Почему нельзя было вместо

AC>>
type TNotifyEvent = procedure (Sender: TObject) of object;

AC>> написать просто:
AC>>
type TNotifyEvent = procedure (Sender: TObject);


S> Например, потому что в результате отвалится считывание из dfm,

S> которое надо будет непонятно как крепить.

Да что ты?!

S> Например, потому что object нужен гораздо чаще, чем не нужен,

S> и в названном вами варианте программа утонет в идиотском коде типа

Вопросов больше не имею.(С)
Занудствующие снобы тусуются в соседней курилке.

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re: Обработчики событий и методы класса.
От: Leonid Troyanovsky  
Дата: 22.11.05 10:08
Оценка: +1
Здравствуйте, Alex.Che, Вы писали:

AC>Поднимите мне веки. Не вижу такой жуткой необходимости.


Жуткой необходимости нет.
Просто удобней, т.к. обработчики обычно из других классов.

Ну, а для удовлетворения иных потребностей никто не препятствует
использованию хоть регулярной процедуры.

--
Regards, LVT.
--
С уважением, LVT
Re[2]: Обработчики событий и методы класса.
От: Alex.Che  
Дата: 22.11.05 10:34
Оценка:
Привет, Leonid!
Вы пишешь 22 ноября 2005:

AC>> Поднимите мне веки. Не вижу такой жуткой необходимости.


LT> Жуткой необходимости нет.

LT> Просто удобней, т.к. обработчики обычно из других классов.

LT> Ну, а для удовлетворения иных потребностей никто не препятствует

LT> использованию хоть регулярной процедуры.

Спасибо.
Собственно, это и хотелось услышать.
Потребность использовать процедуру, но не метод, иногда возникает,
при написании неких общих модулей, имплементируемых в несколько проектов.
Стандартные компоненты VCL, для подключения обработчика события,
"требуют", дабы непременно был создан какой-либо объект, "содержащий" нужный метод.
Но независимо от того, создан оный объект, или же нет,
код метода все равно наличествует в приложении.
Но, не имея "живого" объекта (пусть трижды ненужного),
невозможно корректно воспользоваться сим кодом.
Почему, собственно, и ворчу...

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re[5]: Обработчики событий и методы класса.
От: Softwarer http://softwarer.ru
Дата: 22.11.05 10:43
Оценка:
Здравствуйте, Alex.Che, Вы писали:

S>> Например, потому что в результате отвалится считывание из dfm,

S>> которое надо будет непонятно как крепить.

AC>Да что ты?!


Представь себе. Впрочем, с интересом увижу пример кода, опровергающий мои слова.

AC>Вопросов больше не имею.(С)


Хорошо. Тогда только поправлю очевидные ошибки.

AC> Стандартные компоненты VCL, для подключения обработчика события, "требуют", дабы непременно был создан какой-либо объект, "содержащий" нужный метод.


Не так.

Но независимо от того, создан оный объект, или же нет,
код метода все равно наличествует в приложении.
Но, не имея "живого" объекта (пусть трижды ненужного),
невозможно корректно воспользоваться сим кодом.

Не так. Либо Вы путаете понятие объекта (как созданного экземпляра, представителя класса с самим классом), либо не так.
Re[6]: Обработчики событий и методы класса.
От: Alex.Che  
Дата: 22.11.05 10:46
Оценка: -2
Привет, Softwarer!
Вы пишешь 22 ноября 2005:

S>>> Например, потому что в результате отвалится считывание из dfm,

S>>> которое надо будет непонятно как крепить.

AC>> Да что ты?!


S> Представь себе. Впрочем, с интересом увижу пример кода, опровергающий мои слова.


Идите, идите, я подаю только по субботам. (С)

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re[3]: Обработчики событий и методы класса.
От: Leonid Troyanovsky  
Дата: 22.11.05 11:08
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>Но, не имея "живого" объекта (пусть трижды ненужного),

AC>невозможно корректно воспользоваться сим кодом.

Почему невозможно? Ты, видимо, забыл.
В свое время Vladimir Titov показывал массу подобных примеров.

procedure MyFormRegularProc(Self, Sender: TObject);
begin
  ShowMessage(Self.ClassName + ' ' + Sender.ClassName);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  method: TMethod; // локальная, уточнено by Softwarer
begin
  method.Code := @MyFormRegularProc;
  method.Data := Self;
  Button1.OnClick := TNotifyEvent(method);
end;
--
С уважением, LVT
Re[4]: Обработчики событий и методы класса.
От: Alex.Che  
Дата: 22.11.05 11:11
Оценка:
Привет, 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;

Smth.OnSomeEvent := TDummy.EventHandler;
Re[6]: Обработчики событий и методы класса.
От: ekamaloff Великобритания  
Дата: 22.11.05 12:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Причина проста — в случае, когда функция обратного вызова декларирована как указатель на метод класса,

А>вызвать из него обычную функцию не вызывает большого труда (даже если придётся сделать лишний класс для этого).

А>В противном же случае, когда ф-я обратного вызова декларирована как указатель на обычную ф-ю,

А>а требуется вызвать метод класса, то без серьёзного хака типа MakeObjectInstance такая проблема
А>не решается вообще.

А>Потом, если ты не хочешь создавать объект, ты всегда можешь назначить обработчиком

А>событий классовые методы класса:

А>TDummy = class

А> class procedure EventHandler(Sender: TObject);
А>end;

А>Smth.OnSomeEvent := TDummy.EventHandler;


Вот всем и ответ на изначальный вопрос! И не надо <b>таких</b>
Автор: Leonid Troyanovsky
Дата: 22.11.05
извращений. Впрочем уверены ли вы что обработчиками можно назначать классовые методы? А то не могу сейчас проверить.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[6]: Обработчики событий и методы класса.
От: Alex.Che  
Дата: 22.11.05 12:20
Оценка:
Привет, "человек без имени"!
Вы пишешь 22 ноября 2005:

> Причина проста — в случае, когда функция обратного вызова декларирована как указатель на метод класса,

> вызвать из него обычную функцию не вызывает большого труда (даже если придётся сделать лишний класс для этого).

> В противном же случае, когда ф-я обратного вызова декларирована как указатель на обычную ф-ю,

> а требуется вызвать метод класса, то без серьёзного хака типа MakeObjectInstance такая проблема
> не решается вообще.

Не уверен, что правильно понял этот абзац. Поясни.
Имеется в виду, что внутри регулярной процедуры (не метода),
если не предпринимать доп.шагов, недоступен Self ?

> Потом, если ты не хочешь создавать объект, ты всегда можешь назначить обработчиком

> событий классовые методы класса:

> TDummy = class

> class procedure EventHandler(Sender: TObject);
> end;

> Smth.OnSomeEvent := TDummy.EventHandler;


Можно.
Но вопрос был именно о "насущной необходимости...".
Ответ на него я (думаю) получил.

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re[7]: Обработчики событий и методы класса.
От: Softwarer http://softwarer.ru
Дата: 22.11.05 12:31
Оценка:
Здравствуйте, ekamaloff, Вы писали:

E>Вот всем и ответ на изначальный вопрос! И не надо <b>таких</b>
Автор: Leonid Troyanovsky
Дата: 22.11.05
извращений. Впрочем уверены ли вы что обработчиками можно назначать классовые методы? А то не могу сейчас проверить.


http://rsdn.ru/article/delphi/Handlers.xml
Автор(ы): Александр Просторов
Дата: 08.02.2005
В статье подробно разбирается создание обработчиков событий в Delphi и их использование – на примерах разбирается реализация и механизмы работы.
Re[7]: Обработчики событий и методы класса.
От: Leonid Troyanovsky  
Дата: 22.11.05 12:41
Оценка:
Здравствуйте, ekamaloff, Вы писали:

E>Вот всем и ответ на изначальный вопрос! И не надо <b>таких</b>
Автор: Leonid Troyanovsky
Дата: 22.11.05
извращений.


Сам ты извращенец.
Посмотри на код VCL на предмет использования приведения типа TMethod.
--
С уважением, LVT
Re[6]: Обработчики событий и методы класса.
От: Leonid Troyanovsky  
Дата: 22.11.05 12:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>В противном же случае, когда ф-я обратного вызова декларирована как указатель на обычную ф-ю,

А>а требуется вызвать метод класса, то без серьёзного хака типа MakeObjectInstance такая проблема
А>не решается вообще.

Это совсем другая песня, сложенная из-за необъектности Win32.
Прототипы этих функций уже определены, и туда просто не всунуть лишний параметр.
--
С уважением, LVT
Re[7]: Обработчики событий и методы класса.
От: Softwarer http://softwarer.ru
Дата: 22.11.05 12:54
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:

LT> Это совсем другая песня, сложенная из-за необъектности Win32.

LT> Прототипы этих функций уже определены, и туда просто не всунуть лишний параметр.

Дык примерно это и предлагается — убрать "объектный" параметр. Ну и начнутся примеры в духе моего любимого хака:

constructor TLanguages.Create;
type
  TCallbackThunk = packed record
    POPEDX: Byte;
    MOVEAX: Byte;
    SelfPtr: Pointer;
    PUSHEAX: Byte;
    PUSHEDX: Byte;
    JMP: Byte;
    JmpOffset: Integer;
  end;
var
  Callback: TCallbackThunk;
begin
  inherited Create;
  Callback.POPEDX := $5A;
  Callback.MOVEAX := $B8;
  Callback.SelfPtr := Self;
  Callback.PUSHEAX := $50;
  Callback.PUSHEDX := $52;
  Callback.JMP     := $E9;
  Callback.JmpOffset := Integer(@TLanguages.LocalesCallback) - Integer(@Callback.JMP) - 5;
  EnumSystemLocales(TFNLocaleEnumProc(@Callback), LCID_SUPPORTED);
end;
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.