Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > не работает глобальный hook сообщений


Автор: dbgrid 11.6.2009, 10:44
Здравствуйте Уважаемые..
Третий день дрючусь с хуками))
ничего не получается....
есть DLL для установки глобального хука и записи в файл хэндлов окон которые шлют сообщения (для примера!!!)

Код

library dllhooook;

uses
  Windows, SysUtils,
  Messages, classes, unit1;

var
 SysHook : HHook = 0;
 Wnd : Hwnd = 0;
 f:TextFile;
 mmsg:MSG;

function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
begin
    if code<0 then begin
       SysMsgProc:=CallNextHookEx(SysHook,code,wParam,lparam);
       Exit;
    end;

   Wnd := TMsg(Pointer(lParam)^).hwnd;

        AssignFile(f,'log.txt');
        if not FileExists('log.txt') then Rewrite(f) else Reset(f);
         Append(f);
         Writeln(f,inttohex(Wnd,0));
         CloseFile(f);
  end;
end;

procedure RunStopHook(State : Boolean) export; stdcall;
begin
 if State then SysHook:=SetWindowsHookEx(WH_GETMESSAGE,@SysMsgProc,HInstance,0)
 else
  begin
   UnhookWindowsHookEx(SysHook);
   SysHook := 0;
end;

exports RunStopHook index 1;

begin
end.
 
теоретически всё просто...и должно работать....
но в файл записываются только хэндлы программы которая включает этот хук....и всё, все остальные окна игнорируются...
что здесь не так??

Кстати...переодически при использовании это DLL слетает explorer.exe

Автор: Romikgy 11.6.2009, 12:28
а где вызов этого же 
Цитата(dbgrid @  11.6.2009,  09:44 Найти цитируемый пост)
CallNextHookEx(SysHook,code,wParam,lparam);

после того как ты залогировал событие ? или у тя по логике должны все сообщения убиватся ?

Автор: kami 11.6.2009, 12:34
Цитата(dbgrid @  11.6.2009,  10:44 Найти цитируемый пост)
Код

AssignFile(f,'log.txt');

А в папках программ файл log.txt не пробовали поискать? smile 
Вы ведь открываете файл в текущей директории для вызвавшего хук процесса.

Добавлено через 3 минуты и 47 секунд
Цитата(dbgrid @  11.6.2009,  10:44 Найти цитируемый пост)
Кстати...переодически при использовании это DLL слетает explorer.exe

Потому что не выполнено требование, озвученное Romikgy.

Автор: dbgrid 11.6.2009, 13:13
Цитата(Romikgy @  11.6.2009,  12:28 Найти цитируемый пост)
после того как ты залогировал событие ? или у тя по логике должны все сообщения убиватся ? 


Спасибо, согласен, explorer теперь не слетает


Цитата(kami @  11.6.2009,  12:34 Найти цитируемый пост)
А в папках программ файл log.txt не пробовали поискать? smile 
Вы ведь открываете файл в текущей директории для вызвавшего хук процесса.


)))))Спасибо....это многое объясняет.....например появление log.txt на рабочес столе)))))
Исправил на C:\log.txt

НО!!!
Всё равно, запускаю прогу, беру окно БЛОКНОТЫ, перемещаю его, закрываю прогу...
захожу в log но там хэндла БЛОКНОТА нету...
Сравниваю с результатами spy++

Автор: Romikgy 11.6.2009, 13:33
а после твоей длл пробовал блокнот запускать ?

Автор: dbgrid 11.6.2009, 13:41
Цитата(Romikgy @  11.6.2009,  13:33 Найти цитируемый пост)
а после твоей длл пробовал блокнот запускать ? 

пробовал
На самом деле ХУК действительно ГЛОБАЛЬНЫЙ....записывает в log кучу окон
но блокнота там нет
я использовал функцию
Код

Writeln(f,GetModuleName(GetClassLong(Wnd,GCL_HMODULE)));

для того чтобы по хэндлу сразу записывалось имя процесса.....
но блокнота там нет....((((

вообще изначальная задумка была такая
например в блокноте открываешь файл, или нажимаешь какой нибудь пункт в меню....генерируется сообщение...моя dll эти сообщения фильтрует....и регестрирует в ЛОге

Автор: Romikgy 11.6.2009, 14:02
дай полный текст этой длл  и проекта запуска ее буду бета тестером smile

Автор: dbgrid 11.6.2009, 14:08
DLL
Код

library dllhooook;

uses
  Windows, SysUtils,
  Messages, classes, unit1;

var
 SysHook : HHook = 0;
 Wnd : Hwnd = 0;
 f:TextFile;
 mmsg:MSG;

function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
begin
    if code<0 then begin
       SysMsgProc:=CallNextHookEx(SysHook,code,wParam,lparam);
       Exit;
    end;

   Wnd := TMsg(Pointer(lParam)^).hwnd;

        AssignFile(f,'C:\log.txt');
        if not FileExists('C:\log.txt') then Rewrite(f) else Reset(f);
           Append(f);
//         Writeln(f,inttohex(Wnd,0));
           Writeln(f,GetModuleName(GetClassLong(Wnd,GCL_HMODULE)));
           CloseFile(f);
       SysMsgProc:=CallNextHookEx(SysHook,code,wParam,lparam);
end;

procedure RunStopHook(State : Boolean) export; stdcall;
begin
 if State then SysHook:=SetWindowsHookEx(WH_GETMESSAGE,@SysMsgProc,HInstance,0)
 else
  begin
   UnhookWindowsHookEx(SysHook);
   SysHook := 0;
  end;
end;

exports RunStopHook index 1;

begin
end.


сама форма
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
procedure RunStopHook(State : Boolean) stdcall; external 'dllhooook.dll' index 1;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
RunStopHook(true);
caption:='ВКЛ';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
RunStopHook(false);
caption:='ВЫКЛ';
end;

end.


Добавлено через 4 минуты и 6 секунд
Я запустил хук
после чего запустил блокнот.....пощёлкал по менюшкам.....закрыл блокнот

а в ЛОГе сохранилось

Код

C:\Documents and Settings\XXX\Рабочий стол\hook\Project1.exe
C:\Documents and Settings\XXX\Рабочий стол\hook\Project1.exe
C:\Documents and Settings\XXX\Рабочий стол\hook\Project1.exe
C:\Documents and Settings\XXX\Рабочий стол\hook\Project1.exe
C:\WINDOWS\Explorer.EXE
D:\MozilaFirefox\firefox.exe
D:\MozilaFirefox\firefox.exe


Автор: Romikgy 11.6.2009, 14:47
система не грузит эту длл  ко всем процессам , странно и не понятно , для меня ((

Автор: dbgrid 11.6.2009, 14:53
Цитата(Romikgy @  11.6.2009,  14:47 Найти цитируемый пост)
система не грузит эту длл  ко всем процессам , странно и не понятно , для меня (( 

))))ну хоть не мне одному непонятно))))))

Автор: dbgrid 23.6.2009, 08:55
разобрался сам...
кому интересно..
функция перехвата будет выглядеть так
Код

function SysMsgProc(code : integer; wParam : word; lParam : longint) : longint; stdcall;
var
mes,lpam,wpam,logf:string;
begin
    if code<0 then begin
       SysMsgProc:=CallNextHookEx(SysHook,code,wParam,lparam);
       Exit;
    end;

   Wnd := TMsg(Pointer(lParam)^).hwnd;
   mes:=IntToHex(TMsg(Pointer(lParam)^).message,8);
   lpam:=IntToHex(TMsg(Pointer(lParam)^).lParam,8);
   wpam:=IntToHex(TMsg(Pointer(lParam)^).wParam,8);

   if not(GetModuleName(GetClassLong(Wnd,GCL_HMODULE))='C:\Program Files\The KMPlayer\KMPlayer.exe') then exit; //перехват событий только из программы KMPlayer или ВЫХОД

        AssignFile(f,'log.txt');
        if not FileExists('log.txt') then Rewrite(f) else Reset(f);  //LOG файл всётаки приходится создавать в директории проги за которой следишь
           Append(f);
           Writeln(f,mes+' ---> '+lpam+' - '+wpam); //список событий в чистом виде))))
           CloseFile(f);

       SysMsgProc:=CallNextHookEx(SysHook,code,wParam,lparam);
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)