delphi – 如何覆盖调用以在TEdit中显示CapsLock提示窗口?

前端之家收集整理的这篇文章主要介绍了delphi – 如何覆盖调用以在TEdit中显示CapsLock提示窗口?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
基本上我有这个问题: CapsLock password message in TEdit visually fails with VCL Styles.

我想要做的不是解决问题,如答案或评论中所示.

我想完全禁用那个丑陋的提示窗口.而是显示一个图像,让用户知道帽子被锁定.

像这样

解决方法

我找到了我的问题的解决方案,它涉及到我宁愿不使用的黑客攻击.

它是这样的.

>覆盖WndProc.

  1. type
  2. TEdit = class (Vcl.StdCtrls.TEdit)
  3. protected
  4. procedure WndProc(var Message: TMessage); override;
  5. end;

>拦截EM_SHOWBALLOONTIPmessage,你就完成了

  1. procedure TEdit.WndProc(var Message: TMessage);
  2. begin
  3. if Message.Msg = EM_SHOWBALLOONTIP then
  4. showmessage('Do your thing.')
  5. else
  6. inherited;
  7. end;

有关更多信息,请查看MSDN文档:

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

这是TEdit的后代,如果使用PasswordChar<>分配某个FOnPasswordCaps事件,则允许在密码编辑控件上抑制CapsLock警告. #0

  1. unit NCREditUnit;
  2.  
  3. interface
  4.  
  5. uses
  6. Vcl.StdCtrls,vcl.Controls,Winapi.Messages,System.Classes;
  7.  
  8. type
  9. TNCREdit = class(TEdit)
  10. private
  11. FOnPasswordCapsLocked: TNotifyEvent;
  12. FIsCapsLocked: boolean;
  13. FOnPasswordCapsFreed: TNotifyEvent;
  14. FBlockCapsBalloonTip: boolean;
  15. FValuePasswordChrOnCaps: boolean;
  16. procedure SetOnPasswordCapsEvents;
  17. procedure SetOnPasswordCapsFreed(const aValue: TNotifyEvent);
  18. procedure SetOnPasswordCapsLocked(const aValue: TNotifyEvent);
  19. protected
  20. procedure WndProc(var Message: TMessage); override;
  21. procedure KeyUp(var Key: Word; Shift: TShiftState); override;
  22. procedure DoEnter; override;
  23. procedure DoExit; override;
  24. published
  25. property BlockCapsBalloonTip: boolean read FBlockCapsBalloonTip write FBlockCapsBalloonTip default False;
  26. property ValuePasswordChrOnCaps: boolean read FValuePasswordChrOnCaps write FValuePasswordChrOnCaps default True;
  27.  
  28. //... The usual property declaration of TEdit
  29.  
  30. property OnPasswordCapsLocked: TNotifyEvent read FOnPasswordCapsLocked write SetOnPasswordCapsLocked;
  31. property OnPasswordCapsFreed: TNotifyEvent read FOnPasswordCapsFreed write SetOnPasswordCapsFreed;
  32. end;
  33.  
  34.  
  35. implementation
  36.  
  37. uses
  38. Winapi.CommCtrl,Winapi.Windows;
  39.  
  40. { TNCREdit }
  41.  
  42. procedure TNCREdit.DoEnter;
  43. begin
  44. inherited;
  45. if FBlockCapsBalloonTip then
  46. begin
  47. FIsCapsLocked := Odd(GetKeyState(VK_CAPITAL));
  48. SetOnPasswordCapsEvents;
  49. end;
  50. end;
  51.  
  52. procedure TNCREdit.DoExit;
  53. begin
  54. if FBlockCapsBalloonTip and (FIsCapsLocked) then
  55. begin
  56. FIsCapsLocked := False;
  57. SetOnPasswordCapsEvents;
  58. end;
  59. inherited;
  60. end;
  61.  
  62. procedure TNCREdit.KeyUp(var Key: Word; Shift: TShiftState);
  63. begin
  64. if Key = VK_CAPITAL then
  65. FIsCapsLocked := not FIsCapsLocked;
  66. SetOnPasswordCapsEvents;
  67. inherited;
  68. end;
  69.  
  70. procedure TNCREdit.SetOnPasswordCapsEvents;
  71. begin
  72. if FIsCapsLocked then
  73. begin
  74. if Assigned(FOnPasswordCapsLocked) and
  75. ((self.PasswordChar <> #0) or ( not FValuePasswordChrOnCaps)) then
  76. begin
  77. FOnPasswordCapsLocked(Self);
  78. end;
  79. end
  80. else
  81. begin
  82. if Assigned(FOnPasswordCapsLocked) and
  83. ((self.PasswordChar <> #0) or ( not FValuePasswordChrOnCaps)) then
  84. begin
  85. FOnPasswordCapsFreed(Self);
  86. end;
  87. end;
  88. end;
  89.  
  90. procedure TNCREdit.SetOnPasswordCapsFreed(const aValue: TNotifyEvent);
  91. begin
  92. FOnPasswordCapsFreed := aValue;
  93. FBlockCapsBalloonTip := True;
  94. end;
  95.  
  96. procedure TNCREdit.SetOnPasswordCapsLocked(const aValue: TNotifyEvent);
  97. begin
  98. FOnPasswordCapsLocked := aValue;
  99. FBlockCapsBalloonTip := True;
  100. end;
  101.  
  102. procedure TNCREdit.WndProc(var Message: TMessage);
  103. begin
  104. if (Message.Msg = EM_SHOWBALLOONTIP) and FBlockCapsBalloonTip then Exit;
  105. inherited;
  106. end;
  107.  
  108. end.

Kobik先生制作了一段非常优雅的代码,我认为不应该信任PasteBin,所以我决定在这里添加它.

根据我的理解,它允许您在TPasswordEdit接收焦点时触发的一个事件处理程序中处理TPasswordCapsLockState,失去焦点,在焦点处按下CapsLock键,并在PasswordChar更改时触发可选触发.

使用这种方法,我可以使用OnPasswordCapsLock事件在我的问题中显示/隐藏图像,而不是强迫组件的使用者为每个状态使用两个事件处理程序(顺便说一句非常聪明且不易出错).

也只要LNeedHandle:= FBlockCapsBalloonTip和IsPassword;是真的我有另一个TPasswordEdit的附加功能,它也是在OnPasswordCapsLock中处理OnEnter和OnExit,

那么我能说什么Kobik Je vous轮胎mon chapeau.

  1. type
  2. TPasswordCapsLockState = (pcsEnter,pcsExit,pcsKey,pcsSetPasswordChar);
  3.  
  4. TPasswordCapsLockEvent = procedure(Sender: TObject;
  5. Locked: Boolean; State: TPasswordCapsLockState) of object;
  6.  
  7. TPasswordEdit = class(TCustomEdit)
  8. private
  9. FIsCapsLocked: boolean;
  10. FBlockCapsBalloonTip: boolean;
  11. FOnPasswordCapsLock: TPasswordCapsLockEvent;
  12. protected
  13. procedure WndProc(var Message: TMessage); override;
  14. procedure KeyUp(var Key: Word; Shift: TShiftState); override;
  15. procedure DoEnter; override;
  16. procedure DoExit; override;
  17. procedure HandlePasswordCapsLock(State: TPasswordCapsLockState); virtual;
  18. function GetIsPassword: Boolean; virtual;
  19. public
  20. property IsPassword: Boolean read GetIsPassword;
  21. published
  22. property BlockCapsBalloonTip: boolean read FBlockCapsBalloonTip write FBlockCapsBalloonTip default False;
  23. //... The usual property declaration of TEdit
  24. property OnPasswordCapsLock: TPasswordCapsLockEvent read FOnPasswordCapsLock write FOnPasswordCapsLock;
  25. end;
  26.  
  27. implementation
  28.  
  29. function TPasswordEdit.GetIsPassword: Boolean;
  30. begin
  31. Result := ((PasswordChar <> #0) or
  32. // Edit control can have ES_PASSWORD style with PasswordChar == #0
  33. // if it was creaed with ES_PASSWORD style
  34. (HandleAllocated and (GetWindowLong(Handle,GWL_STYLE) and ES_PASSWORD <> 0)));
  35. end;
  36.  
  37. procedure TPasswordEdit.HandlePasswordCapsLock;
  38. var
  39. LNeedHandle: Boolean;
  40. begin
  41. LNeedHandle := FBlockCapsBalloonTip and IsPassword;
  42. if LNeedHandle then
  43. begin
  44. FIsCapsLocked := Odd(GetKeyState(VK_CAPITAL));
  45. if Assigned(FOnPasswordCapsLock) then
  46. FOnPasswordCapsLock(Self,FIsCapsLocked,State);
  47. end;
  48. end;
  49.  
  50. procedure TPasswordEdit.DoEnter;
  51. begin
  52. inherited;
  53. HandlePasswordCapsLock(pcsEnter);
  54. end;
  55.  
  56. procedure TPasswordEdit.DoExit;
  57. begin
  58. inherited;
  59. HandlePasswordCapsLock(pcsExit);
  60. end;
  61.  
  62. procedure TPasswordEdit.KeyUp(var Key: Word; Shift: TShiftState);
  63. begin
  64. inherited;
  65. if Key = VK_CAPITAL then
  66. HandlePasswordCapsLock(pcsKey);
  67. end;
  68.  
  69. procedure TPasswordEdit.WndProc(var Message: TMessage);
  70. begin
  71. if (Message.Msg = EM_SHOWBALLOONTIP) and FBlockCapsBalloonTip and IsPassword then
  72. Exit;
  73. // Optional - if password char was changed
  74. if (Message.Msg = EM_SETPASSWORDCHAR) and Self.Focused then
  75. HandlePasswordCapsLock(pcsSetPasswordChar);
  76. inherited;
  77. end;

猜你在找的Delphi相关文章