Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
type
// TMax и TMax2 должны использовать одинаковое соглашение о вызове
// для всех стандартных обработчиков и процедур
// в Delphi по умолчанию используется модель register
// можно указать модель вызова явно
TMax = procedure (P:PChar) of object; stdcall; <- метод класса
TMax2 = procedure (Self: TObject; P:PChar); stdcall; <- процедура
// В процедуре, которая должна быть обработчиком события,
// необходимо явно описать еще один, дополнительный параметр,
// который будет получать значение Self.
// Self скрытый параметр, который передается каждому методу в объекте.
// Он позволяет методу обратиться к объекту.
// поэтому в описание TMax2 добавлен первым параметр Self: TObject.
procedure TSomeObject.Max(P: PChar);
begin
ShowMessage(P);
end;
procedure Max2(Self: TObject; P:PChar); stdcall;
begin
ShowMessage(P)
end;
procedure Hello(T: TMax);
begin
T('Hello');
end;
// Наша задача: вызвать процедуру Hello, передав ей процедуру типа TMax2
// вместо ожидаемого ею метода класса
procedure Test;
var
Method: TMethod;
begin
// TMethod - специальный тип TMethod, описанный в модуле System
// используемый для приведения типов.
// Он представляет собой внутреннюю реализацию объектного процедурного типа.
// Method.Code - указатель на метод класса
Method.Code := @Max2;
// Method.Data - объект, который будет передан в качестве Self
// в метод
Method.Data := nil;
// Вызываем Hello с помощью приведения типов...
Hello(TMax(Method))
end;
Что такое метод класса, как переменные такого типа представляются в памяти (TMethod) и чем это отличается от процедурного типа.
Я надеюсь автор или сам разберется, как работает этот "обман" Delphi, или попросит пояснений :)
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.