Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

system-wide hot keys -- how to detect global keyboard shortcuts programmatically?

QUESTION

How does one programmatically interrogate Win7 to get a list of all currently active global keyboard shortcuts?

Scenario

In many versions of Windows there is the so called "Windows Key", a.k.a. "flag", "start key", et cetera.

Microsoft has a support article "Keyboard shortcuts for Windows" that lists many of these under the section "Microsoft Natural Keyboard keys", as well as many others the do not involve using the "Windows Key" such as the global Ctrl+C, et cetera.

Other keyboard shortcuts can be discovered by accident. For example, Windows Key + Left arrow or Right arrow in Win7 moves the focused window around the display, and, with multiple monitors, from one display to the next.

Still other keyboard shortcuts can be found in the "options" settings, for example, Left-Ctrl+Alt+K is the default for "Show KeePass Window".

Additionally, there may be hardware specific keyboard shortcuts, for example, on my laptop, Fn+F8 toggles speaker muting.

Stolen Keyboard Shortcuts

When Snagit is running, I've configured PrtSc as my shortcut, but when Visual Studio(VS) is running, it steals PrtSc from Snagit.

Two time consuming methods of manually discovered keyboard shortcuts

(a) Global keyboard shortcuts can be discovered by having only the desktop and a couple of windows open and trying various key combinations.

(b) in VS, many VS keyboard shortcuts can be discovered by trying various combinations in the keyboard shortcuts window where, if a combination is already used, VS will notify one about the current usage for that combination.

Two reasons for wanting to discover all currently active global keyboard shortcuts

(a) to avoid annoying accidents like Windows Logo Key+L which locks the computer.

(b) to determine which keys are currently still available for assignment.

like image 542
gerryLowry Avatar asked Nov 03 '22 16:11

gerryLowry


1 Answers

This is a quite interesting but difficult issue. The Windows Operating System apparently does not offer a direct way to do this via maybe EnumerateHotKeys? However, when the RegisterHotKey function is called, there's a search using __FindHotKey. So it may be possible to hack into this function and find out available hot keys. See this C example. There's also a complete example in assembly languagedownloadable from here but this is likely not to work in Windows Vista +.

Another method is to scan all the shortcuts in the system. This can really take a long time if you want to scan all shortcuts on the system. However you can still grab most of them using the common shortcut directories such as:

%AllUsersProfile%\desktop %UserProfile%\Start Menu %AllUsersProfile%\Start Menu %appdata%\Microsoft\Internet Explorer\Quick Launch %appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\StartMenu %appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar

Here's a simple program I just wrote that scans all the shortcuts in the UserProfile directory.

using IWshRuntimeLibrary;//You can download this library from http://www.codeproject.com/KB/dotnet/ShellLink/ShellLink.zip


WshShell wsh = new WshShellClass();
var files = GetFiles(Environment.ExpandEnvironmentVariables("%userprofile%"), "*.lnk*");
foreach (string f in files)
{
    try
    {
        WshShortcut wa = wsh.CreateShortcut(f) as WshShortcut;
        if (wa.Hotkey != "")
        {
            MessageBox.Show("Shortcut Found! - " + wa.Hotkey, wa.TargetPath);
        }
    }
    catch
    {
        continue;
    }
}

Grap the GetFiles method from here if you want to use it. The major advantage of the method is just to avoid directory permission issues.

Good luck.

like image 153
Chibueze Opata Avatar answered Nov 09 '22 17:11

Chibueze Opata