Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/VCL/Standard Controls/TMainMenu    [ Add a report in this area ]  
Report #:  68816   Status: Open
Menu Accelerator Keys Not Showing Up
Project:  Delphi Build #:  12.0.3210.17555
Version:    12.1 Submitted By:   Louis Kessler
Report Type:  Minor failure / Design problem Date Reported:  11/11/2008 3:02:15 PM
Severity:    Serious / Highly visible problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All versions Internal Tracking #:   267107
Resolution: None (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 6
Accelerator keys in submenus do not show up when the submenu is opened with the mouse.

There is a full description of the problem, along with images at:
Steps to Reproduce:
See the answer in green at the stackoverflow site. He says:

"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."

Tomohiro Takahashi at 11/11/2008 7:16:48 PM -
I corrected Project field, Version field and Area field as Sysop.

Louis Kessler at 11/21/2009 6:14:45 PM -
mghie did some work on this. See: StackOverflow at:

where he found the cause of this and a workaround. His entire text is:


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

  procedure WndProc(var Message: TMessage); override;

like so:

procedure TYourForm.WndProc(var Message: TMessage);
  ODS_NOACCEL = $100;
  pDIS: PDrawItemStruct;
  ShowAccel: BOOL;
  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;

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.

Tomohiro Takahashi at 11/22/2009 6:35:43 PM -
Thanks for the information. I will update internal status about your workaournd.

Ulrich Gerhardt at 1/12/2012 2:03:44 AM -
The problem persists in XE2.

Server Response from: ETNACODE01