Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Сравнение двух величин TNotifyEvent [D6, WinXP]


Страницы:   1 2 3 4

Andsin ©   (2005-09-26 12:26:00) 

Привет!
Планирую использовать контейнер для уведомления экземляров классов о событии. Именно экземпляров, а не одного экземпляра. Пытаюсь реализовать так:

procedure Foo.AttachOnReply(AnEvent: TNotifyEvent);
var
 matched: boolean;
 i: integer;
begin
 matched := false;
 for i := 0 to Length(FEvents)-1 do
   if FEvents[i] = AnEvent then matched := true;
 if not matched then
 begin
   i := Length(FEvents);
   SetLength(FEvents, i+1);
   FEvents[i] := AnEvent;
 end;
end;

В строчке if FEvents[i] = AnEvent then matched := true;возникают две одинаковых ошибки:
[Error] foo.pas(221): Not enough actual parameters.
т.е. компилятор пытается вызвать соответствующие методы.
Могу ли я исправить код так, чтобы компилятор проверял равенство указателей на метод класса, вместо вызова?
P.S. Преобразование TNotifyEvent  к типу TMethod, на мой взгляд, не является документированной производителем, поэтому такие варианты не катят...

Спасибо!


andsin   (2005-09-27 09:39:00) [41]

И вижу, что находится масса людей, которая не вникла в суть вопроса... повторю вопрос:
Существует ли документированный способ сравнения двух величин типа TNotifyEvent. Преобразование к типу TMethod прошу не предлагать.


andsin   (2005-09-27 09:35:00) [42]


> И чем же эта фраза нелепа? Переменная типа TNotifyEvent
> действительно содержит 2 двойных слова (точно также как
> и TMethod): адрес обработчика и указатель на объект, в контексте
> которого будет вызван этот обработчик, т.е. Self.

Если прочитаете справку по self,  поймете, что это указатель на экземпляр класса, доступный из методов класса. Нелепость в том, что TNotifyEvent будет содержать Self, только в том случае, если из метода какого- либо класса написать примерно следующее

begin
 Form1.OnShow := Self.FormShow;
end;


> Вообще, я бы посоветовал тем, кто начинает работать с указателями
> тем или иным образом, почаще открывать CPU Window и вникать,
>  что и почему.

Да, так можно знаешь до чего довникаться... Нет, справка это единственный источник информации, и по указателям в том числе.

отладка кода на строчке  if @F = @MyFunction then дала отрицательный результат. действительно, содержимое указателя на екземпляр класса не анализируется.
Получается, что без преобразования типов не обойтись, чтоли?


Lamer@fools.ua   (2005-09-27 09:19:00) [43]

>> Defunct ©   (27.09.05 06:17) [17]

> Фраза не так уж нелепа как могло показаться. TMethod( NotifyEvent).data и есть тот самый Self.

Оне не нелепа. Просто некорректна.

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs;

type
 TSomeObj = class(TObject)
 public
   procedure OnFormClick(Sender: TObject);
 end;

 TForm1 = class(TForm)
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   FSomeObj: TSomeObj;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

{ TSomeObj }

procedure TSomeObj.OnFormClick(Sender: TObject);
begin
 ShowMessage('Ку!');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FSomeObj := TSomeObj.Create;
 try
   OnClick := FSomeObj.OnFormClick; // И совсем здесь не Self, а FSomeObj.
 except
   OnClick := nil;
   FreeAndNil(FSomeObj);
   raise;
 end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 OnClick := nil;
 FreeAndNil(FSomeObj);
end;

end.


evvcom   (2005-09-27 08:29:00) [44]


> Фраза не так уж нелепа как могло показаться

неведающему. Не надо всех сюда грести.


Defunct   (2005-09-27 06:17:00) [45]

ps: Самое правильное решение imho jack128 ©   (26.09.05 14:01) [6]
все остальное от лукавого. Особенно @ - вообще ничего не даст.

Andsin   (26.09.05 16:03) [15]
З.Ы. Заметьте, я не стал придираться к вашей нелепой фразе относительно того, что переменная типа TNotifyEvent содержит Self.

Фраза не так уж нелепа как могло показаться. TMethod( NotifyEvent).data и есть тот самый Self.

> Andsin
> if @F = @MyFunction then
так лучше не делать, т.к. методы разных экземляровтак выявить не удастся. С помощью ссылки "@" получите только указатель на метод класса.


evvcom   (2005-09-26 20:20:00) [46]


> слушай, но ведь procedure of object это код, а method pointer
> это текст в стправке

Тоже придирусь. И то, и другое - это текст. Но первый используется в коде для описания типа, а второй является обобщением для первого и еще function of object. А это действительно описано в терминологии, что и советовал jack128 ©   (26.09.05 14:05) [7]подучить.

> Заметьте, я не стал придираться к вашей нелепой фразе относительно
> того, что переменная типа TNotifyEvent содержит Self.

И чем же эта фраза нелепа? Переменная типа TNotifyEvent действительно содержит 2 двойных слова (точно также как и TMethod): адрес обработчика и указатель на объект, в контексте которого будет вызван этот обработчик, т.е. Self.
Вообще, я бы посоветовал тем, кто начинает работать с указателями тем или иным образом, почаще открывать CPU Window и вникать, что и почему.


Andsin   (2005-09-26 16:03:00) [47]


> Да ??? А всегда думал, что

если сейчас вы так не думаете, то напрасно. я имелл ввиду, что procedure of object мы пишем в исходниках, а method pointer написано в хелпе. очень хочется найти явное взаимно-однозначное соответствие написанному в исходниках(для обозначения оного я использовал слово код, которое вам почему-то не понравилось) написанному в хелпах. чего и удалось достичь благодаря alex_*** и GuAV.
З.Ы. Заметьте, я не стал придираться к вашей нелепой фразе относительно того, что переменная типа TNotifyEvent содержит Self.


jack128   (2005-09-26 15:12:00) [48]

jack128 ©   (26.09.05 15:11) [13]
А я всегда думал, что подобная конструкция используется


jack128   (2005-09-26 15:11:00) [49]

andsin   (26.09.05 14:44) [10]
procedure of object это код


Да ??? А всегда думал, что полдобная конструкция используюется при объявлении ТИПА. Переменная этого типа хранит в себе УКАЗАТЕЛЬ на код, а так же Self.


Digitman   (2005-09-26 14:51:00) [50]


> ведь можно же проверить на равенство nil, в этом случае
> компилятор не пытается проверить возвращенное значение


да, можно.
потому что компилятор при этом делает неявное приведение именно к типу TMethod

когда ты объявляешь поле класса/структуры как procedure..of object, компилятор резервирует под это поле область памяти со структурой TMethod.


andsin   (2005-09-26 14:51:00) [51]

авторы [1] и [9], вы абсолютно правы. только надо было мне это в справке показать. вот что я наарыл
f F = MyFunction then ...;

In this case, the occurrence of F results in a function call; the compiler calls the function pointed to by F, then calls the function MyFunction, then compares the results. The rule is that whenever a procedural variable occurs within an expression, it represents a call to the referenced procedure or function. In a case where F references a procedure (which doesn’t return a value), or where F references a function that requires parameters, the statement above causes a compilation error. To compare the procedural value of F with MyFunction, use

if @F = @MyFunction then ...;

@F converts F into an untyped pointer variable that contains an address, and @MyFunction returns the address of MyFunction.
To get the memory address of a procedural variable (rather than the address stored in it), use @@. For example, @@F returns the address of F.

это из справки по оператору @
всем спасибо, вопрос решен.


andsin   (2005-09-26 14:44:00) [52]


> То есть связи между "procedure of object" и "method pointer"
> ты не видешь?? Тогда советую подучить основы языка или терминологии.
>  Либо там, либо там но где ты плаваешь.

слушай, но ведь procedure of object это код, а method pointer это текст в стправке. есть ли в справке что-либо, что бы их связывало, кроме их похожести?
Других методов, кроме использования явного приведения типов нет? ведь можно же проверить на равенство nil, в этом случае компилятор не пытается проверить возвращенное значение...


GuAV   (2005-09-26 14:15:00) [53]

Andsin   (26.09.05 13:36) [2]
сдается, что нет... так я получу лишь адреса элементов, схожих с TMethod, не более того.


Нифига не нет, [1] верно.

procedure TForm1.FormCreate(Sender: TObject);
var
 E1, E2: TNotifyEvent;
begin
 E1 := FormCreate;
 E2 := FormCreate;
 ShowMessage(IntToStr(SizeOf(@E1))); // output is 8
 ShowMessage(BoolToStr(@E2 = @E1, True)); // output is true
 ShowMessage(BoolToStr(@@E2 = @@E1, True)); // output is false
end;


evvcom   (2005-09-26 14:06:00) [54]


> jack128 ©   (26.09.05 14:01) [6]

лень сейчас проверять, но по-моему любое употребление AnEvent без @ (кроме банального присваивания переменной типа TNotifyEvent) будет восприниматься компилятором как вызов обработчика.


jack128   (2005-09-26 14:05:00) [55]

Andsin   (26.09.05 13:51) [4]
Я это видел. Не убедительно как-то... Про procedure of objectни слова.

This type can be used in a type cast of a method pointerto access
То есть связи между "procedure of object" и "method pointer" ты не видешь?? Тогда советую подучить основы языка или терминологии. Либо там, либо там но где ты плаваешь.


jack128   (2005-09-26 14:01:00) [56]

if (TMethod(FEvents[i]).Code = TMethod(AnEvent).Code) and (TMethod(FEvents[i]).Data = TMethod(AnEvent).Data) then ...


evvcom   (2005-09-26 13:58:00) [57]


> Andsin   (26.09.05 13:51) [4]

Ну как знаешь!
А в FEvents[i] = AnEvent идет именно вызовобработчика AnEvent, а тебе нужны указатели.


Andsin   (2005-09-26 13:51:00) [58]

Я это видел. Не убедительно как-то... Про procedure of object ни слова.


Digitman   (2005-09-26 13:40:00) [59]


> Преобразование TNotifyEvent  к типу TMethod, на мой взгляд,
>  не является документированной производителем


это почему же ?

оч даже документирован !

и сам тип в интерф.части описан, и в справке черным по белому сказано :

This type can be used in a type cast of a method pointer to access the code and data parts of the method pointer.


Andsin   (2005-09-26 13:36:00) [60]

сдается, что нет... так я получу лишь адреса элементов, схожих с TMethod, не более того.


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо