Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a method as callback to a Windows API call?

Tags:

winapi

delphi

I'd like to pass a method of a class as callback to a WinAPI function. Is this possible and if yes, how?

Example case for setting a timer:

TMyClass = class
public
  procedure TimerProc(Wnd:HWND; uMsg:DWORD; idEvent:PDWORD; dwTime:DWORD);
  procedure DoIt;
end;
[...]
procedure TMyClass.DoIt;
begin
  SetTimer(0, 0, 8, @TimerProc);  // <-???- that's what I want to do (last param)
end;

Thanks for your help!

Edit: The goal is to specify a method of this class as callback. No procedure outside the class.

Edit2: I appreciate all your help but as long as the method has no "TMyClass." in front of its name it is not what I am searching for. I used to do it this way but wondered if could stay fully in the object oriented world. Pointer magic welcome.

like image 532
Heinrich Ulbricht Avatar asked May 07 '10 10:05

Heinrich Ulbricht


1 Answers

Madshi has a MethodToProcedure procedure. It's in the "madTools.pas" which is in the "madBasic" package. If you use it, you should change the calling convention for "TimerProc" to stdcall and DoIt procedure would become,

TMyClass = class
private
  Timer: UINT;
  SetTimerProc: Pointer;
[...]

procedure TMyClass.DoIt;
begin
  SetTimerProc := MethodToProcedure(Self, @TMyClass.TimerProc);
  Timer := SetTimer(0, 0, 8, SetTimerProc);
end;
// After "KillTimer(0, Timer)" is called call:
// VirtualFree(SetTimerProc, 0, MEM_RELEASE);


I've never tried but I think one could also try to duplicate the code in the "classses.MakeObjectInstance" for passing other procedure types than TWndMethod.

like image 183
Sertac Akyuz Avatar answered Sep 20 '22 14:09

Sertac Akyuz