Solved

Need to hook left CTRL button only in my application.

Posted on 2004-09-06
14
182 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
  • 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
 

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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

759 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now