Проблема с указателем на метод класса
EnumWindows(@MyClass.EnumWindowsProc, 0);
Проблема в том, что вызванная таким образом EnumWindowsProc не видит значения полей (они заполнены всякой белибердой). Смотрел в отладчике – ощущение такое, что когда я вызываю метод класса используя указатель, то создается новый экземпляр класса :( Заранее благодарен.
Метод класса - это процедура/функция вида:
Код:
procedure Method(Self: TItsClass; <другие параметры>); register; (а не stdcall !!)
явный параметр Self-указатель на вызывавший объект передаётся неявным образом, но он ВСЕГДА есть. Все процедуры/функции в делфи по умолчанию вызываются по соглашению register (fastcall или borland_fastcall) и параметры частично передаются через быстрые регистры, а частично - через стек. (обычно первые четыре 4-байтовых параметра идут в регистры - остальные в стек), в то время как stdcall требует передачи ВСЕХ параметров через стек.
Для корректной работы EnumWindows должна получать адрес функции вида:
Код:
function EnumWindowsProc(Wnd: THandle; Some4BytesParam: pointer): LongBool; stdcall;
В твоём случае нужно делать так:
Код:
TMyClass = class
function NextWindow(Handle: THandle): boolean;
procedure EnumWindows;
end;//of class
function EnumWindosProc(Wnd: THandle; Obj: TMyClass): LongBool; stdcall;
begin
if Obj <> nil then
// передаём хэндл
Result:=Obj.NextWindow(Wnd)
else
// на всякий случай ;)
Result:=false;
end;
function TMyClass.NextWindow(Handle: THandle): boolean;
begin
// делаем чё хотим с хэндлом
Result:=true; // продолжаем перечисление или
Result:=false; // останавливаем перечисление
end;
procedure TMyClass.EnumWindows;
begin
EnumWindows(@EnumWindowsProc, integer(Self));
end;
function NextWindow(Handle: THandle): boolean;
procedure EnumWindows;
end;//of class
function EnumWindosProc(Wnd: THandle; Obj: TMyClass): LongBool; stdcall;
begin
if Obj <> nil then
// передаём хэндл
Result:=Obj.NextWindow(Wnd)
else
// на всякий случай ;)
Result:=false;
end;
function TMyClass.NextWindow(Handle: THandle): boolean;
begin
// делаем чё хотим с хэндлом
Result:=true; // продолжаем перечисление или
Result:=false; // останавливаем перечисление
end;
procedure TMyClass.EnumWindows;
begin
EnumWindows(@EnumWindowsProc, integer(Self));
end;