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
Solved

Disable the numlock key using Delphi 7

Posted on 2008-10-27
7
1,021 Views
Last Modified: 2013-11-23
I want to be able to use Delphi 7 to disable the numlock key.  This needs to work in XP and preferably Vista also.

Actually what I specifically want to do is to make sure the numlock key can't be turned off if that makes more sense?  setting it explicitly to on first, before turning off the key would therefore work well.
0
Comment
Question by:AuthorwareXtras
  • 3
  • 3
7 Comments
 
LVL 18

Expert Comment

by:Johnjces
ID: 22818674
You could try, to "click" the numlock key;

keybd_event(VK_NUMLOCK, 0, 0, 0);

Actually the above will "hold down" the key.

To click try;

keybd_event(VK_NUMLOCK, 0, KEYEVENTF_KEYDOWN, 0);

To reverse it, try;

keybd_event(VK_NUMLOCK, 0, KEYEVENTF_KEYUP, 0);

John
0
 
LVL 1

Expert Comment

by:leei
ID: 22819122
This should be everything you need:
1. Method to set NumLock state
2. Keyboard hook to allow watching for attempts to change the NumLock state and reset it if needed.
-Lee

var
  KbdHook : HHook;
 
//call initially to set numlock on
procedure SetNumLock(Lock : Boolean);
var
  KeyState : TKeyboardState;
begin
  GetKeyboardState(KeyState);
  if Lock and (KeyState[VK_NUMLOCK] = 0) then begin
    //simulate key presses
    Keybd_Event(VK_NUMLOCK, 1, KEYEVENTF_EXTENDEDKEY, 0);
    Keybd_Event(VK_NUMLOCK, 1, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
  end else if not Lock and (KeyState[VK_NUMLOCK] = 1) then begin
    //simulate key presses
    Keybd_Event(VK_NUMLOCK, 0, KEYEVENTF_EXTENDEDKEY, 0);
    Keybd_Event(VK_NUMLOCK, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
  end;
end;
 
function KeyboardHookProc(nCode : Integer; wParam : Word; lParam : LongInt) : LongInt;
   stdcall;
begin
  if nCode < 0 then begin
    //If code is less than zero, the hook procedure must pass the message to
    //the CallNextHookEx function without further processing and should
    //return the value returned by CallNextHookEx
    Result := CallNextHookEx(KbdHook, nCode, wParam, lParam);
    Exit;
  end;
  if (wParam = VK_NUMLOCK) then begin
    Result := 0; //stop further processing
    SetNumLock(True); //re-set numlock
  end else
    Result := CallNextHookEx(KbdHook, nCode, wParam, lParam);
end;
 
//do this either in form create/destroy or somewhere similar.
 
procedure TForm1.FormCreate(Sender : TObject);
begin
  //Set the keyboard hook so we can intercept keyboard input
  KbdHook := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, HInstance,
     GetCurrentThreadId());
end;
 
procedure TForm1.FormDestroy(Sender : TObject);
begin
  //unhook
  UnHookWindowsHookEx(KbdHook);
end;

Open in new window

0
 

Author Comment

by:AuthorwareXtras
ID: 22820043
Does this not have to be done from a DLL so the hook is system wide?
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 1

Accepted Solution

by:
leei earned 500 total points
ID: 22820326
The example applies to either an application or DLL. You will want to replace the call to GetCurrentThreadId() with 0 if establishing the hook form a DLL, though.
Of course, with a DLL you need to establish and release the windows keyboard hook in some place other than the sample form methods I provided.
0
 

Author Comment

by:AuthorwareXtras
ID: 22822267
In a Delphi app it works fine.

In a DLL,  when I press the numlock key, the numlock indicator flashes on and off repeatedly and the whole machine slows down?
0
 

Author Comment

by:AuthorwareXtras
ID: 22823266
When I change this line:

Result := 0; //stop further processing
to a non zero value (e.g.  Result := 1;)

Then it functions.
0
 
LVL 1

Expert Comment

by:leei
ID: 22825858
My mistake. You are correct - a non zero result should be returned from the keyboard hook to stop further processing.
0

Featured Post

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Best free Visio Editor? 2 195
Print Graphic and Text to Epson TM-T88v 12 380
PHP preg_replace code convert to Delphi 14 66
Tidtcpserver listening on multiports? 1 35
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…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.

860 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