2017-12-11 140 views
6

Temel olarak şu sorunum var: CapsLock password message in TEdit visually fails with VCL Styles.Bir TEdit'teki CapsLock ipucu penceresini göstermek için çağrı nasıl geçersiz kılınır?

Yapmak istediğim şey, sorunun yanıtında veya yorumlarında gösterildiği gibi çözülmesi değil.

Bu çirkin ipucu penceresini tamamen devre dışı bırakmak istiyorum. ve bunun yerine, kullanıcının kapakların kilitlendiğini bilmesini sağlayan bir görüntüyü gösterin. Benim sorununa çözüm bulundu bu

enter image description here

cevap

7

gibi

, Ben doğrusu kullanmak ister yazarlardan içerir.

Böyle gider.

  1. WndProc'u geçersiz kıl.

kod

type 
    TEdit = class (Vcl.StdCtrls.TEdit) 
    protected 
    procedure WndProc(var Message: TMessage); override; 
    end; 
  • Intercept EM_SHOWBALLOONTIP mesaj
      ve bitirdiniz

    kod

    procedure TEdit.WndProc(var Message: TMessage); 
    begin 
    if Message.Msg = EM_SHOWBALLOONTIP then 
        showmessage('Do your thing.') 
    else 
        inherited; 
    end; 
    

    fazla bilgi kontrol için MSDN dökümantasyonu:


    Bu

    How do I suppress the CapsLock warning on password edit controls?

    belli FOnPasswordCaps olaylar PasswordChar <> #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. 
    

    Mr ile atanmışsa, şifre düzenleme denetimlere CapsLock uyarıyı bastırmak için izin verecek TEdit soyundan olan Kobik, PasteBin'in ev sahipliğine güvenilmemesi gerektiğini düşündüğüm çok zarif bir kod parçası yaptı, ben de buraya eklemeye karar verdim. Ben size, TPasswordEdit odağı aldığında ateşlenir TPasswordCapsLockState bir olay işleyicisi kolu sağlayan anlaşılan kadarıyla

    PasswordChar değiştirildiğinde odak ve isteğe bağlı ateş sırasında basıldığında odak, CapsLock tuşunu kaybeder.

    Bu yaklaşımı kullanarak, her bir durum için iki olay işleyicisini kullanacak şekilde bileşenin tüketicisini zorlamak yerine sorgumda görüntüyü göstermek/gizlemek için OnPasswordCapsLock olayını kullanabilirim (çok akıllıca ve daha az hataya neden olabilir). sürece LNeedHandle := FBlockCapsBalloonTip and IsPassword; olarak da

    Ben OnEnter ele alınması ve aynı zamanda OnPasswordCapsLock yılında OnExit olduğunu TPasswordEdit başka ilave özelliği,

    Yani ben Bay Kobik Je vous lastik mon chapeau ne diyebilirim sahip True olduğunu.Beni güldürdü @JerryDodge

    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; 
    
  • +0

    çok şaşırtıcı değil ... Sonuçta, VCL Stiller –

    +0

    :-) zaten ilk etapta bir hack vardır. teşekkür ederim. –

    +2

    Bu, sorunuzun sadece yarısıdır. Simgenizin görüntüsünü tetiklemek için bunu kullanabilirsiniz. Ancak, Düzenleme denetimi, kullanıcı Caps Lock'u değiştirdiğinde araç ipucunu reddederken karşılık gelen bildirim yoktur. Böylece, simgenizi gizlemek için Caps Lock'un durumunu izlemeniz gerekecek. Bu yüzden simgeyi göstermek için de kullanabilirsiniz ve bu çözümü sadece Edit'in araç ipucunu kapatmak için kullanın. –