Workaround 1:
(Modifies VCL code -- also inefficient, but less work for integration into
applications)
Modify, in 2 locations in menus.pas, the following code to
TMenuItem.AdvancedDrawItem (approx lines 1200, 1400):
if Win2K and (odNoAccel in State) then
DrawStyle := DrawStyle or DT_HIDEPREFIX;
to:
var FAlwaysDrawUnderline: BOOL; {in variable declarations, approx line 1025}
if SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, @FAlwaysDrawUnderline, 0) then
if not FAlwaysDrawUnderline then
if Win2K and (odNoAccel in State) then
DrawStyle := DrawStyle or DT_HIDEPREFIX;
Workaround 2:
(Recommended -- more efficient and doesn't modify the VCL code)
Include the following code in the form with the MainMenu. This turns off
the ODS_NOACCEL flag before the menu is drawn, if appropriate. If you want
to ensure that the application updates its settings when the Control Panel
option is changed, you can either (1) set FWndProcInit:=False in an
Application.OnMessage event procedure when WM_SETTINGCHANGE is received, or
(2) set FWndProcInit:=False in an Application.OnActivate event procedure.
const
SPI_GETKEYBOARDCUES = $100A;
var
FAlwaysDrawUnderline: BOOL = False;
FWndProcInit: Boolean = False;
procedure TfrmTike.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_DRAWITEM:
begin
if not FWndProcInit then
begin
SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, @FAlwaysDrawUnderline, 0);
FWndProcInit := True;
end;
if FAlwaysDrawUnderline then
with PDrawItemStruct(Message.lParam)^ do
if (CtlType = ODT_MENU) and Assigned(Menu) then
itemState := itemState and $FEFF;
end;
end;
inherited;
end;
|