Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
4-1108021054
__max__
2005-02-10 10:37
2005.03.20
Проблемы с OpenFileMapping - Не удается найти указанный файл


14-1109160034
GRAND25
2005-02-23 15:00
2005.03.20
Футбол. Лига Чемпионов 2004/2005


6-1105444565
Grant
2005-01-11 14:56
2005.03.20
TClientSocket &amp; TServerSocket


1-1110124594
syscoder
2005-03-06 18:56
2005.03.20
Проблемы со StringGrid ом! С многострочностью не клеится...


14-1109714893
quickblack
2005-03-02 01:08
2005.03.20
Search toolbar