Is there a way to force mnemonic key to show out without pressing ALT?
Asked Answered
C

1

5

I'm working on a WinForms app and I'd like to use Mnemonics key. It appears that due to a Windows parameter, you can choose to show them while using the application only after pressing ALT (this option is like it as default). I got aware of this option thanks to this question (btw related but not duplicate).

I changed this option, and the Mnemonics underline shows properly at the start. But I'd like to avoid users have to either turn this option on or have to press ALT in order to see the underlined keys.

So my question is : Is there anyway in-app to force the underline of an Mnemonic key without changing settings or pressing ALT ?

Case answered 15/2, 2019 at 8:42 Comment(11)
Generally, the answer to questions of the form "I'd like to do things in a manner contrary to what's explicitly set in the options, can I" is either "no" or "you shouldn't", whether or not you like what Microsoft's doing. The decision to underline accelerators is made based on various window messages. In theory, controls can be coaxed to do so even absent the appropriate user input; in practice this would be involved and error-prone. Unless you want to go full custom controls, this is probably a lost battle.Patric
Users "know", if they're aware of these keys, that they press the ALT key to see them or change their preferences. Why are you seeking to subvert user expectations?Phraseograph
@JeroenMostert It was a bit what I though but I wanted to check if there is a way. I guess I'll just emulate a ALT press at the creation of the form to show it up. Thanks to you to confirm that. Damien, because some know that, but some who don't works often with this kind of application and don't really have great knowledge of computers don't.Case
If you try stuff like that, be prepared for more confused users, and possibly stuff breaking. For example, if the user now presses Alt, changes their mind and doesn't press an accelerator key (or one that doesn't actually exist), the underlines are still gone, and will stay gone until Alt is pressed again. That's assuming accelerators continue to work in the first place, and aren't broken by your generating of an Alt keypress! If you need consistency of this inside your workplace, the proper solution would be Group Policy, rather than trying to solve it on an application level.Patric
Also, obviously (?) and for completeness -- the presence or absence of keyboard shortcuts should never be crucial to your application. If they need to be displayed because users would have a hard or impossible time accessing something otherwise, you're definitely doing it wrong.Patric
@JeroenMostert I don't know if it's my WinForms version, but one you pressed ALT underline stay, even if press ALT again. So for that point it would not be a problem. And for the fact I want them to show up at the beginning, it's because my chief like shortcut and I anticipate that she'd like to use them as soon as possible, and I guess that if she have to always press ALT on each forms she's gonna run out of patience. To end up not make an extended discussion in comment, I'll just go like that and ask her if it's good, as she's nearly the only one using Mnemonics keys.Case
I've never tried any key emulation tricks, hence why I said "possibly". The behavior for actual keypresses, on my Windows, is that the underlines appear only while in "Alt mode". But that involves pressing the key and letting go; if you simulate only a downward keypress the effects can be different. Even so, be prepared for potential problems and test thoroughly with things like opening submenus and dialog windows. If displaying underlines is absolutely crucial to your application for some scenarios, a custom approach is better -- underlines in labels don't toggle, menus are not mandatory.Patric
(Actually, now that I say that, underlines in labels could still toggle, if those are subject to the accelerator rules. Let's make it more general and say you can still draw text with underlines while ignoring the setting. :-))Patric
Why not sending the alt key? Have you tried protected override void OnShown(EventArgs e) { base.OnShown(e); SendKeys.Send("%"); };Hath
@RezaAghaei I'm actually trying to emulate an ALT input, but it's harder than i though, SendKeys don't work here so I'm trying to use keybd_event from user32.dll, but send ALT alone bring up some problems which I have to solve before use it properlyCase
SendKeys doesn't work?! Did you try what I shared?Hath
H
7

For MenuStrip, you need to create a custom renderer to always show mnemonics regardless of pressing or not pressing Alt key. To do so derive from ToolStripProfessionalRenderer and override its OnRenderItemText, removing NoPrefix and HidePrefix flags from e.TextFormat. Then register the renderer for ToolStripManager.Renderer.

For other controls to show mnemonics, you can override WndProc method of the form and handle WM_UPDATEUISTATE message and set WParam to combination of UISF_HIDEACCEL as high order word and UIS_CLEAR as low order words. This way all the controls will show mnemonic underline.

Example

Just copy and paste the following code in your form and run your application. The form will show underlines for all mnemonics without needing to press Alt:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
const int WM_UPDATEUISTATE = 0x0128;
const int UISF_HIDEACCEL = 0x2;
const int UIS_CLEAR = 0x2;
protected override void OnShown(EventArgs e)
{
    base.OnShown(e);
    ToolStripManager.Renderer = new MyRenderer();
}
protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_UPDATEUISTATE)
        m.WParam = (IntPtr)((UISF_HIDEACCEL & 0x0000FFFF) | (UIS_CLEAR << 16));
    base.WndProc(ref m);
}
public class MyRenderer : ToolStripProfessionalRenderer
{
    protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
    {
        e.TextFormat &= ~TextFormatFlags.NoPrefix;
        e.TextFormat &= ~TextFormatFlags.HidePrefix;
        base.OnRenderItemText(e);
    }
}

enter image description here

Hath answered 15/2, 2019 at 14:44 Comment(1)
Really nice answer, works perfectly as I need. Thanks a lot.Case

© 2022 - 2024 — McMap. All rights reserved.