Tuesday, May 18, 2010

Force C# to always show keyboard shortcuts (access keys) in Windows Forms

Windows has a setting that will hide the underscore on window accelerator keys (shortcut keys) until the user presses the <ALT> key. Personally, I find this annoying. Windows 7 has it set like this by default. You can turn this on or off Windows-wide through the accessibility options. Press <Windows key><U> to open accessibility options. Then click "Make the keyboard easier to use". Then check the box that says "Underline keyboard shortcuts and access keys" under the heading "Make it easier to use keyboard shortcuts". Here's what baffles me: if everything on the path to this setting refers to making it "easier", why isn't it "on" by default?

In any case, for one particular program, I want to force the underscores to show all of the time, regardless of the user's setting. Now some may say that the choice should fall on the user and their preferred settings inside Windows, but in this particular case, it's an internal application that only a few of us will use, and I'm going to do it the way I want. :)

Windows API to the rescue... We can make a simple call to Windows unmanaged code to accomplish this task. Here's a sample of the code.

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int SystemParametersInfo(int uAction, int uParam, int lpvParam, int fuWinIni);

private const int SPI_SETKEYBOARDCUES = 4107; //100B
private const int SPIF_SENDWININICHANGE = 2;

[STAThread]
static void Main()
{
    // always show accelerator underlines
    SystemParametersInfo(SPI_SETKEYBOARDCUES, 0, 1, SPIF_SENDWININICHANGE);

    Application.Run(new MainForm());
}

6 comments:

  1. Hi Friend!! Just want to thank you for the code snippet!! You saved my ass!! Thanks!!

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. This is great! Thank you for the info.

    ReplyDelete
  4. Great Help! Thanks.

    Would this also reset the settings once the Application is closed? (Since these are Windows settings I do not wish to leave the state changed after my App execution is complete)

    OR is there any API to Reset or just by providing some different constants to SystemParametersInfo()?

    ReplyDelete
  5. If you just use the code, then it only is set for that application. There's no need to do the manual steps in Windows, because doing that makes the setting for all applications.

    ReplyDelete
  6. This is great! Thank you a lot.

    But it change system setting for all application. Is it any way to revert back the changes when application is closed ?

    ReplyDelete