Keyboard hook question

Hi,

I made a "global" keyboard hook using Delphi. It works fine.

But how can I clear the key that got hooked ?

My function below will be called continuously when I press the ESC key (hooked key).

function KeyboardHookProc (Code: Integer; WordParam: Word; LongParam: LongInt) : LongInt;
begin
  // ESC Key preseed ?
  if (WordParam = $1B) then
  begin
    if (MainForm.Tray.ApplicationVisible) then
    begin
       MainForm.Tray.HideApplication;
       // I need to clear the keyboard buffer here ! So this function will be called only ONCE. How ?
    end;
  end;
end;

I need a way to DISPOSE / REMOVE they "key" after it has been hooked.

Any idea ?

Thanks
kapotAsked:
Who is Participating?
 
mikelittlewoodCommented:
Im not sure how you are calling the original hook, maybe something like

JHook := SetWindowsHookEx(WH_JOURNALRECORD , @JHookFunc, hInstance, 0);

where JHook is a THandle

To unhook just call

UnhookWindowsHookEx(JHook);
JHook := 0;
0
 
ZhaawZSoftware DeveloperCommented:
what do you call "DISPOSE / REMOVE they key after it has been hooked"? And "clear the keyboard buffer"? And where's the result of the function?

About "calling function only once" - it's called on each keyboard message, i.e., wm_keydown and wm_keyup.
About that result of function - here's quote from MSDN:
[quote]
If code is less than zero, the hook procedure must return the value returned by CallNextHookEx.
If code is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.
[/quote]


And btw, what is "WordParam" and "LongParam"?
LRESULT CALLBACK KeyboardProc(
  int code,
  WPARAM wParam,
  LPARAM lParam
);
wParam and lParam actually are not wordparam and longparam. And these types both are 32bit integer types (however word is only 16bit). Here's how it looks in windows.pas:
type
  WPARAM = Longint;
  {$EXTERNALSYM WPARAM}
  LPARAM = Longint;
  {$EXTERNALSYM LPARAM}
  LRESULT = Longint;
  {$EXTERNALSYM LRESULT}
0
 
ZhaawZSoftware DeveloperCommented:
1 more thing - if I'm not wrong, you should add 'stdcall' there:
function KeyboardHookProc (code, wParam, lParam : integer) : integer; stdcall;

About "So this function will be called only ONCE" - I already said that if it is keyboard hook, it will be called on each wm_keydown and each wm_keyup message (and these are different messages). I suppose that you need to process only one type of actions, i.e., pressing OR releasing key. You may check if key is pressed or released by checking bit nr.31 of lParam which specifies the transition state (0 if the key is being pressed and 1 if it is being released). Just from head:
if (wParam = $1B) and (lParam and (1 shl 31) = 0) then {key is being pressed}
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
ZhaawZSoftware DeveloperCommented:
About those "word" and "longint" - some "wrong" resources say that wParam is 'short parameter' (16bit), lParam is 'long parameter' (32bit), but if you take a look at MSDN (Microsoft Developer Network, http://msdn.microsoft.com/), you'll see that they both are 32bit parameters:

3) INT = 32-bit signed integer
2) typedef unsigned int UINT_PTR;
1) typedef UINT_PTR WPARAM;

3) LONG = 32-bit signed integer
2) typedef long LONG_PTR;
1) typedef LONG_PTR LPARAM;
0
 
BedouinDNCommented:
Based on the answers from ZhaawZ:


function KeyboardHookProc
   (Code: Integer;
   WParam: Word;
   LParam: LongInt) : LongInt;
begin
  if Code > 0 then
  begin
    Result := CallNextHookEx(KBHook, Code, WParam,LParam);
  end
  else
  begin
    if (lParam and (1 shl 31) = 0)  then
    begin
      if wParam = $1B then
      begin
        if (MainForm.Tray.ApplicationVisible) then
        begin
          MainForm.Tray.HideApplication;
        end;  
      end;
    Result:= CallNextHookEx(KBHook, Code, WParam, LParam);
    end
    else
    begin
      Result:= CallNextHookEx(KBHook, Code, WParam, LParam);
    end;
  end;
end;

Cheers.
Colin..
0
 
ZhaawZSoftware DeveloperCommented:
it should be
function KeyboardHookProc (code, wParam, lParam : integer) : integer; stdcall;
instead of
function KeyboardHookProc   (Code: Integer;   WParam: Word;   LParam: LongInt) : LongInt;
0
 
BedouinDNCommented:
It should indeed.. :-)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.