【问题标题】:Is there a way to force mnemonic key to show out without pressing ALT?有没有办法在不按 ALT 的情况下强制显示助记键?
【发布时间】:2019-02-15 08:42:18
【问题描述】:

我正在开发一个 WinForms 应用程序,我想使用 Mnemonics 键。似乎由于 Windows 参数,您可以选择在使用应用程序时仅在按下 ALT 后显示它们(此选项与默认设置类似)。感谢question(顺便说一句,相关但不重复),我知道了这个选项。

我更改了此选项,助记符下划线在开始时正确显示。但我想避免用户必须打开此选项或必须按 ALT 才能看到带下划线的键。

所以我的问题是:应用内是否有强制助记键下划线而不更改设置或按 ALT 的情况?

【问题讨论】:

  • 一般来说,对于“我想以与选项中明确设置的方式相反的方式做事,我可以”形式的问题的答案是“否”或“你应该” t",不管你是否喜欢微软的做法。下划线加速器的决定是基于various window messages。理论上,即使没有适当的用户输入,也可以诱使控件这样做;在实践中,这将涉及并且容易出错。除非您想完全自定义控件,否则这可能是一场失败的战斗。
  • 用户“知道”,如果他们知道这些键,他们会按下 ALT 键来查看它们或更改他们的偏好。你为什么要颠覆用户的期望?
  • @JeroenMostert 这有点像我,但我想检查是否有办法。我想我会在创建表单时模拟一个 ALT 键来显示它。谢谢你确认。 Damien,因为有些人知道这一点,但有些人不经常使用这种应用程序并且对计算机并不了解。
  • 如果您尝试这样的事情,请为更多困惑的用户做好准备,并且可能会破坏。例如,如果用户现在按下 Alt,改变主意并且没有按下加速键(或实际上不存在的快捷键),那么下划线仍然消失,并且会一直消失,直到再次按下 Alt。这是假设加速器首先继续工作,并且不会被您生成的 Alt 按键破坏!如果您需要在工作场所内保持一致性,正确的解决方案是组策略,而不是尝试在应用程序级别解决它。
  • 另外,显然 (?) 和完整性 - 键盘快捷键的存在与否对您的应用程序永远不应该是至关重要的。如果因为用户很难或不可能访问某些内容而需要显示它们,那么您肯定做错了。

标签: c# .net winforms mnemonics


【解决方案1】:

对于MenuStrip,您需要创建一个自定义渲染器以始终显示助记符,无论是否按下 Alt 键。为此,从ToolStripProfessionalRenderer 派生并覆盖其OnRenderItemText,从e.TextFormat 中删除NoPrefixHidePrefix 标志。然后为ToolStripManager.Renderer注册渲染器。

对于其他控件显示助记符,您可以覆盖表单的WndProc方法并处理WM_UPDATEUISTATE消息并将WParam设置为UISF_HIDEACCEL作为高位词和UIS_CLEAR作为低位词的组合。这样所有控件都会显示助记符下划线。

示例

只需将以下代码复制并粘贴到您的表单中并运行您的应用程序。该表格将显示所有助记符的下划线,无需按 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);
    }
}

【讨论】:

  • 非常好的答案,可以根据我的需要完美运行。非常感谢。
猜你喜欢
  • 2012-01-25
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
  • 1970-01-01
  • 2017-12-27
相关资源
最近更新 更多