Solved

Need to hook left CTRL button only in my application.

Posted on 2004-09-06
14
185 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
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

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…
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 video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

820 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