Форум: "Основная";
Текущий архив: 2004.01.20;
Скачать: [xml.tar.bz2];
ВнизКак получить указатель на функцию класса? Найти похожие ветки
← →
maker (2004-01-07 22:23) [0]:: @Как получить указатель на функцию класса?
← →
raidan (2004-01-07 22:43) [1]Учи матчасть.
← →
maker (2004-01-07 22:52) [2]и все-же...
← →
Юрий Зотов (2004-01-07 22:56) [3]Вот прямо так и получить:
Ptr := @MyMethod;
← →
maker (2004-01-08 09:28) [4]Вот например такой случай:
TEx=class
function FUNC1:pointer;
function FUNC2:byte;
end;
<...>
function TEx.FUNC1:pointer;
begin
//Здесь будет ошибка
FUNC1:=@FUNC2;
end;
function TEx.FUNC2:byte;
begin
Result:=23;
end;
как получить указатель в таком случае?
← →
alex_*** (2004-01-08 09:33) [5]указатель на Func2 нужен?
type
PFunc2 = function ():byte of object;
var
PFunc: PFunc2;
PFunc := @ex.Func2;
← →
alex_*** (2004-01-08 09:36) [6]вернее
PFunc := ex.Func2;
← →
Тимохов (2004-01-08 11:34) [7]Надо так
function TEx.FUNC1:pointer;
begin
FUNC1:=@TEx.FUNC2;
end;
← →
alex_*** (2004-01-08 11:43) [8]ну тогда Func2 надо определить как class function FUNC2:byte;
и собаку я бы убрал ))
← →
Kerk (2004-01-08 11:43) [9]Методы класса приводятся к типу TMethod
Посмотри описание этого типа, там кажется есть указатель на экземпляр класса и указатель на данную функцию
← →
Тимохов (2004-01-08 11:45) [10]alex_*** © (08.01.04 11:43) [8]
Я написал точно правильно, т.к. именно это я использую в своей программе. Это точно работает и работает правильно.
← →
alex_*** (2004-01-08 11:49) [11]ну не знаю. у меня не компилится. пришлось сделать 2 изменения:
1. тип Func1 пришлось сделать как function():Boolean of object;
2. и поставить class перед определеинем Func2
в противном случае придется извращаться через TMethod.
← →
Kerk (2004-01-08 11:53) [12]
> alex_*** © (08.01.04 11:49) [11]
> ну не знаю. у меня не компилится. пришлось сделать 2 изменения:
> 1. тип Func1 пришлось сделать как function():Boolean of
> object;
так это естесственно, т.к. function(): Boolean - это TFunction, а function(): Boolean of object - это TMethod.
типы совсем разные.
> в противном случае придется извращаться через TMethod.
почему извращаться? наиболее прямой метод.
← →
Тимохов (2004-01-08 11:54) [13]Такой кусок у меня компилиться.
TEx = class
function FUNC1:pointer;
function FUNC2:byte;
end;
function TEx.FUNC1:pointer;
begin
Result := @TEx.FUNC2;
end;
function TEx.FUNC2:byte;
begin
Result := 23;
end;
← →
alex_*** (2004-01-08 12:00) [14]OK. Скомпилился. сам виноват.
← →
maker (2004-01-08 20:58) [15]Посмотрите пожалуйста, что не так с указателями()...
<...>
type
TApiForm=class
constructor Create(ClassName,Name:string;W,H,X,Y:integer);
function WindowProc (Window: HWND; Message, WParam: Cardinal; LParam: Cardinal): Longint; stdcall;
end;
<...>
function TApiForm.WindowProc (Window: HWND; Message, WParam: Cardinal; LParam: Cardinal): Longint; stdcall;
begin
Result := DefWindowProc (Window, Message, WParam, LParam);
end;
constructor TApiForm.Create(ClassName,Name:string;W,H,X,Y:integer);
var
WClass : WNDCLASS;
FormHWND : HWND;
ExMsg : MSG;
lpMsgBuf : PChar;
begin
WClass.style:=cs_hredraw or cs_vredraw;
// - Так все работает!:
// WClass.lpfnWndProc:=@DefWindowProc;
// - Так НЕТ..,
WClass.lpfnWndProc:=@TApiForm.WindowProc;
WClass.cbClsExtra:=0;
WClass.cbWndExtra:=0;
WClass.hInstance:=HInstance;
WClass.hIcon:=LoadIcon(0,idi_application);
WClass.hCursor:=LoadCursor(0,idc_arrow);
WClass.hbrBackground:=COLOR_BTNFACE+1;
WClass.lpszMenuName:=nil;
WClass.lpszClassName:=PChar(ClassName);
if Windows.RegisterClass(WClass) = 0 then begin
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
nil, GetLastError(), 0, @lpMsgBuf, 0, nil);
MessageBox(HWND_Desktop,lpMsgBuf, "Ошибка", MB_ICONINFORMATION);
Exit;
end;
FormHWND:=CreateWindowEx(0,PChar(ClassName),PChar(Name),
WS_POPUP,X,Y,W,H,0,0,HInstance,nil);
if FormHWND = 0 then begin
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
nil, GetLastError(), 0, @lpMsgBuf, 0, nil);
MessageBox(HWND_Desktop,lpMsgBuf, "Ошибка", MB_ICONINFORMATION);
Exit;
end;
ShowWindow (FormHWND, SW_SHOWNORMAL);
UpdateWindow (FormHWND);
//while GetMessage(ExMsg,0,0,0) do begin
// TranslateMessage (ExMsg);
// DispatchMessage(ExMsg);
//end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
APIForm:TApiForm;
begin
APIForm.Create("MyClass","myWindow",200,200,100,100);
end;
← →
Teren (2004-01-09 02:01) [16]Хех, свой VCL пишешь :)
1) Я не понимаю, как может работать
WClass.lpfnWndProc:=@DefWindowProc
Ведь DefWindowProc это экспортируемая функция... разве вот так можно на нее указатель передать?
2) WClass.lpfnWndProc:=@TApiForm.WindowProc
а это ежу понятно, что работать не будет.
Читаем HELP:
lpfnWndProc - Points to the window procedure. For more information, see WindowProc
Смотрим WindowProc
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle of window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
Как видишь, функция принимает четыре параметра. А твоя TApiForm.WindowProc принимает пять параметров. Первый - это скрытый параметр Self, ведь твоя TApiForm.WindowProc является методом класса TApiForm
К тому же, если уж и не было бы параметра Self, все равно неорректно писать
function TApiForm.WindowProc...
...
WClass.lpfnWndProc:=@TApiForm.WindowProc
Ты в методе класса обращаешься к типу класса - не надо так делать. Тебе ведь надо дать ссылку на метод РЕАЛЬНО существующего класса, то есть:
WClass.lpfnWndProc:=@WindowProc
Но все равно так не прокатит из-за Self"а
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.01.20;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.01 c