Reputation: 410
I've got some problems with EnumWindows
function that uses callback function from a nested class:
TProcessWatch = class(TObject)
private
...
type
TProcessInfo = class(TObject)
private
type
PEnumCallbackParam = ^TEnumCallbackParam;
TEnumCallbackParam = class
A : Integer;
...
end;
private
FOwner : TProcessWatch;
function FEnumWindowsCallback(hWindow : HWND; lParam : LPARAM) : BOOL; export;
procedure SomeProc;
...
end;
private
FProcesses : TProcessInfo;
...
public
...
Within the SomeProc
there is a call to EnumWindows
EnumCallbackParam := TEnumCallbackParam.Create;
try
EnumCallbackParam.A := 0;
EnumWindows(@TProcessWatch.TProcessInfo.FEnumWindowsCallback, LongInt(@EnumCallbackParam));
...
finally
EnumCallbackParam.Free;
end;
And here is a FEnumWindowsCallback
function listing:
function TProcessWatch.TProcessInfo.FEnumWindowsCallback(hWindow: HWND;
lParam : LPARAM): BOOL; export;
var
CallbackParam : PEnumCallbackParam;
begin
CallbackParam := Pointer(lParam); // A is inaccessible
Result := True;
...
end;
In runtime, when EnumWindows
is called, FEnumWindowsCallback
is always receiving hWindow = 0
and lParam
is pointing to inaccessible value.
All this working fine if callback function is declared private in the form, but when I've tried to make this function private in nested class it went wrong.
Why? And how to make this working? The goal is to make FEnumWindowsCallback
and all other involved functions private in TProcessWatch
.
Upvotes: 2
Views: 226
Reputation: 612794
The callback is declared wrongly. It should be:
class function EnumWindowsCallback(hWindow: HWND;
lParam: LPARAM): BOOL; static; stdcall;
You were using the wrong calling convention, and an instance method.
Other comments:
EnumCallbackParam
is already a pointer. You can pass it as the param.LPARAM
rather then LongInt
so that you code will work if you ever compile to 64 bit. export
keyword has no meaning in 32 or 64 bit Delphi. It is ignored and you should not use it since it adds clutter and may confuse. Upvotes: 4