Solved

Need to hook left CTRL button only in my application.

Posted on 2004-09-06
14
186 Views
Last Modified: 2010-04-05
Hello Guys,

I need code to hook all click on right CTRL button...
But I need to hook clicks only for my application.

Thanks,
Dan
0
Comment
Question by:DanDaemon
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 6
14 Comments
 
LVL 11

Expert Comment

by:robert_marquardt
ID: 11991202
Now which one? Left or Right? :-)

Write a message handler for WM_KEYDOWN. There you get the full key information to check for left or right Ctrl key.
See the Win32 help for WM_KEYDOWN for details.
0
 

Author Comment

by:DanDaemon
ID: 11991215
Yes, sorry, LEFT!

Need good example on Delphi
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 11991858
mmm...maybe something like this?

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes,Forms,Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);

begin
  Application.OnMessage := AppMessage;

end;

procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
function HighOrderBitSet (theWord: Word): Boolean;
const
  HighOrderBit = 15;
type
  BitSet = set of 0..15;
begin
  HighOrderBitSet := (HighOrderBit in BitSet(theWord));
end;

begin
   if (Msg.Message = WM_KeyDown) then
   if (Msg.wParam = VK_Control) and
      (HighOrderBitSet(Word(GetKeyState(VK_LCONTROL)))) then
         begin
            showmessage('left ctrl pressed');
            Handled := True;
         end;
end;


end.
0
Technology Partners: 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!

 

Author Comment

by:DanDaemon
ID: 11991901
Hello Ferruccio68,

Thanks, your function works properly.
I will increase points because understand that I need to detect also when it will be unpressed...

I.e. I need to detect when left CTRL will be pressed one time and unpressed back.
I.e. I need to detect two messages from system...

Can you modify your code?

Thanks,
Dan
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 11991980
var
pressed: Boolean;
begin
   if (Msg.Message = WM_KeyDown) and
      (Msg.wParam = VK_Control) and
      (HighOrderBitSet(Word(GetKeyState(VK_LCONTROL)))) then
         begin
            showmessage('left ctrl pressed');
            Pressed := True;
            Handled := True;
         end
   else
   if (Msg.Message = WM_KeyUp) and
      Msg.wParam = VK_Control) and Pressed then
       begin
            showmessage('left ctrl unpressed');
            Pressed := False;
            Handled := True;
         end;
end;

Just from head (sorry, delphi not available at the moment)...
0
 

Author Comment

by:DanDaemon
ID: 11995018
Hello Ferruccio,

Your function does not work properly :(

Thanks,
Dan
0
 

Author Comment

by:DanDaemon
ID: 11995088
Hello Ferruccio,

I think I need to change first task, sorry but it is so.

I need a global hook for left ctrl button and this hook shold work so:

"user pressed left CTRL"______he still hold it____"user unpressed left CTRL"
__(software gets event)_______(no events)_______(software gets event)

I need to get two events:
1. Press left CTRL;
2. Unpress left CTRL (I should get this event only if CTRL was pressed and hooked by my software).

Sorry for changing :)

Thanks,
Dan.
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 11995194
ok, so do this:

put a TTimer on a form with interval = 100

then paste this code in unit1

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  pressed: Boolean;
  Down, Up: Integer;
implementation

{$R *.dfm}
function lCtrlDown: Boolean;
var
  State: TKeyboardState;
begin
  GetKeyboardState(State);
  Result := ((State[VK_lCONTROL] and 128) <> 0);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if lctrldown and not pressed then
   begin
      Pressed := True;
      Inc(Down);
   end else
      If not lctrldown and pressed then
         begin
            Pressed := False;
            inc(up);
         end;
caption := Format('Left Control Down: %d LeftControl Up: %d',[Down,up]);
end;

end.

F68 ;-)
0
 

Author Comment

by:DanDaemon
ID: 11998482
Hello Ferruccio68,

Any ideas about global hook?

Thanks, you code works perfect... But need to global hook.

Thanks,
Dan
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 12004786
mmm...
Do you mean a Keyboard Hook using a dll or just trapping keyboard messages in your application?

As i can see the Timer solution is pretty simple and less coded.

Also note that the Pressed situation is a little bit hard to be checked in a WM_ message as it's considered as a repeteable key down-up....
0
 

Author Comment

by:DanDaemon
ID: 12004852
No, when my software is running I can hide it to system tray, but in this case main form is not active but I still need to hook left control button.

Your first example does not allow to hook this event when main form is not active...

Thanks,
Dan
0
 
LVL 22

Accepted Solution

by:
Ferruccio Accalai earned 250 total points
ID: 12006100
mmm....in this case you need a dll

well, this is the more simple method:
first you have to create your dll hook like this

library HandlerLib;

uses
  Windows;
var
pressed: Boolean;

function lCtrlDown: Boolean;
var
  State: TKeyboardState;
begin
  GetKeyboardState(State);
  Result := ((State[VK_lCONTROL] and 128) <> 0);
end;

procedure Handler( nCode : Integer;
                  wParam : WPARAM;
                  lParam : LPARAM); stdcall;
begin
 if lctrldown and not pressed then
   begin
      Pressed := True;
      MessageBox(0,'Left Control Pressed','Info',0); //here you can instead  store the value where you prefere and then read it  from your app
   end else
      If not lctrldown and pressed then
         begin
            Pressed := False;
            MessageBox(0,'Left Control Released','Info',0);
         end;
 CallNextHookEx( 0, nCode, wParam, lParam );
end;

exports Handler;

begin
end.

Now from your app

unit Unit2;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);


  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  hook : HHOOK;
  dll : HMODULE;

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
begin
 dll:=LoadLibrary( 'HandlerLib' );
 hook:=SetWindowsHookEx( WH_KEYBOARD, GetProcAddress( dll, 'Handler' ), dll, 0 );
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnhookWindowsHookEx( hook );
  FreeLibrary( dll );
end;
end.

what you can do is to create a dat (or ini) file on create and reset up and down values
then from dll just increment when needed these values in dat

from your for simply get the refreshed values from dat

hope this helps

0
 

Author Comment

by:DanDaemon
ID: 12007723
Thanks man! Works perfect!
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 12007738
Glad to have helped you :)

F68 ;-)
0

Featured Post

Industry Leaders: 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!

Question has a verified solution.

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

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

738 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