![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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]на сколько помню в примере хука на этом сайте какие-то ошибки, какие - не помню.