使用默认的
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) 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;
我确保通过使用TReader.OnFindComponentClass挂钩表单流机制来创建TUIStateAwareLabel而不是TLabel.
处理TCustomGroupBox后代更加混乱.对于他们,我使用TCustomGroupBox.Paint的源代码复制到我的后代并再次使用HideAccelFlag.
下一个任务是将其写为QC报告.