Текущий архив: 2005.03.20;
Скачать: CL | DM;
Вниз
Почему хук срабатывает несколько раз? Найти похожие ветки
← →
guest_Dmitry (2005-02-10 08:05) [0]Ставлю ловушку WH_CBT, перехватываю сообщение HCBT_CREATEWND. В результате при создании окна хук срабатывает несколько раз. Почему так?
← →
Digitman © (2005-02-10 08:14) [1]цитата из станд.справки :
HCBT_CREATEWND A window is about to be created. The system calls the hook procedure before sending the WM_CREATE or WM_NCCREATE message to the window
← →
guest_Dmitry (2005-02-10 08:23) [2]Справку я прочитал, но почему несколько раз? Может ловушку тогда другую поставить?
← →
guest_Dmitry (2005-02-10 08:26) [3]Справку я прочитал, но почему несколько раз? Может ловушку тогда другую поставить?
← →
Digitman © (2005-02-10 08:52) [4]
> Справку я прочитал, но почему несколько раз?
не знаю, что ты там читал, но в справке четко написано почему)
при создании окна система посылает сначала WM_NCCREATE , а затем WM_CREATE
и, согласно справке, перед посылкой КАЖДОГО из этих сообщений, система вызывает хук-ф-цию HCBT_CREATEWND
← →
guest_Dmitry (2005-02-10 11:18) [5]Чтобы перехватить сообщение WM_CREATE какую ловушку следует использовать?
← →
Digitman © (2005-02-10 11:26) [6]смотря в какой момент нужен перехват
WH_CBT - до постановки сообщения в очередь
WH_CALLWNDPROC - в момент постановки сообщения в очередь
WH_CALLWNDPROCRET - в момент возврата результата обработки сообщения
WH_GETMESSAGE - в момент выборки сообщения из очереди вызовами Get/PeekMessage
← →
guest_Dmitry (2005-02-10 12:20) [7]Мне момент не важен, нужно зафиксировать сам факт открытия окна.
Почитав статью с этого сайта, хук ставлю следующим образом:
function CallWndProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
var
AppWnd: HWND;
if code < 0 then
begin
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
Exit;
end;
if TMsg(Pointer(lParam)^).message = WM_CREATE
then
begin
AppWnd:= GetForegroundWindow();
SendMessage(HWND_BROADCAST, WM_MYKEYHOOK, wParam, AppWnd);
end;
CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
Result:= 0;
end;
В результате получаю бесконечное срабатывание хука. Что не так в коде?..
← →
VMcL © (2005-02-10 12:25) [8]>>guest_Dmitry (10.02.05 12:20) [7]
>Что не так в коде?..
SendMessage.
← →
guest_Dmitry (2005-02-10 12:33) [9]SendMessage - сообщение в мое приложение, в котором передаю handle окна, которое создается. А что не так с SendMessage?
← →
GuAV © (2005-02-10 12:52) [10]
> if TMsg(Pointer(lParam)^).message = WM_CREATE
А почему TMsg ? Где написано что lParam указывает на TMsg ?
← →
GuAV © (2005-02-10 12:59) [11]
> CallWndProc(code : integer; wParam : word; lParam :
> longint
wParam когда-то может и был Word но не для
> [D5, Win95/98, WinXP]
Надо такfunction CallWndProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
← →
guest_Dmitry (2005-02-10 13:03) [12]мда.. действительно, исправил на
TCWPStruct(Pointer(lParam)^).message = WM_CREATE
но все равно получается, что хук срабатывает раз 15..
← →
Digitman © (2005-02-10 13:08) [13]
> все равно получается, что хук срабатывает раз 15
ну ты же поставил WH_CALLWNDPROC-хук ?
а чего ж ты хочешь тогда ?
все твои асинхронные Sendmessage в теле твоей CallWndProc-ф-ции опять же будут приводить к вызову хук-ф-ции, на то это хук (WH_CALLWNDPROC) и существует ...
← →
guest_Dmitry (2005-02-10 13:15) [14]GuAV © (10.02.05 12:59) [11]
видимо справка древняя у меня.. поправил.
Digitman © (10.02.05 13:08) [13]
у меня задача стоит записать в файл имя запущеного приложения. Каким образом тогда передать значение в мое приложение?
← →
GuAV © (2005-02-10 13:19) [15]guest_Dmitry (10.02.05 13:03) [12]
но все равно получается, что хук срабатывает раз 15..
А hwnd разные ? Может просто создаётся 15 окон ?
guest_Dmitry (10.02.05 13:15) [14]
у меня задача стоит записать в файл имя запущеного приложения.
Так записать в файл, а SendMessage зачем ?
← →
GuAV © (2005-02-10 13:26) [16]
> видимо справка древняя у меня.. поправил.
Ха, я понял.. это не справка древняя а код тупо скопирован из примера к статье. Статья хорошая, а вот код к ней - не очень, там ещё ошибка есть.
← →
Digitman © (2005-02-10 13:31) [17]
> guest_Dmitry (10.02.05 13:15) [14]
> у меня задача стоит записать в файл имя запущеного приложения.
а если приложение консольное ? и не создает никаких окон ?
← →
guest_Dmitry (2005-02-10 13:43) [18]GuAV © (10.02.05 13:19) [15]
>А hwnd разные ? Может просто создаётся 15 окон ?
hwnd одинаковые.
>Так записать в файл, а SendMessage зачем ?
из dll?
GuAV © (10.02.05 13:26) [16]
Справку я имел в виду по WinAPI. Каюсь, код скопировал. Пытаюсь со справкой разобраться в нем.
Digitman © (10.02.05 13:31) [17]
консольные, думаю, не нужны.
← →
GuAV © (2005-02-10 14:06) [19]
> hwnd одинаковые.
Вот эти
> AppWnd:= GetForegroundWindow();
скорее всего будут одинаковыми.
Какому окну посылается WM_CREATE и как это окно связанно с foreground window ?
← →
GuAV © (2005-02-10 14:13) [20]guest_Dmitry (10.02.05 13:43) [18]
из dll?
Действительно, чтобы избежать попытки записывать в файл одновременно, проще писать из ехе.
← →
guest_Dmitry (2005-02-10 14:25) [21]GuAV © (10.02.05 14:06) [19]
AppWnd:= GetForegroundWindow(); - тут я пытаюсь получить handle открываемого окна. Если я не прав, то поправьте пожалуйста.
← →
guest_Dmitry (2005-02-10 14:30) [22]Переделал в такой вариант - в файл вообще ничего не пишется..
function CallWndProc(code : integer; wParam : WPARAM; lParam : LPARAM) : LRESULT; stdcall;
var
AppWnd: HWND;
f: TextFile;
begin
if code < 0 then
begin
Result:= CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
Exit;
end;
if TCWPStruct(Pointer(lParam)^).message = WM_CREATE
then
begin
AppWnd:= GetForegroundWindow();
AssignFile(f, "c:\report.txt");
writeln(f, "It is work");
CloseFile(f);
end;
CallNextHookEx(GlobalData^.SysHook, Code, wParam, lParam);
Result:= 0;
end;
← →
GuAV © (2005-02-10 16:45) [23]guest_Dmitry (10.02.05 14:30) [22]
AssignFile(f, "c:\report.txt");
writeln(f, "It is work");
CloseFile(f);
А append или rewrite кто делать будет ?
В прочем, в [21] я согласился уже, что писать в файл лучше из осн. программы.
guest_Dmitry (10.02.05 14:25) [21]
Нет, это handle of the foreground window. А окно которое создаётся это то окно которое получает WM_CREATE, т.е. его handle в TCWPStruct(Pointer(lParam)^).
← →
GuAV © (2005-02-10 16:46) [24]GuAV © (10.02.05 16:45) [23]
В прочем, в [21] я согласился уже,
Имелось ввиду в [20]
← →
Игорь Шевченко © (2005-02-10 16:53) [25]Digitman © (10.02.05 08:52) [4]
Сергей, система вызывает хук WH_CBT один раз при создании окна, перед посылкой сообщения WM_NCCREATE.
С уважением,
← →
Digitman © (2005-02-10 17:01) [26]
> Игорь Шевченко © (10.02.05 16:53) [25]
Игорь, прокомментируй в данном случае свое видение фразы [1]..
← →
Игорь Шевченко © (2005-02-10 17:20) [27]
> HCBT_CREATEWND A window is about to be created. The system
> calls the hook procedure before sending the WM_CREATE or
> WM_NCCREATE message to the window
Ну, MS считает, что WM_NCCREATE может быть не послано.. Точнее, пишет, что считает, на самом деле оно посылается, сразу после WM_GETMINMAXINFO :)
Хук WH_CBT имеет право запретить создание окна, имеет право модифицировать данные в CreateParams и т.д.
Поэтому он посылается до любого сообщения, посланного окну, так как от его результатов зависит дальнейшее создание окна.
← →
GuAV © (2005-02-10 17:23) [28]
> имеет право модифицировать данные в CreateParams и
> т.д.
Т.е. можно превратить WS_OVERLAPPEDWINDOW в WS_CHILDWINDOW ?
← →
guest_Dmitry (2005-02-10 17:28) [29]GuAV © (10.02.05 16:45) [23]
исправил GetForegroundWindow() на
TCWPStruct(Pointer(lParam)^).hwnd
В результате получаю полтора десятка разных значений на открытие одного приложения.
А нужно, например, при запуске "Блокнота" получить notepad.exe.
← →
Игорь Шевченко © (2005-02-10 17:33) [30]GuAV © (10.02.05 17:23) [28]
Нет, можно менять размер, позицию и Z-order.
← →
guest_Dmitry (2005-02-10 17:43) [31]Прошу прощения! Все получилось. Спасибо всем огромное. Торможу к вечеру.
← →
GuAV © (2005-02-10 18:12) [32]Игорь Шевченко © (10.02.05 17:33) [30]
> Нет, можно менять размер, позицию и Z-order.
спасибо.
Страницы: 1 вся ветка
Текущий архив: 2005.03.20;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.056 c