我已尽力而为,无法弄清楚这里发生了什么。它在Delphi 4中运行良好。升级到Delphi 2009之后,我不知道这是否应该如何工作,或者它是否有问题:

这是我的程序菜单在Delphi 2009下的设计模式中的样子:

请注意,主菜单和文件子菜单中的每个单词都有一个带下划线的字母。应该是这样的。带下划线的字母称为加速键,是Windows应用程序的标准字母,因此您可以使用Alt键和该字母快速选择菜单项,然后使用键盘而不是鼠标快速选择子菜单项。

你可以通过使用“&”来获得这种方式。字符作为项目标题的一部分,例如:Save& As ...

当我运行我的应用程序,并使用鼠标打开文件菜单时,它看起来像这样:

主菜单中的字符带下划线,但文件菜单中没有加下划线。

如果相反,我使用Alt-F键打开文件子菜单,然后看起来像这样:

并且所有Accelerator Key字母都有正确的下划线。

我玩过AutoHotKeys选项,但这不是问题。

之前有人遇到过此问题吗?第二个图像中的示例是否是我不知道的正确行为?或者我可能错过了一些选项或编码错误?


2009年11月(一年后):mghie似乎已经找到了根源,并找出了问题所在。请参阅下面接受的答案。

有帮助吗?

解决方案

除非按住Alt键,否则有一个标准的Windows设置(在显示属性下)通常会隐藏这些加速器。这可以解释为什么用Alt + F10打开菜单会为你显示它们。也许这就是原因?

[编辑]:不,不是。我刚试过,一个带菜单项的简单TForm显示加速器,但是只要我添加TImageList并设置单个菜单项的ImageIndex,或者只是将OwnerDraw设置为true,加速器下划线就会消失。我想这确实是VCL中的一个错误。

BTW,这是在Windows XP上。

解决方法:

我在Windows XP 64上使用Delphi 2009进行了调试,缺少加速器的根本原因似乎是Windows发送 WM_DRAWITEM 消息并设置了 ODS_NOACCEL 标志如果系统设置为始终显示加速器,则不应该这样做。所以你可以说它不是VCL错误,而是VCL无法解决的Windows问题。

但是,您可以在自己的代码中解决它,只需要在将消息传递给VCL之前重置标志。覆盖窗口proc

protected
  procedure WndProc(var Message: TMessage); override;
像这样:

procedure TYourForm.WndProc(var Message: TMessage);
const
  ODS_NOACCEL = $100;
var
  pDIS: PDrawItemStruct;
  ShowAccel: BOOL;
begin
  if (Message.Msg = WM_DRAWITEM) then begin
    pDIS := PDrawItemStruct(Message.LParam);
    if (pDIS^.CtlType = ODT_MENU)
      and SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, @ShowAccel, 0)
    then begin
      if ShowAccel then
        pDIS^.itemState := pDIS^.itemState and not ODS_NOACCEL;
    end;
  end;
  inherited;
end;

这只是演示代码,每次收到 WM_DRAWITEM 消息时都不应该调用 SystemParametersInfo(),但是一旦程序启动,然后每次你的程序收到 WM_SETTINGCHANGE 消息。

其他提示

这是一个“特征”。 Windows 2000引入:

The Old New Thing:为什么Windows会隐藏键盘加速器并默认聚焦矩形?

似乎Delphi 4不支持此Windows功能。

要让2000和XP菜单显示加速键,右键单击桌面上的空白点,选择属性,单击外观选项卡,然后在效果下,取消选中隐藏带下划线的键盘导航字母,直到我按Alt键键的。单击“确定”两次。

不确定如何在Vista中执行此操作。

我认为这不是Delphi生成的错误,因为你在Vista上的记事本具有相同的行为。也是在Delphi本身BTW ...
我必须承认,在你的问题之前,我没有注意。谢谢你指出来。

正如Jim McKeeth上面提到的(正确地),这是“按设计”。行为。如果通过键盘操作触发菜单,则应显示加速器,但如果由鼠标触发,则故意不显示加速器。

我的XP配置为始终显示加速器,但更改该选项的快速测试确认菜单不应显示下划线(Visual Studio按我的预期响应,使用鼠标时没有下划线)。但是,Microsoft Office忽略此设置并始终显示下划线。所以它看起来像是如何在Delphi中绘制菜单的一个错误(我自己没有任何Delphi经验)。

我也找到了Vista的选项: http://www.vistax64.com/vista-general/42125-always-show-menu-underline-keyboard-accelerators.html

  

您可以在新的轻松访问中心中启用此功能(转到“控制”   单击“面板”,单击“轻松访问”,然后单击“轻松访问中心”。在   轻松访问中心,单击使键盘更容易使用,和   在最底部选择下划线键盘快捷键和访问权限   钥匙复选框。

在进行进一步研究时,我在Delphi论坛上发现了这个相关错误: http: //qc.codegear.com/wc/qcmain.aspx?d=37403

在您的情况下,子窗口(绘制的菜单)看起来没有或没有从父窗口处理WM_UIUPDATESTATE消息,这是导致重绘加速器的原因。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top