使用默认的Windows设置,在用户按下ALT键之前,加速键不会显示在对话框上.
Delphi的TLabel控件不遵守此约定,如下所示:

虽然标签和复选框都指定了加速键,但复选框会正确隐藏它,但标签不会.当然,当ALT按下时,加速器显示复选框,但它是之前的行为是不正确的.
我对这种情况发生的理解是,实现此行为的VCL代码包含在TWinControl例如UpdateUIState方法中,并依赖于向底层窗口控件发送WM_CHANGEUISTATE消息.由于TLabel没有窗口,它错过了这个处理.
任何人都可以建议一种方法来实现非窗口控件的所需行为吗?
更新1
我刚刚发现组框和广播组也没有响应UI状态.
更新2
我想我已经找到了处理它的方法.
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报告.
| 归档时间: |
|
| 查看次数: |
767 次 |
| 最近记录: |