Solved

Need to hook left CTRL button only in my application.

Posted on 2004-09-06
14
184 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
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 

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

ScreenConnect 6.0 Free Trial

Discover new time-saving features in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

803 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