Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Menu Accelerator Keys Not Showing Up (Delphi 2009)

I've tried my best and cannot figure out what happened here. It worked fine in Delphi 4. After upgrading to Delphi 2009, I don't know if this is the way it is supposed to work, or if it's a problem:

This is what my program's menu looks like in Design Mode under Delphi 2009:

enter image description here

Notice that every word in the Main Menu and the File submenu have one letter underlined. It is supposed to be like this. This underlined letter is called the Accelerator Key and is standard in Windows applications so that you can use the Alt-key and that letter to quickly select the menu item and then submenu item with the keyboard rather than with your mouse.

You get them this way by using the "&" character as part of the caption of the item, for example: Save &As...

When I run my application, and use the mouse to open the File menu, it looks like this:

enter image description here

The characters are underlined in the main menu, but are not underlined in the File menu.

If instead, I use the Alt-F key to open up the File submenu, then it looks correct like this:

enter image description here

and all the Accelerator Key letters are properly underlined.

I've played with the AutoHotKeys option but that's not the problem.

Has someone encountered this problem before? Is the example in the 2nd image correct behavior that I don't know of? Or is there some option or coding mistake that I might have missed?


Nov 2009 (one year later): mghie seems to have got to the root of this and figured out the problem. See his accepted answer below.

like image 990
lkessler Avatar asked Nov 11 '08 07:11

lkessler


2 Answers

There is a standard Windows setting (under display properties) to normally hide those accelerators unless the Alt key is held down. That would explain why opening the menu with Alt+F10 shows them for you. Maybe that's the cause?

[EDIT]: No, it's not. I just tried, and a simple TForm with a menu item shows the accelerator, but as soon as I add a TImageList and set the ImageIndex of the single menu item, or simply set OwnerDraw to true, then the accelerator underline disappears. I guess that really is a bug in the VCL.

BTW, this is on Windows XP.

Workaround:

I have debugged this using Delphi 2009 on Windows XP 64, and the root cause for the missing accelerators seems to be that Windows sends WM_DRAWITEM messages with the ODS_NOACCEL flag set, which it shouldn't if the system is set to show accelerators at all times. So you could say that it is not a VCL bug, but a Windows problem which the VCL does not work around.

However, you can work around it in your own code, you just need to reset the flag before passing the message to the VCL. Override the window proc

protected
  procedure WndProc(var Message: TMessage); override;

like so:

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;

This is demonstration code only, you should not call SystemParametersInfo() every time a WM_DRAWITEM message is received, but once at program start, and then every time your program receives a WM_SETTINGCHANGE message.

like image 176
mghie Avatar answered Sep 22 '22 01:09

mghie


It is a "feature" introduced with Windows 2000:

The Old New Thing: Why does Windows hide keyboard accelerators and focus rectangles by default?

It would appear that Delphi 4 didn't support this Windows feature.

To have 2000 and XP menus show accelerator keys, right-click an empty spot on the desktop, choose Properties, click the Appearance tab, and under Effects, uncheck Hide Underlined Letters for Keyboard Navigation until I Press the Alt Key. Click OK twice.

Not sure how to do it in Vista.

like image 6
Jim McKeeth Avatar answered Sep 19 '22 01:09

Jim McKeeth