title: Windows Global Keyboard Hook - Delphi
body: <p>I've created a GLOBAL keyboard hook DLL, using source code found on the internet. For the best part it works brilliant, except when it comes to browsers.</p>
  
  <p>It picks up every key in the browser except, it seems, when the browser gets focus, it looses the first key that is pressed. Tested this in IE and Firefox and it seems to be the same for both.</p>
  
  <p>For instance, if I open IE and start typing www. , I only get back ww. If the browser window stays in focus no further keys are lost. As soon as the browser looses focus and regains focus, the first key is again missing.</p>
  
  <p>Could it be because of using only WH_KEYDOWN instead of WH_KEYPRESS / WH_KEYUP ? Can anyone shed some light on this please?</p>
  
  <p>Thank you</p>
  
  <p>PS: The hook function itself is below: The DLL is sent a memo box and app handle to wich the DLL will send messages as well as a usermessage.</p>
  
  <pre><code>    function KeyHookFunc(Code, VirtualKey, KeyStroke: Integer): LRESULT; stdcall; 
  var
    KeyState1: TKeyBoardState; 
    AryChar: array[0..1] of Char; 
    Count: Integer; 
  begin 
    Result := 0; 
    if Code = HC_NOREMOVE then Exit;
  
    Result := CallNextHookEx(hKeyHook, Code, VirtualKey, KeyStroke); 
    {I moved the CallNextHookEx up here but if you want to block 
     or change any keys then move it back down} 
    if Code &lt; 0 then 
      Exit; 
    if Code = HC_ACTION then 
    begin 
      if ((KeyStroke and (1 shl 30)) &lt;&gt; 0) then 
        if not IsWindow(hMemo) then
        begin 
         {I moved the OpenFileMapping up here so it would not be opened 
          unless the app the DLL is attatched to gets some Key messages} 
          hMemFile  := OpenFileMapping(FILE_MAP_WRITE, False, 'NetParentMAP');//Global7v9k
          PHookRec1 := MapViewOfFile(hMemFile, FILE_MAP_WRITE, 0, 0, 0); 
          if PHookRec1 &lt;&gt; nil then 
          begin 
            hMemo := PHookRec1.MemoHnd; 
            hApp  := PHookRec1.AppHnd; 
          end; 
        end;
      if ((KeyStroke AND (1 shl 31))  = 0) then //if ((KeyStroke and (1 shl 30)) &lt;&gt; 0) then
      begin 
        GetKeyboardState(KeyState1); 
        Count := ToAscii(VirtualKey, KeyStroke, KeyState1, AryChar, 0); 
        if Count = 1 then
        begin
          SendMessage(hMemo, WM_CHAR, Ord(AryChar[0]), 0); 
          {I included 2 ways to get the Charaters, a Memo Hnadle and 
           a WM_USER+1678 message to the program} 
          PostMessage(hApp, WM_USER + 1678, Ord(AryChar[0]), 0);
        end;
      end; 
    end; 
  end; 
  </code></pre>