Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема с указателем на метод класса

8.3K
24 апреля 2006 года
banshee
40 / / 25.11.2005
Доброго времени суток. Создаю класс, одним из методов которого реализована функция EnumWindows (перечисляет окна верхнего уровня), которая должна получать указатель на функцию EnumWindowsProc. EnumWindowsProc тоже реализована как метод класса (она активно использует поля класса). Вызываю так:

EnumWindows(@MyClass.EnumWindowsProc, 0);

Проблема в том, что вызванная таким образом EnumWindowsProc не видит значения полей (они заполнены всякой белибердой). Смотрел в отладчике – ощущение такое, что когда я вызываю метод класса используя указатель, то создается новый экземпляр класса :( Заранее благодарен.
5
24 апреля 2006 года
hardcase
4.5K / / 09.08.2005
Ну ты даал!!!
Метод класса - это процедура/функция вида:
 
Код:
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;
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог