即使UI状态说不,TLabel也会显示加速键

Dav*_*nan 7 delphi

使用默认的Windows设置,在用户按下ALT键之前,加速键不会显示在对话框上.

Delphi的TLabel控件不遵守此约定,如下所示:

虽然标签和复选框都指定了加速键,但复选框会正确隐藏它,但标签不会.当然,当ALT按下时,加速器显示复选框,但它是之前的行为是不正确的.

我对这种情况发生的理解是,实现此行为的VCL代码包含在TWinControl例如UpdateUIState方法中,并依赖于向底层窗口控件发送WM_CHANGEUISTATE消息.由于TLabel没有窗口,它错过了这个处理.

任何人都可以建议一种方法来实现非窗口控件的所需行为吗?

更新1

我刚刚发现组框和广播组也没有响应UI状态.

更新2

QC#97044.

Dav*_*nan 7

我想我已经找到了处理它的方法.

function HideAccelFlag(Control: TControl): Integer;
begin
  //ask the top level window about its UI state
  while Assigned(Control.Parent) do begin
    Control := Control.Parent;
  end;
  if (Control.Perform(WM_QUERYUISTATE, 0, 0) and UISF_HIDEACCEL)=UISF_HIDEACCEL then begin
    Result := DT_HIDEPREFIX;
  end else begin
    Result := 0;
  end;
end;

type
  TUIStateAwareLabel = class(TLabel)
  protected
    procedure DoDrawText(var Rect: TRect; Flags: Longint); override;
  end;

procedure TUIStateAwareLabel.DoDrawText(var Rect: TRect; Flags: Integer);
begin
  if ShowAccelChar then begin
    Flags := Flags or HideAccelFlag(Self);
  end;
  inherited;
end;
Run Code Online (Sandbox Code Playgroud)

我确保我总是创建TUIStateAwareLabel而不是TLabel通过挂钩表单流机制TReader.OnFindComponentClass.

处理TCustomGroupBox后代更加混乱.对于他们,我使用复制源代码TCustomGroupBox.Paint到我的后代并HideAccelFlag再次使用.

下一个任务是将其写为QC报告.