KeyBd_Event broken for multiple control keys in 64 bit systems

I have a longstanding application which sends keystrokes using KeyBd_Event in the User32 dll.

While it mostly works, where we send combinations like {Ctrl+Shift+Home} only the first control key (in the order Shift Ctrl Alt) is now recognised for 64 bit windows.

The code puts the required control keys down, then sends the characters required, then puts the control keys up again, all using KeyBd_Event calls.

This works fine in 32 bit XP & W7 but not in 64 bit W7.
I have not yet tested 32 bit W8 or 64 bit XP and W8).

If you are aware of a solution to this issue I would be grateful.
It looks as if when one control key is depressed other control keys are raised.

I am now looking at switching to SendInput for 64bit systems, but would obviously prefer to stay with code that has been working well for a long time.

It happens that I am coding in Delphi-7 but since I end up calling the API directly I don't think this is particularly relevant to the problem, though a solution in Delphi would be helpful, though any other language would be OK also.
Who is Participating?
Joe Winograd - EE Fellow & MVEConnect With a Mentor DeveloperCommented:
If you're willing to consider a different product to send keystrokes, I've been using AutoHotkey (excellent and free!) with complete success in W7/64-bit (and W8/64-bit). There have been many forks of the original language and recently a new community was established to move the language forward. The latest release at the new community has a Windows installer, an offline help file, and a compiler that turns the AHK source code (plain text) into a stand-alone/no-install executable (an EXE file).

There is excellent documentation:

...including an alphabetical command and function index:

...a good tutorial:

...and an active user forum:

I started out with AutoHotkey when my old keyboard macro program wouldn't work in W7/64-bit, but now I use it for more than just sending keystrokes, as it is a complete, robust programming/scripting language. If you'd like to see it used in a full program, here's an EE article that includes a description of all the AutoHotkey code snippets:

Give AutoHotkey a spin — I think you'll like it. Regards, Joe
GHG-RCHAuthor Commented:
Since posting this question we have found that the problem is associated with NumLock.
If NumLock is active then this problem occurs.
I will modify the code to determine the NumLock state, set it off, do what is needed, then set it back on again.

I will also look at AutoHotKey, though we try to minimise the use of non source third party products because it can become quite complex keeping things up to date, support is sometimes unreliable and the long term existence of the product is not guaranteed.
GHG-RCHAuthor Commented:
Marked as good as it suggested a way round without actually addressing the problem.
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.

Joe Winograd - EE Fellow & MVEDeveloperCommented:
Interesting catch on the NumLock issue! Thanks for posting that. Regards, Joe
Dale FyeCommented:

I'm looking to implement something similar but simply need to send the shift key to the keyboard prior to opening a database using automation.

Care to share:

How do you declare the user32.dll?

How do you then send the shift key to the keyboard?
GHG-RCHAuthor Commented:
I use it through the Delphi Windows unit.
I call the keybd_event function and send approprirate KeyDown and KeyUp calls.
This works fine normally, however if NumLock is on single control key calls work OK (e.g. Ctrl-C) but multiple control key events do not and the system acts as if only one has been pressed (e.g. Ctrl-Shift-Home is treated ad Ctrl-Home or Shift-Home).
I have worked round this problem by detecting NumLock, taking it off, carrying out the required operation, then putting it back to the previous state. Everything now works fine.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.