[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Keyboard hook question

Posted on 2006-04-01
9
Medium Priority
?
522 Views
Last Modified: 2010-04-04
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
0
Comment
Question by:kapot
  • 4
  • 2
7 Comments
 
LVL 15

Accepted Solution

by:
mikelittlewood earned 136 total points
ID: 16352139
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
 
LVL 11

Assisted Solution

by:ZhaawZ
ZhaawZ earned 132 total points
ID: 16352243
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
 
LVL 11

Expert Comment

by:ZhaawZ
ID: 16352364
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 11

Expert Comment

by:ZhaawZ
ID: 16352386
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
 
LVL 4

Assisted Solution

by:BedouinDN
BedouinDN earned 132 total points
ID: 16352516
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
 
LVL 11

Expert Comment

by:ZhaawZ
ID: 16353205
it should be
function KeyboardHookProc (code, wParam, lParam : integer) : integer; stdcall;
instead of
function KeyboardHookProc   (Code: Integer;   WParam: Word;   LParam: LongInt) : LongInt;
0
 
LVL 4

Expert Comment

by:BedouinDN
ID: 16353574
It should indeed.. :-)
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses
Course of the Month17 days, 22 hours left to enroll

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question