-
Пытаюсь отловить сообщения окон при помощи SetWinEventHook Хук ставится, сообщения ловятся, все работает, но нередко после успешного вызова UnhookWinEvent, dll-файл не удается удалить (Delphi пишет: [Fatal Error] Could not create output file 'WinHook.dll'). Другими словами, библиотека не выгружается из адресного пространства каких-то процессов. С чем это может быть связано.
const WM_EVENT_HOOK = WM_USER + $FF;
var hWinHook : HWND; hLogWin : HWND;
function CheckWindow(hWnd : HWND) : Boolean; var WindowName : array[0..64] of Char; WindowClass : array[0..32] of Char; begin ... end;
procedure HookProc(hWinEventHook: THandle; Event: DWORD; hWnd: HWND; idObject, idChild: Longint; idEventThread, dwmsEventTime: DWORD); stdcall; begin if (idObject = OBJID_WINDOW) and (idChild = CHILDID_SELF) then if CheckWindow(hWnd) then PostMessage(hLogWin, WM_EVENT_HOOK, hWnd, Event); end;
function SetHook(State : Boolean; Manager : HWND) : Boolean; export; stdcall; begin if State then begin hWinHook := SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_DESTROY, hInstance, @HookProc, 0, 0, WINEVENT_INCONTEXT); Result := hWinHook > 0; end else begin Result := UnhookWinEvent(hWinHook); end; end;
procedure DLLEntryPoint(dwReason:DWord); begin case dwReason of DLL_PROCESS_ATTACH: hLogWin := FindWindow(...) end; end;
exports SetrHook;
{$R *.res}
begin DllProc:= @DLLEntryPoint; DLLEntryPoint(DLL_PROCESS_ATTACH); end.
-
> [0] ЗапомниСынок (31.05.08 11:43)
> С чем это может быть связано.
с архитектурой и идеалогией системы.
-
> [0] ЗапомниСынок (31.05.08 11:43) > С чем это может быть связано.
С неправильной реализацией. Была статья про Hook`и. Поищи ее.
-
Собственно проблема проблемой является только при отладке. Когда не удается повторно скомпилировать файл, приходится перезагружать систему.
2 LightRipple Может вы мне еще подскажите в чем заключается неправильная реализация.
-
> [3] ЗапомниСынок (31.05.08 13:50) > Может вы мне еще подскажите в чем заключается неправильная реализация.
IHMO, в работе с глобальными переменными. Позволю себе повториться: поищи статью. Вроде она была на этом форуме. Не помню :(
-
А где обещали мгновенную выгрузку ?
-
> [5] guav © (31.05.08 14:04) > А где обещали мгновенную выгрузку ?
А про мгновенную я ничего не говорила :)
-
> ЗапомниСынок (31.05.08 11:43)
> из адресного пространства каких-то процессов. С чем это > может быть связано.
Dll c обычными хуками не выгружаются сразу после снятия оных. Им требуется еще, чтобы в зацепленном потоке произошло еще одно отлавливаемое событие. Например, для WH_GETMESSAGE это Post(Thread)Message.
Возможно, что и в случае WinHook требуется нечто подобное. Можно попробывать генирировать кустомное сообщение.
Да, и еще [4]. И так делать не надо:
> case dwReason of > DLL_PROCESS_ATTACH: > hLogWin := FindWindow(...)
hLogWin, то можно, например, найти его при первом вызове HookProc. > {$R *.res} Это какие такие ресурсы?
-- Regards, LVT.
-
> Leonid Troyanovsky © (31.05.08 15:03) [7]
> Можно попробывать генирировать кустомное сообщение.
В смысле - событие, sorry.
-- Regards, LVT.
-
2 LightRipple Прежде чем давать ответ на вопрос, можно было хотя бы взглянуть на код. Вы путаете функции SetWinEventHook и SetWindowsHookEx. Во втором случае дескриптор Hook-а требуется для корректного вызова CallNextHookEx. В первом случае этого не требуется, поэтому и выделять общую область памяти при момощи CreateFileMapping не нужно.
2 Leonid Troyanovsky Ясно, примерно так я и думал. Спасибо. Проблема собственно заключается в том, что после установки hook-а становится невозможным продолжать разработку программы. поскольку dll не удается скомпилировать заново. Приходится либо перегружать систему, либо идти пить чай, поскольку через некоторое время библиотека выгружается.
{$R *.res} Осталось после генерации библиотеки средой :) Вы правы.
>> case dwReason of >> DLL_PROCESS_ATTACH: >> hLogWin := FindWindow(...)
>hLogWin, то можно, например, найти его при первом >вызове HookProc.
Можно, причем не находить, а просто передавать в функцию SetHook, но тогда как раз придется выделять общую память, чтобы предоставить доступ к этому hLogWin всем экземплярам dll. Предполагается, что Hook устанавливается/снимается при создании/уничтожении окна FindWindow(...), т.е. окно заведомо существует, поэтому не вижу здесь ничего криминального. Вопрос разве что в скорости, может вы и правы.
-
> [9] ЗапомниСынок (02.06.08 09:53) > Прежде чем давать ответ на вопрос, можно было хотя бы взглянуть на код. > Вы путаете функции SetWinEventHook и SetWindowsHookEx.
Sorry. Действительно, невнимательна :(
-
> ЗапомниСынок (02.06.08 09:53) [9]
> окна FindWindow(...), т.е. окно заведомо существует, поэтому > не вижу здесь ничего криминального. Вопрос разве что в скорости, > может вы и правы.
Во-ще-то, я имел ввиду http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspxТ.е., все отклонения от генерального курса должны быть тщательно обдуманы и обоснованны. Сомнительным в одноразовой передаче хендла приемника является участок от начала HookProc до PostMessage. Возможно, что PostThreadMessge здесь более предпочтителен. > Приходится либо перегружать систему
Думаю, что хватит и логофа. -- Regards, LVT.
|