none
Powershell Win Forms Hotkeys / Access Keys

    Question

  • Hi,

    I have a program made from powershell using winforms.

    I have buttons which open new programs, I'd like to create access keys for these buttons, however I cant

    seem to find a way to get the underlined letter or the 'access key' letter.

    I know in VB script you would just use:

    button1.text = '&test' and the letter 't' would be underlined.

    Is there anyway I can do this in Powershell which calls winforms?

    Thanks !

    Josh

    Monday, February 27, 2012 1:57 PM

Answers

  • Hi,

    I'm not sure, but I think the purpose of that code is to enable the setting for all programs. This is what I meant by "changing global state to manage local problem." A running program should not change a setting like that because it affects all other programs. It is a Windows standard GUI convention that shortcut keys don't show by default unless the user selects the option for themselves.

    In other words, in my opinion, I think you should follow the convention and let the users pick the option for themselves if they want to enable it.

    Bill

    • Marked as answer by Josh Budd Monday, February 27, 2012 4:56 PM
    • Unmarked as answer by Josh Budd Tuesday, February 28, 2012 8:57 AM
    • Marked as answer by Bill_StewartModerator Wednesday, May 16, 2012 9:05 PM
    Monday, February 27, 2012 4:47 PM

All replies

  • Windows Forms is Windows Forms.  Use the & in front of the letter you want to assign as an accelerator.  Press the Alt key to see the letter underlined.

    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)


    • Edited by Bigteddy Monday, February 27, 2012 2:11 PM
    Monday, February 27, 2012 2:08 PM
  • Ah !

    Didn't even try the ALT key so never noticed it was working !

    Is there anyway to keep the underlines there permanently without pressing the ALT key?

    Cheers,

    Josh

    Monday, February 27, 2012 2:15 PM
  • I quote:

    "The only documented way to always display control accelerators is by sending
    a WM_CHANGEUISTATE to the parent form, using the SendMessage API method.
    However, things are quite intricate because you must send this message after the
    form has initialized but before the form becomes visible. You must do this for
    each form in your application."


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Monday, February 27, 2012 2:24 PM
  • Note:  This is not a Windows Forms issue, it is system-wide that accelerator keys are not shown by default in O/S's after/including  XP/2003.

    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)



    • Edited by Bigteddy Monday, February 27, 2012 3:34 PM
    Monday, February 27, 2012 2:26 PM
  • I've done a bit of research via google :),

    and it looks like i've gone right into a can of worms !

    Could you give me the code I would need to change the window state?

    Thanks allot !

    Josh

    Monday, February 27, 2012 3:07 PM
  • I have no idea!  You're right about a can of worms.  Try any Windows application (Even your Powershell ISE), and you will see this behaviour is system-wide.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Monday, February 27, 2012 3:09 PM
  • Is there anyway I could use

    $wshell = new-object -com wscript.shell
    $wshell.sendkeys("ALT")

    After I've shown the dialog? -

    $form1.Showdialog()

    Monday, February 27, 2012 3:17 PM
  • Hi,

    As bigteddy said, displaying the underlined characters is a user-wide preference. In Windows 7, you can enable this setting in Control Panel->Ease of Access Center->Make the keyboard easier to use->Underline keyboard shortcuts and access keys. Configuring this setting is not a scripting issue.

    Bill

    Monday, February 27, 2012 3:56 PM
  • Cool tip, Bill (I didn't know that).  When it comes to Windows Forms, it becomes a grey area as to whether it's scripting or application development.

     But, it seems that we do mainly "Administrative scripting" here, and Windows Forms (whether used from Powershell or Visual Studio) should be posted to the Windows Forms forum, for best advice.


    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Monday, February 27, 2012 4:03 PM
  • Hi bigteddy,

    Agree there is a gray area, but the issue of whether to display the underlined hotkeys really has nothing to do with scripting. It's a UI user preference issue. In general, I would caution against using global state to manage a local problem.

    Bill

    Monday, February 27, 2012 4:07 PM
  • Thanks for the clarification Bill,

    Unfortunately I cant change the settings in the control panel

    (the program will be used in a college, on all the college computers including students)

    So there's no 'easy' solution to setting one form to display these keys?

    Thanks for all the help !

    Josh

    P.S,

    I've just found this little snippet in C# (although I havnt the slightest on how to convert this to powershell)

    [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()); }

    Could it be used?

    • Edited by Josh Budd Monday, February 27, 2012 4:34 PM Update
    Monday, February 27, 2012 4:31 PM
  • Hi,

    I'm not sure, but I think the purpose of that code is to enable the setting for all programs. This is what I meant by "changing global state to manage local problem." A running program should not change a setting like that because it affects all other programs. It is a Windows standard GUI convention that shortcut keys don't show by default unless the user selects the option for themselves.

    In other words, in my opinion, I think you should follow the convention and let the users pick the option for themselves if they want to enable it.

    Bill

    • Marked as answer by Josh Budd Monday, February 27, 2012 4:56 PM
    • Unmarked as answer by Josh Budd Tuesday, February 28, 2012 8:57 AM
    • Marked as answer by Bill_StewartModerator Wednesday, May 16, 2012 9:05 PM
    Monday, February 27, 2012 4:47 PM
  • Ok,

    Thanks for all the help to both of you :)

    Josh

    Monday, February 27, 2012 4:55 PM
  • $code=@'
         public static class SPI{
         [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;
         public static void SetKeyboard(){
             // always show accelerator underlines
             SystemParametersInfo(SPI_SETKEYBOARDCUES, 0, 1, SPIF_SENDWININICHANGE);
         }
    }
    '@
    add-type -TypeDefinition $code
    [spi2]::SetKeyboard()


    ¯\_(ツ)_/¯

    Monday, February 27, 2012 5:48 PM
  • That works !

    I havn't a clue how ! But it does !

    By the way, I had to change the last line from SPI2 to SPI.

    Thank you very much !

    Thanks to all 3 of you guys ^^

    Josh

    Tuesday, February 28, 2012 8:57 AM
  • That works !

    I havn't a clue how ! But it does !

    By the way, I had to change the last line from SPI2 to SPI.

    Thank you very much !

    Thanks to all 3 of you guys ^^

    Josh

    Note that you are changing this for all applications not just the current one.


    ¯\_(ツ)_/¯

    Tuesday, February 28, 2012 9:07 AM
  • Hi,

    This is why I don't recommend this course of action. It is not polite for one program to change global state such that it affects all other programs. This is what is meant by changing global state to manage a local problem. Your program is not a good citizen if it does this.

    Bill

    Tuesday, February 28, 2012 3:05 PM
  • Hi,

    This is why I don't recommend this course of action. It is not polite for one program to change global state such that it affects all other programs. This is what is meant by changing global state to manage a local problem. Your program is not a good citizen if it does this.

    Bill


    I quite agree.  Why fight the system?  What's so special about this program that it needs it's accelerator keys visible at all times.  A simple instruction to the user should be enough:  "If you want to use shortcuts, press Alt".

    Grant Ward, a.k.a. Bigteddy

    What's new in Powershell 3.0 (Technet Wiki)

    Tuesday, February 28, 2012 3:14 PM
  • That's a fair point.

    I think I'll let users know about holding alt.

    And set a option to keep them on permantly, whilst letting them know it affects all programs.

    Thanks again,

    Josh

    Tuesday, February 28, 2012 10:02 PM