Avatar billede borrisholt Novice
04. august 2008 - 15:25 Der er 13 kommentarer

globalt MESSAGE HOOK

Hej Eksperter

Jeg skal bruge et globalt message hook. Er der nogen der er leverings dyktige i sådan et ?

Jens Borrisholt
Avatar billede hrc Mester
05. august 2008 - 09:56 #1
Hej Jens. Jeg så dit forrige indlæg lidt sent og fik ikke fordybt mig ret meget i det før du lukkede det igen. Har kun meget begrænset erfaring med HOOK's som jo i princippet ikke er det helt vilde. Praksis er vist en anden sag.

Jeg har oversat din kode og får heller ikke noget svar fra hookeren.

Arbejder lidt med det - en blind høne finder jo også et korn fra tid til anden (skulle jeg sige hest?)
Avatar billede borrisholt Novice
05. august 2008 - 10:05 #2
Hej Henrik

Jeg har et STORT PROBLEM. Jeg har en magnet kortlæser og et keyboard ... koblet til en almindelig PC.

Min kortlæser sender til windows ved hjælp af keyborad koder ...

Hvis jeg bruger et keyboard hook, får jeg ikke at vide hvilket keyboard (det rigtige eller kort læseren) der har sendt taste trykket ...

Hvis jeg lytter efter beskeden WM_INPUTT kan jeg finde ud af hvilkey "keyboard" der har har sendt beskeden. Her er der så bare to problemer ...

Hvis jeg laver et lokalt message hook kan jeg ikke stoppe beskeden ...Hvis jeg lavet er globalt message hook modtager jeg slet ikke beskeden ...

Inden du farer i gang med google. Skal jeg lige sige denne post er blevet til efter 7 dages intensiv surfen efter en løsning ...

Der er MANGE der har det samme problem.

Jens B
Avatar billede hrc Mester
05. august 2008 - 10:43 #3
Jeg kan se at selve Hook'en fint bliver sat. Sættes et breakpoint på PostMessage linjen standser programmet fint. Den sender altså en message til hWndServer = Handle = mainformen. Den når bare aldrig frem.

Så langt er du nok også kommet. Bliver nødt til at kigge på det i aften hvis ellers jeg kan få adgang til MIN (det er altså min, Winnie) bærbare.
Avatar billede Slettet bruger
19. august 2008 - 11:03 #4
Jeg går ud fra at i er klar over at en system wide hook skal ligge i en dll?
Avatar billede borrisholt Novice
19. august 2008 - 12:21 #5
Jappe44>> Ja jeg troede jeg havde 100% styr på hooks. Linge indtil jeg ville hooke WM_input ...

Just for you informnation så kan du lave system wide  muse og keyboard hooks uden brug af dll filer, blot ved at lave et low-level hook ...

Men er du mand for en løsning af en globalt hook af WM_input så er spørgsmålet stadig åbent ..

løsning i C#, C++ eller Delphi

Jens B
Avatar billede Slettet bruger
19. august 2008 - 15:48 #6
Jeg kikker lige i mine skuffer når jeg kommer hjem, jeg har for mange år siden leget med hooks og har en del kode i delphi. Jeg har også en færdiglavet dll du også kan bruge i C, dog ikke koden.
Avatar billede Slettet bruger
19. august 2008 - 17:57 #7
hej så er jeg hjemme. Det lader til at jeg har sourcen og ligeud af landevejen. Kan dog, ikke huske meget.

{A DLL is necessary for a system hook.  The sample code below,
was found somewhere in dejanews.  The first file shows the code
for a simple hook that would be placed in the dll.  Next, a unit
is shown  that provides basic interface to import the dll  The
remaining comments are from the original author}

{This is the core of the system and task hook.  Some notes:           
                                                                       
  1)  You will definitely want to give the file a more descriptive name 
      to avoid possible collisions with other DLL names.               
  2)  Edit the MouseHookCallBack function to do what you need when a   
      mouse message is received.  If you are hooking something other   
      mouse messages, see the SetWindowsHookEx topic in the help for the
      proper WH_xxxx constant, and any notes about the particular type 
      of hook.                                                         
  3)  If an application that uses the DLL crashes while the hook is     
      installed, all manner of wierd things can happen, depending on the
      sort of thing you are doing in the callback.  The best suggestion 
      is to use a utility that displays loaded DLLs and forcibly unload 
      the DLL.  You could also write a simple app that checks to see if 
      the DLL is loaded, and if so, call FreeModule until it returns 0. 
  4)  If you make changes to the DLL but the changes don't seem to be   
      working, you may have the DLL already loaded in memory.  Remember,
      loading a DLL that is already in memory just increments a usage   
      count in Windows and uses the already loaded copy.               
  5)  Remember when you are hooking in at the *system* level, your     
      callback function is being called for everything in the OS.  Try 
      to keep the processing in the callback as tight and fast as you   
      possibly can.                                                     
  6)  Be careful of the uses clause.  If you include stuff like Dialogs,
      you will end up linking in a lot of the VCL, and have a DLL that 
      comes out compiled to around 250k.  You would probably be better 
      served using WM_USER messages to communicate with the application.
  7)  I have successfully hooked mouse messages without the use of a   
      DLL, but many of the hooks say they require the callback to be in 
      a DLL, so I am hesitant to include this method.  It certainly     
      makes the build/test cycle *much* easier, but since it is not     
      "sanctioned" by MS, I would stay away from it and discourage it.}

library HookDLL;

uses WinTypes, WinProcs, Messages;
var
  HookCount: integer;
  HookHandle: HHook;

{$IFDEF WIN32}
function MouseHookCallBack(Code: integer; Msg: WPARAM;
                          MouseHook: LPARAM): LRESULT; stdcall;
{$ELSE}
function MouseHookCallBack(Code: integer; Msg: word;
                          MouseHook: longint): longint; export;
{$ENDIF}
begin
  { If the value of Code is less than 0, we are not allowed to do anything
    except pass it on to the next hook procedure immediately. }
  if Code >= 0 then begin
    { This example does nothing except beep when the right mouse button is pressed. }
    if Msg = WM_RBUTTONDOWN then
      MessageBeep(1);

    { If you handled the situation, and don't want Windows to process the
      message, do *NOT* execute the next line.  Be very sure this is what
      want, though.  If you don't pass on stuff like WM_MOUSEMOVE, you   
      will NOT like the results you get.                                  }
    Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
  end else
    Result := CallNextHookEx(HookHandle, Code, Msg, MouseHook);
end;

{ Call InstallHook to set the hook. }
function InstallHook(SystemHook: boolean; TaskHandle: THandle) : boolean; export;
{This is really silly, but that's the way it goes.  The only way to get the 
module handle, *not* instance, is from the filename.  The Microsoft example
just hard-codes the DLL filename.  I think this is a little bit better. }
  function GetModuleHandleFromInstance: THandle;
  var
    s: array[0..512] of char;
  begin
    { Find the DLL filename from the instance value. }
    GetModuleFileName(hInstance, s, sizeof(s)-1);
    { Find the handle from the filename. }
    Result := GetModuleHandle(s);
  end;
begin
{ Technically, this procedure could do nothing but call SetWindowsHookEx(),
  but it is probably better to be sure about things, and not set the hook   
  more than once.  You definitely don't want your callback being called more
  than once per message, do you?                                            }
  Result := TRUE;
  if HookCount = 0 then begin
    if SystemHook then
      HookHandle := SetWindowsHookEx(WH_MOUSE, MouseHookCallBack,HInstance, 0)
    else
    { See the Microsoft KnowledgeBase, PSS ID Number: Q92659, for a discussion of
      the Windows bug that requires GetModuleHandle() to be used.                }
      HookHandle := SetWindowsHookEx(WH_MOUSE, MouseHookCallBack,
                                    GetModuleHandleFromInstance,TaskHandle);
    if HookHandle <> 0 then
      inc(HookCount)
    else
      Result := FALSE;
  end else
    inc(HookCount);
end;

{ Call RemoveHook to remove the system hook. }
function RemoveHook: boolean; export;
begin
  { See if our reference count is down to 0, and if so then unhook. }
  Result := FALSE;
  if HookCount < 1 then exit;
  Result := TRUE;
  dec(HookCount);
  if HookCount = 0 then
    Result := UnhookWindowsHookEx(HookHandle);
end;

{ Have we hooked into the system? }
function IsHookSet: boolean; export;
begin
  Result := (HookCount > 0) and (HookHandle <> 0);
end;

exports
  InstallHook,
  RemoveHook,
  IsHookSet,
  MouseHookCallBack;

{ Initialize DLL data. }
begin
  HookCount := 0;
  HookHandle := 0;
end.

(* Then have this importation unit: *)

{ This is a simple DLL import unit to give us access to the functions in
  the HOOKDLL.PAS file.  This is the unit your project will use.}
unit Hookunit;

interface

uses WinTypes;

function InstallSystemHook: boolean;
function InstallTaskHook: boolean;
function RemoveHook: boolean;
function IsHookSet: boolean;
{ Do not use InstallHook directly.  Use InstallSystemHook or InstallTaskHook. }
function InstallHook(SystemHook: boolean; TaskHandle: THandle): boolean;

implementation

uses WinProcs;

const
  HOOK_DLL = 'HOOKDLL.DLL';

function InstallHook(SystemHook: boolean;
                    TaskHandle: THandle): boolean; external HOOK_DLL;
function RemoveHook: boolean; external HOOK_DLL;
function IsHookSet: boolean; external HOOK_DLL;

function InstallSystemHook: boolean;
begin
  InstallHook(TRUE, 0);
end;

function InstallTaskHook: boolean;
begin
  InstallHook(FALSE,
              {$IFDEF WIN32}
                GetCurrentThreadID
              {$ELSE}
                GetCurrentTask
              {$ENDIF}
            );
end;

end.
Avatar billede Slettet bruger
19. august 2008 - 18:09 #8
Nu er det jo 10 år gammel kode, men mon ikke det kan lede dig på vejen.

Jeg har en del mere, men man kan jo ikke uploade filer her
Avatar billede borrisholt Novice
19. august 2008 - 19:19 #9
Jeg prøver ... Dog er jeg lidt skeptisk ... Problemet er at messagen VH_INPUT ikke sådan lige lader sig stoppe...

Du er velkommen til at spamme min postkasse Jens@Borrisholt.com

Jens Borrisholt
Avatar billede Slettet bruger
19. august 2008 - 19:53 #10
Du øhh! siger WH_KEYBOARD Hook dig noget?
Avatar billede Slettet bruger
19. august 2008 - 19:55 #11
Jeg er rimeligt begejstret for din tidsangivelse på din sidste post: 19/08-2008 19:19:19
He he. What are the chances?
Avatar billede Slettet bruger
19. august 2008 - 20:01 #12
Jeg tror at det tæteste man kan komme på det er 19/09-2019 19:19:19 Mens vi lever :-)
Avatar billede Slettet bruger
19. august 2008 - 20:12 #13
WH_JOURNALRECORD Hook... så får du hele baduljen. sjovt som vi sapiens kun kan kommunikere med en computer, via et keyboard og en mus
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester