![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
SetWinEventHook
ЗапомниСынок © (2008-05-31 11:43:00)Пытаюсь отловить сообщения окон при помощи 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.
Leonid Troyanovsky (2008-06-02 18:42:00) [1]
> ЗапомниСынок (02.06.08 09:53) [9]
> окна FindWindow(...), т.е. окно заведомо существует, поэтому
> не вижу здесь ничего криминального. Вопрос разве что в скорости,
> может вы и правы.
Во-ще-то, я имел ввиду
http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx
Т.е., все отклонения от генерального курса должны быть
тщательно обдуманы и обоснованны.
Сомнительным в одноразовой передаче хендла приемника
является участок от начала HookProc до PostMessage.
Возможно, что PostThreadMessge здесь более предпочтителен.
> Приходится либо перегружать систему
Думаю, что хватит и логофа.
--
Regards, LVT.
LightRipple (2008-06-02 11:47:00) [2]> [9] ЗапомниСынок (02.06.08 09:53)
> Прежде чем давать ответ на вопрос, можно было хотя бы взглянуть на код.
> Вы путаете функции SetWinEventHook и SetWindowsHookEx.
Sorry. Действительно, невнимательна :(
ЗапомниСынок (2008-06-02 09:53:00) [3]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(...), т.е. окно заведомо существует, поэтому не вижу здесь ничего криминального. Вопрос разве что в скорости, может вы и правы.
Leonid Troyanovsky (2008-05-31 15:05:00) [4]
> Leonid Troyanovsky © (31.05.08 15:03) [7]
> Можно попробывать генирировать кустомное сообщение.
В смысле - событие, sorry.
--
Regards, LVT.
Leonid Troyanovsky (2008-05-31 15:03:00) [5]
> ЗапомниСынок (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.
LightRipple (2008-05-31 14:09:00) [6]> [5] guav © (31.05.08 14:04)
> А где обещали мгновенную выгрузку ?
А про мгновенную я ничего не говорила :)
guav (2008-05-31 14:04:00) [7]А где обещали мгновенную выгрузку ?
LightRipple (2008-05-31 13:56:00) [8]> [3] ЗапомниСынок (31.05.08 13:50)
> Может вы мне еще подскажите в чем заключается неправильная реализация.
IHMO, в работе с глобальными переменными.
Позволю себе повториться: поищи статью.
Вроде она была на этом форуме. Не помню :(
ЗапомниСынок (2008-05-31 13:50:00) [9]Собственно проблема проблемой является только при отладке. Когда не удается повторно скомпилировать файл, приходится перезагружать систему.
2 LightRipple
Может вы мне еще подскажите в чем заключается неправильная реализация.
LightRipple (2008-05-31 13:10:00) [10]> [0] ЗапомниСынок (31.05.08 11:43)
> С чем это может быть связано.
С неправильной реализацией.
Была статья про Hook`и. Поищи ее.
Eraser (2008-05-31 12:52:00) [11]> [0] ЗапомниСынок (31.05.08 11:43)
> С чем это может быть связано.
с архитектурой и идеалогией системы.