thx
In WinInet.pas the callback parameter is defined:
INTERNET_STATUS_CALLBACK = TFarProc;
A TFarProc is just a plain old Pointer which is 4 bytes. I think method
pointers are 6 bytes long something about an object pointer and a method
offset. I'm sure you could find out more on google.
Good luck,
Gardner
The parameter list of your callback function must match that expected
by the library or unit you are sending it to. A class member function
includes the self pointer as an additional parameter that is not seen
by you, so cannot be used in winapi calls and such.
If you are defining your own callbacks for internal use you can define
them as
TMyProc = procedure(MyParameter:TSomething) of Object; (of Object
tells us the callback must be a class member)
or TMyProc = procedure(MyParameter:TSomething); (Since of Object is
not used here this callback cannot be a class member).
HTH
Ben
.
"Robert Oschler" <Osc...@earthlink.net> wrote in message
news:3d3744b4$1_1@dnews...
Hi Robert,
> In C++ you can't use non-static class methods as callback functions, I
> forget why, something to do with not really knowing the address of the
> method I think. Is it the same with Delphi class methods?
This is what I have been using for years:
// Helpers to create a callback function out of a object method
{
-----------------------------------------------------------------------------
}
{ This is a piece of magic by Jeroen Mineur. Allows a class method to
be used }
{ as a callback. Create a stub using CreateStub with the instance of the
object }
{ the callback should call as the first parameter and the method as the
second }
{ parameter, ie @TForm1.MyCallback or declare a type of object for the
callback }
{ method and then use a variable of that type and set the variable to
the }
{ method and pass
it: }
{
}
{
type
}
{ TEnumWindowsFunc = function (AHandle: hWnd; Param: lParam): BOOL of
object; stdcall; }
{
}
{ TForm1 =
class(TForm) }
{
private
}
{ function EnumWindowsProc(AHandle: hWnd; Param: lParam): BOOL;
stdcall; }
{
end;
}
{
}
{
var
}
{ MyFunc:
TEnumWindowsFunc; }
{ Stub:
pointer; }
{
begin
}
{ MyFunct :=
EnumWindowsProc; }
{ Stub := CreateStub(Self,
MyFunct); }
{
....
}
{
or
}
{
}
{
var
}
{ Stub:
pointer; }
{
begin
}
{ MyFunct :=
EnumWindowsProc; }
{ Stub := CreateStub(Self,
TForm1.EnumWindowsProc); }
{
....
}
{ Now Stub can be passed as the callback pointer to any windows
API }
{ Don't forget to call Dispose Stub when not needed }
{
-----------------------------------------------------------------------------
}
const
AsmPopEDX = $5A;
AsmMovEAX = $B8;
AsmPushEAX = $50;
AsmPushEDX = $52;
AsmJmpShort = $E9;
type
TStub = packed record
PopEDX: Byte;
MovEAX: Byte;
SelfPointer: Pointer;
PushEAX: Byte;
PushEDX: Byte;
JmpShort: Byte;
Displacement: Integer;
end;
{
-----------------------------------------------------------------------------
}
function CreateStub(ObjectPtr: Pointer; MethodPtr: Pointer): Pointer;
var
Stub: ^TStub;
begin
// Allocate memory for the stub
New(Stub);
// Pop the return address off the stack
Stub^.PopEDX := AsmPopEDX;
// Push the object pointer on the stack
Stub^.MovEAX := AsmMovEAX;
Stub^.SelfPointer := ObjectPtr;
Stub^.PushEAX := AsmPushEAX;
// Push the return address back on the stack
Stub^.PushEDX := AsmPushEDX;
// Jump to the 'real' procedure, the method.
Stub^.JmpShort := AsmJmpShort;
Stub^.Displacement := (Integer(MethodPtr) -
Integer(@(Stub^.JmpShort))) -
(SizeOf(Stub^.JmpShort) + SizeOf(Stub^.Displacement));
// Return a pointer to the stub
Result := Stub;
end;
{
-----------------------------------------------------------------------------
}
{
-----------------------------------------------------------------------------
}
procedure DisposeStub(Stub: Pointer);
begin
Dispose(Stub);
end;
{
-----------------------------------------------------------------------------
}
Method pointers are 8 bytes long. In system.pas there is a declaration to expose
the contents of ll "of object" type method pointers. The address of the object
and the address of the function:
TMethod = record
Code, Data: Pointer;
end;
I hope that helps to clarify things.
--- Mark
You might want to repost that. Either it's screwed up or my OE screwed it up
<g>
--
Dave Nottage (TeamB)
Your OE screwed it up - the 'Begin' bug.
Hit Ctrl+F3 to get it all.
--
Regards,
Chris Luck.
Thanks!
--
Dave Nottage (TeamB)