Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Hooks: память не может быть read. [D7, WinXP]


MikeZ ©   (2008-07-16 19:21:00) 

Всем привет!

Надо было сделать глобальный хук на создание окна (WH_SHELL + HSHELL_WINDOWCREATED). Делал хук по статье "Hooks - аспекты реализации" ( http://delphimaster.ru/articles/hooks/index.html) и её 3-му примеру ( http://delphimaster.ru/articles/hooks/example.zip). Выглядит это так:
Procedure SetHook(Switch: Boolean; hMainProg: HWnd) Export; Stdcall;
Begin
 If Switch = True Then
   Begin
     GlobalData^.SysHook := SetWindowsHookEx(WH_SHELL, @HookProc, HInstance, 0);
     {...}
   end
 Else
   Begin
     UnHookWindowsHookEx(GlobalData^.SysHook);
     {...}
   end;
end;

Где функция-фильтр имеет вид:
Function HookProc(Code: Integer; WParam: WParam; LParam: LParam): LRESULT; Stdcall;
Begin
 If Code = HSHELL_WINDOWCREATED Then
   SendMessage(GlobalData^.MyAppWnd, WM_MYMESS, WParam, LParam);
 Result := CallNextHookEx(GlobalData^.SysHook, Code, WParam, LParam);
End;


В самой программе делаю:
Procedure TForm1.WndProc(Var Msg: TMessage);
Begin
 Inherited;
 If Msg.Msg = WM_MYMESS Then
   Begin
     {Просто записываю handle новосозданного окна}
     ListBox1.Items.Insert(0, IntToStr(Msg.WParam));
   End;
End;


Вроде бы всё делал правильно, но у процессов, запускающих окна, а потом и в моей программе (или в Delphi, если запускаю из-под неё) возникает сообщение "Память не может быть Read", а за ним, если правильно помню, AV. Откомпилировал 3-й пример из статьи, думал, я что-то не так "подправил", так он тоже как-то не очень стабильно работает, тоже эти ошибки выдаёт. Систему DEP отключил полностью, вычитав, что она такие ошибки может провоцировать. Подскажите, что я не так делаю, может, где какая ошибка проскочила?


MikeZ   (2008-07-17 15:23:00) [1]

Rouse_
Да, это именно оно и было! Большое спасибо!
(в ту степь вообще не смотрел :( )

Сергей М.
Тоже спасибо!


Сергей М.   (2008-07-17 10:39:00) [2]

Ну и IsMultiThread=True при инициализации библиотеки будет явно не лишним (в примерах отсутствует), если используется потоконебезопасный менеджер памяти


Rouse_   (2008-07-17 09:44:00) [3]

А в дельфи учитывается тип, а не его наименование, поэтому LParam <> LParam :)


SergeyIT   (2008-07-17 09:41:00) [4]

В С учитывается регистр, поэтому WPARAM <> wParam


Rouse_   (2008-07-17 09:38:00) [5]

В библиотеке из примера нужно убрать STDCALL у procedure DLLEntryPoint.


> Нехорошо переменные именовать как типы

Пиши в Microsoft, пусть срочно переписывают MSDN :)

LRESULT CALLBACK ShellProc(          int nCode,
   WPARAM wParam,
   LPARAM lParam
);


SergeyIT   (2008-07-17 09:28:00) [6]


> WParam: WParam; LParam: LParam

Нехорошо переменные именовать как типы


Сергей М.   (2008-07-17 08:43:00) [7]


> в моей программе


> а за ним, если правильно помню, AV


Если так, то можно воспользоваться встроенным отладчиком, для детального поиска "неисправности".

Изучи стандартный справочный материал по теме назначения пункта IDE-меню "Run|Parameters"


MikeZ   (2008-07-17 08:31:00) [8]

Да, все проверки есть (и в статье тоже): GlobalData не nil. Иначе, кстати, не было бы передачи handle нового окна в программу:
SendMessage(GlobalData^.MyAppWnd, WM_MYMESS, WParam, LParam);
А передача такая есть, т.е. тут всё в порядке.


SergeyIT   (2008-07-16 23:36:00) [9]

Проверьте GlobalData^ на nil


SergeyIT   (2008-07-16 23:35:00) [10]

Вероятно GlobalData^ в процессах недоступрно.


Eraser   (2008-07-16 21:56:00) [11]

на сколько помню в примере хука на этом сайте какие-то ошибки, какие - не помню.


Наверх

Титульная страница Поиск, карта сайта Написать письмо