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...
Пока на собственное сообщение не было ответов, его можно удалить.