Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
菜单快捷键未显示(Delphi 2009)_Delphi_Menu_Delphi 2009_Acceleratorkey - Fatal编程技术网

菜单快捷键未显示(Delphi 2009)

菜单快捷键未显示(Delphi 2009),delphi,menu,delphi-2009,acceleratorkey,Delphi,Menu,Delphi 2009,Acceleratorkey,我已经尽了最大努力,弄不清楚这里发生了什么。它在Delphi4中运行良好。升级到Delphi 2009后,我不知道这是它的工作方式,还是一个问题: 这是我的程序在Delphi 2009的设计模式下的菜单: 请注意,主菜单和文件子菜单中的每个单词都有一个带下划线的字母。应该是这样的。此带下划线的字母称为加速键,是Windows应用程序中的标准字母,因此您可以使用Alt键和该字母快速选择菜单项,然后使用键盘而不是鼠标选择子菜单项 您可以通过将“&”字符作为项目标题的一部分来获得它们,例如:Save

我已经尽了最大努力,弄不清楚这里发生了什么。它在Delphi4中运行良好。升级到Delphi 2009后,我不知道这是它的工作方式,还是一个问题:

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

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

您可以通过将“&”字符作为项目标题的一部分来获得它们,例如:Save&as

当我运行我的应用程序并使用鼠标打开“文件”菜单时,它如下所示:

字符在主菜单中带下划线,但在文件菜单中不带下划线

如果改为使用Alt-F键打开文件子菜单,则它看起来是正确的,如下所示:

所有油门键字母都正确地加了下划线

我使用过自动热键选项,但这不是问题所在

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



2009年11月(一年后):mghie似乎已经找到了问题的根源并解决了问题。查看下面他接受的答案。

我不认为这是Delphi生成的错误,因为你在Vista上使用记事本时有相同的行为。顺便说一句,德尔福本身也是如此。

我必须承认,我没有注意你的问题。感谢您指出这一点。

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

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

顺便说一句,这是在WindowsXP上

解决方法:

我已经在Windows XP 64上使用Delphi 2009对此进行了调试,缺少加速器的根本原因似乎是Windows发送带有
ODS\u NOACCEL
标志集的
WM\u DRAWITEM
消息,如果系统设置为始终显示加速器,则不应该这样做。所以你可以说这不是一个VCL错误,而是一个VCL无法解决的Windows问题

但是,您可以在自己的代码中解决这个问题,只需在将消息传递给VCL之前重置标志。重写窗口进程

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\u DRAWITEM
消息时调用
SystemParametersInfo()
,而应在程序启动时调用一次,然后在程序每次收到
WM\u SETTINGCHANGE
消息时调用一次

这是Windows 2000引入的一项“功能”:

新旧事物:

Delphi4似乎不支持此Windows功能

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


不知道如何在Vista中实现它。

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

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

我还找到了Vista的选项:

您可以在新的Easy of Access Center(转到控制)中启用此功能 面板中,单击易访问性,然后单击易访问性中心)。在里面 要轻松访问中心,请单击“使键盘更易于使用”,然后单击 在最底部选择下划线键盘快捷键并访问 “关键点”复选框

在做进一步的研究时,我在Delphi论坛上发现了这个相关的bug:


在您的情况下,子窗口(绘制的菜单)似乎没有从父窗口获取或处理WM_UIUPDATESTATE消息,这就是使用加速器重新绘制的原因。

我以为您已经找到了答案。但不幸的是,当我看到“隐藏带下划线的字母”选项时(我以前从未知道),我发现它没有被选中。什么操作系统?您的屏幕截图看起来像XP。我刚刚在XP上试用过,效果很好(取消选中该选项,快捷键就会显示出来。)也许你需要重新启动。否。在Delphi2009 for me中,所有子菜单项都显示加速器键,即使我用鼠标选择菜单也是如此。这就是为什么我认为这是我的一些设置,而不是Delphi或操作系统。这绝对是一个很难解决的问题,我已经花了大约4个小时试图修复它。我也使用Windows XP。经过这些回答和我的思考,还有你的帮助,我同意这可能是VCL中的一个bug。顺便说一句,我和Delphi 2007有同样的行为。谢谢你对这件事的进一步研究(一年后!!)和发现这一点。我已经起床了