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