Обработчики событий и методы класса.
От: 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;
Re[7]: Обработчики событий и методы класса.
От: Alex.Che  
Дата: 22.11.05 12:56
Оценка:
Привет, ekamaloff!
Вы пишешь 22 ноября 2005:

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

e> извращений. Впрочем уверены ли вы что обработчиками можно назначать классовые методы? А то не могу сейчас проверить.

Можно.
Но Self там будет не всегда тот, который бы хотелось.
Несмотря на: "In the defining declaration of a class method, the identifier Self represents the class where the method is
called."


program Project3;

uses
  Forms, StdCtrls, Windows;

type
  TDummyClass = class
    class procedure DoClick(Sender: TObject);
  end;

var
  Form1: TForm;

class procedure TDummyClass.DoClick(Sender: TObject);
var
  SName: string;
begin
  SName := Self.ClassName;
  MessageBox(Application.Handle, PChar(SName), 'Class', 0);
end;

begin
  Application.Initialize;
  Application.CreateForm(TForm, Form1);
  with Form1 do begin
    Caption := 'Это пример формы';
    BorderStyle := bsDialog;
    Position := poScreenCenter;
  end;
  with TButton.Create(Form1) do begin
    Parent := Form1;
    Caption := 'Нажми';
    Left := (Parent.Width - Width) div 2;
    Top := (Parent.Height - Height) div 2;
    OnClick := TDummyClass.DoClick;
  end;
  Application.Run;
end.



--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re[7]: Обработчики событий и методы класса.
От: Аноним  
Дата: 22.11.05 13:00
Оценка:
AC>Не уверен, что правильно понял этот абзац. Поясни.
AC>Имеется в виду, что внутри регулярной процедуры (не метода),
AC>если не предпринимать доп.шагов, недоступен Self ?

Шутить изволите? Какой Self у регулярной процедуры? Self какого объекта?

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

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

Тезис состоит в том, что в общем случае перейти от метода к функции легко
(вызвав последнюю из первого),
а от функции к методу — крайне затруднительно
(за исключением некоторых частных случаев, вроде функции потока).

Вы с этим несогласны?
Re[8]: Обработчики событий и методы класса.
От: Alex.Che  
Дата: 22.11.05 13:13
Оценка:
Привет, "человек без имени"!
Вы пишешь 22 ноября 2005:

AC>> Не уверен, что правильно понял этот абзац. Поясни.

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

> Шутить изволите? Какой Self у регулярной процедуры? Self какого объекта?


Никто не запрещает передать мне его в процедуру, как это показано
в примере от Leonid Troyanovsky
Автор: Leonid Troyanovsky
Дата: 22.11.05
.

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

AC>Привет, "человек без имени"!

AC>Вы пишешь 22 ноября 2005:

AC>>> Не уверен, что правильно понял этот абзац. Поясни.

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

>> Шутить изволите? Какой Self у регулярной процедуры? Self какого объекта?


AC>Никто не запрещает передать мне его в процедуру, как это показано

AC>в примере от Leonid Troyanovsky
Автор: Leonid Troyanovsky
Дата: 22.11.05
.


AC>--

AC>With best regards, Alex Cherednichenko.

Это совсем другое. Тебе требуется указатель на метод,
а ты хочешь передать ему регулярную функцию. Нет проблем.

Представь другую ситуацию: TNotifyEvent был объявлен как регулярная процедура.

type TNotifyEvent = procedure(Sender: TObject);

У тебя есть форма, на форме кнопка.
Ты хочешь сделать очень простую вещь:
чтобы по нажатию на кнопку форма, на которой эта кнопка лежит, закрылась.
Пишешь обработчик события

procedure ButtonClick(Sender: TObject);
begin
// ? а что тут писать-то?
end;

Если форма статическая, то ты можешь, конечно, зашить
в обработчик глобальный объект:

procedure ButtonClick(Sender: TObject);
begin
Form1.Close; // И на каждый экземпляр — отдельную процедуру.
end;

А если форма создана динамически, и никакая глобальная переменная на неё не ссылается?
Что тогда будешь делать?

Best regards,
"Человек без имени" aka rounin
Re[10]: Обработчики событий и методы класса.
От: rounin  
Дата: 22.11.05 13:40
Оценка:
Конечно, я немного упростил ситуацию — ведь кнопка знает о форме,
и ты можешь её получить через GetParentForm.
Но напряжём своё воображение и представим, что она о форме ничего не знает.
Re[8]: Обработчики событий и методы класса.
От: Leonid Troyanovsky  
Дата: 22.11.05 15:32
Оценка:
Здравствуйте, Softwarer, Вы писали:

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


S>
S>constructor TLanguages.Create;

S>var
S>  Callback: TCallbackThunk;
S>begin

S>  EnumSystemLocales(TFNLocaleEnumProc(@Callback), LCID_SUPPORTED);
S>end;


IMHO, из стека код лучше убрать.
Лучше по-честному, VirtualAlloc, VirtualProtect & etc,
т.е. как в MakeObjectInstance.
--
С уважением, LVT
Re[3]: Обработчики событий и методы класса.
От: svd71 http://visualdesigner.fatal.ru/
Дата: 22.11.05 19:03
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>Привет, Softwarer!

AC>Вы пишешь 21 ноября 2005:

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


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


AC>При чем тут компилятор?!

AC>Почему нельзя было вместо
AC>
type TNotifyEvent = procedure (Sender: TObject) of object;

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

AC>Ы?
Потому, что для второго типа исплользуется размер в 4 байта (только код на процедуру), а в первом 8 байт (код на процедуру + код на Self — см тип TMethod), что является необходимым при работе в объекте — на все экземляры один экземпляр методов.
Re[3]: Обработчики событий и методы класса.
От: svd71 http://visualdesigner.fatal.ru/
Дата: 23.11.05 18:07
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>Спасибо.

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

Вообще-то борланды и тут изгалились. передаваемый второй параметр -Code- есть ни что иное, как указатель Self. Это подразумевает то, что по логике вещей метод не должен работать на несозданом объекте (фактически это не так). Но иногда такое требуется, и тогда Бормановцы добавили класс-методы (class function — где Self нельзя использовать). Частным случаем класс-метода служыт обычный конструктор любого класса.
И с класс-методом моржно вообще обходится так:

TMyObject.Method1(Form1);
Re[8]: Обработчики событий и методы класса.
От: vlad_gri  
Дата: 24.11.05 07:53
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Ну и начнутся примеры в духе моего любимого хака:


Можно проще.


type
  TLanguages = class
  private
    function LocalesCallback: Integer; stdcall;
    ...
  public
    constructor Create;
    ....
  end;

constructor TLanguages.Create;
begin
  inherited Create;
  EnumSystemLocales(@TLanguages.LocalesCallback, LCID_SUPPORTED);
end;

function TLanguages.LocalesCallback: Integer; stdcall;
var
  AID:Integer;

begin
  ....
  AID := IntToStr('$'+Copy(PChar(Self), 5, 4));
  ....
  ....
  Result := 1;
end;
Re[4]: Обработчики событий и методы класса.
От: Softwarer http://softwarer.ru
Дата: 24.11.05 08:17
Оценка:
Здравствуйте, svd71, Вы писали:

S>Вообще-то борланды и тут изгалились. передаваемый второй параметр -Code- есть ни что иное, как указатель Self. Это подразумевает то, что по логике вещей метод не должен работать на несозданом объекте


Нет такой логики. При вызове метода "на несозданном объекте" Self не должен использоваться иначе как для проверки на существование — вот это близко к истине. Все равно как передавать nil в метод, требующий параметром указатель или объект.

S> и тогда Бормановцы добавили класс-методы


Ну, объективно говоря это все же не их идея. Разве что они придумали этому понятию более удачное название.

S> (class function — где Self нельзя использовать).


Правда?

S> Частным случаем класс-метода служыт обычный конструктор любого класса.


Хм. Интересно, много ли Вы найдете конструкторов, не использующих Self (согласно Вашему утверждению).

Конструктор — не столько частный пример, сколько особый вид class function, поскольку Self в нем трактуется иначе, чем в "обычных" class method-ах.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.