在TEdit.onEnter事件中设置TEdit.PasswordChar属性导致TEdit无法在Delphi XE西雅图

时间:2016-06-01 11:18:27

标签: delphi winapi vcl sendmessage delphi-10-seattle

我在表单上放置了一个TEdit控件,用于输入密码。我的目标是,让TEdit控件在没有聚焦时显示星号,避免其他人看到它,并显示密码以便在聚焦时进行编辑。

为实现这一目标,我添加了OnEnter和OnExit处理程序,将PasswordChar属性设置为#0和'*'。

这在Delphi 7中运行良好,但是在Delphi XE西雅图出错了,TEdit控件进入了一个奇怪的状态,它没有显示闪烁的编辑光标,也没有显示OnEnter事件触发后突出显示的蓝色背景选择(在PasswordChar设置为#0)。

我在调试模式下进入了TEdit控件源代码,发现在设置PasswordChar时,TEdit控件将重新创建它的一些句柄(我不太了解Windows API)。我想这引起了问题,但不确定,并且不知道如何避免它。

请帮我解决这个问题,我已经尝试了很多但没找到方法。

这是最简单的测试程序:

type
  TTestForm = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    procedure Edit1Enter(Sender: TObject);
    procedure Edit1Exit(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  TestForm: TTestForm;

implementation

{$R *.dfm}

procedure TTestForm.Edit1Enter(Sender: TObject);
begin
  Edit1.PasswordChar := #0;
end;

procedure TTestForm.Edit1Exit(Sender: TObject);
begin
  Edit1.PasswordChar := '*';
end;

end.

DFM:

object TestForm: TTestForm
  Left = 0
  Top = 0
  Caption = 'TestForm'
  ClientHeight = 242
  ClientWidth = 472
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Edit1: TEdit
    Left = 72
    Top = 48
    Width = 225
    Height = 21
    PasswordChar = '*'
    TabOrder = 0
    Text = 'You can not see text selection'
    OnEnter = Edit1Enter
    OnExit = Edit1Exit
  end
  object Edit2: TEdit
    Left = 72
    Top = 75
    Width = 225
    Height = 21
    TabOrder = 1
    Text = 'Click this control to trigger TEdit1.OnExit'
  end
end

1 个答案:

答案 0 :(得分:1)

您可以使用EM_SETPASSWORDCHAR消息清除ES_PASSWORD样式。这使编辑保持正常状态。但是在OnExit中你需要设置passwordchar两次才能编辑以重新创建它的窗口。或者您可以使用一些黑客控件来访问RecreateWnd过程(因此它不会创建它的窗口两次)。

procedure TTestForm.Edit1Enter(Sender: TObject);
begin
  SendMessage(Edit1.Handle, EM_SETPASSWORDCHAR, 0, 0);
end;

procedure TTestForm.Edit1Exit(Sender: TObject);
begin
  Edit1.PasswordChar := #0;
  Edit1.PasswordChar := '*';
end;