我想完全禁用那个丑陋的提示窗口.而是显示一个图像,让用户知道帽子被锁定.
像这样
解决方法
它是这样的.
>覆盖WndProc.
码
type TEdit = class (Vcl.StdCtrls.TEdit) protected procedure WndProc(var Message: TMessage); override; end;
>拦截EM_SHOWBALLOONTIPmessage,你就完成了
码
procedure TEdit.WndProc(var Message: TMessage); begin if Message.Msg = EM_SHOWBALLOONTIP then showmessage('Do your thing.') else inherited; end;
有关更多信息,请查看MSDN文档:
How do I suppress the CapsLock warning on password edit controls?
这是TEdit的后代,如果使用PasswordChar<>分配某个FOnPasswordCaps事件,则允许在密码编辑控件上抑制CapsLock警告. #0
unit NCREditUnit; interface uses Vcl.StdCtrls,vcl.Controls,Winapi.Messages,System.Classes; type TNCREdit = class(TEdit) private FOnPasswordCapsLocked: TNotifyEvent; FIsCapsLocked: boolean; FOnPasswordCapsFreed: TNotifyEvent; FBlockCapsBalloonTip: boolean; FValuePasswordChrOnCaps: boolean; procedure SetonPasswordCapsEvents; procedure SetonPasswordCapsFreed(const aValue: TNotifyEvent); procedure SetonPasswordCapsLocked(const aValue: TNotifyEvent); protected procedure WndProc(var Message: TMessage); override; procedure KeyUp(var Key: Word; Shift: TShiftState); override; procedure DoEnter; override; procedure DoExit; override; published property BlockCapsBalloonTip: boolean read FBlockCapsBalloonTip write FBlockCapsBalloonTip default False; property ValuePasswordChrOnCaps: boolean read FValuePasswordChrOnCaps write FValuePasswordChrOnCaps default True; //... The usual property declaration of TEdit property OnPasswordCapsLocked: TNotifyEvent read FOnPasswordCapsLocked write SetonPasswordCapsLocked; property OnPasswordCapsFreed: TNotifyEvent read FOnPasswordCapsFreed write SetonPasswordCapsFreed; end; implementation uses Winapi.CommCtrl,Winapi.Windows; { TNCREdit } procedure TNCREdit.DoEnter; begin inherited; if FBlockCapsBalloonTip then begin FIsCapsLocked := Odd(GetKeyState(VK_CAPITAL)); SetonPasswordCapsEvents; end; end; procedure TNCREdit.DoExit; begin if FBlockCapsBalloonTip and (FIsCapsLocked) then begin FIsCapsLocked := False; SetonPasswordCapsEvents; end; inherited; end; procedure TNCREdit.KeyUp(var Key: Word; Shift: TShiftState); begin if Key = VK_CAPITAL then FIsCapsLocked := not FIsCapsLocked; SetonPasswordCapsEvents; inherited; end; procedure TNCREdit.SetonPasswordCapsEvents; begin if FIsCapsLocked then begin if Assigned(FOnPasswordCapsLocked) and ((self.PasswordChar <> #0) or ( not FValuePasswordChrOnCaps)) then begin FOnPasswordCapsLocked(Self); end; end else begin if Assigned(FOnPasswordCapsLocked) and ((self.PasswordChar <> #0) or ( not FValuePasswordChrOnCaps)) then begin FOnPasswordCapsFreed(Self); end; end; end; procedure TNCREdit.SetonPasswordCapsFreed(const aValue: TNotifyEvent); begin FOnPasswordCapsFreed := aValue; FBlockCapsBalloonTip := True; end; procedure TNCREdit.SetonPasswordCapsLocked(const aValue: TNotifyEvent); begin FOnPasswordCapsLocked := aValue; FBlockCapsBalloonTip := True; end; procedure TNCREdit.WndProc(var Message: TMessage); begin if (Message.Msg = EM_SHOWBALLOONTIP) and FBlockCapsBalloonTip then Exit; inherited; end; end.
Kobik先生制作了一段非常优雅的代码,我认为不应该信任PasteBin,所以我决定在这里添加它.
根据我的理解,它允许您在TPasswordEdit接收焦点时触发的一个事件处理程序中处理TPasswordCapsLockState,失去焦点,在焦点处按下CapsLock键,并在PasswordChar更改时触发可选触发.
使用这种方法,我可以使用OnPasswordCapsLock事件在我的问题中显示/隐藏图像,而不是强迫组件的使用者为每个状态使用两个事件处理程序(顺便说一句非常聪明且不易出错).
也只要LNeedHandle:= FBlockCapsBalloonTip和IsPassword;是真的我有另一个TPasswordEdit的附加功能,它也是在OnPasswordCapsLock中处理OnEnter和OnExit,
那么我能说什么Kobik Je vous轮胎mon chapeau.
type TPasswordCapsLockState = (pcsEnter,pcsExit,pcsKey,pcsSetPasswordChar); TPasswordCapsLockEvent = procedure(Sender: TObject; Locked: Boolean; State: TPasswordCapsLockState) of object; TPasswordEdit = class(TCustomEdit) private FIsCapsLocked: boolean; FBlockCapsBalloonTip: boolean; FOnPasswordCapsLock: TPasswordCapsLockEvent; protected procedure WndProc(var Message: TMessage); override; procedure KeyUp(var Key: Word; Shift: TShiftState); override; procedure DoEnter; override; procedure DoExit; override; procedure HandlePasswordCapsLock(State: TPasswordCapsLockState); virtual; function GetIsPassword: Boolean; virtual; public property IsPassword: Boolean read GetIsPassword; published property BlockCapsBalloonTip: boolean read FBlockCapsBalloonTip write FBlockCapsBalloonTip default False; //... The usual property declaration of TEdit property OnPasswordCapsLock: TPasswordCapsLockEvent read FOnPasswordCapsLock write FOnPasswordCapsLock; end; implementation function TPasswordEdit.GetIsPassword: Boolean; begin Result := ((PasswordChar <> #0) or // Edit control can have ES_PASSWORD style with PasswordChar == #0 // if it was creaed with ES_PASSWORD style (HandleAllocated and (getwindowlong(Handle,GWL_STYLE) and ES_PASSWORD <> 0))); end; procedure TPasswordEdit.HandlePasswordCapsLock; var LNeedHandle: Boolean; begin LNeedHandle := FBlockCapsBalloonTip and IsPassword; if LNeedHandle then begin FIsCapsLocked := Odd(GetKeyState(VK_CAPITAL)); if Assigned(FOnPasswordCapsLock) then FOnPasswordCapsLock(Self,FIsCapsLocked,State); end; end; procedure TPasswordEdit.DoEnter; begin inherited; HandlePasswordCapsLock(pcsEnter); end; procedure TPasswordEdit.DoExit; begin inherited; HandlePasswordCapsLock(pcsExit); end; procedure TPasswordEdit.KeyUp(var Key: Word; Shift: TShiftState); begin inherited; if Key = VK_CAPITAL then HandlePasswordCapsLock(pcsKey); end; procedure TPasswordEdit.WndProc(var Message: TMessage); begin if (Message.Msg = EM_SHOWBALLOONTIP) and FBlockCapsBalloonTip and IsPassword then Exit; // Optional - if password char was changed if (Message.Msg = EM_SETPASSWORDCHAR) and Self.Focused then HandlePasswordCapsLock(pcsSetPasswordChar); inherited; end;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。