set TEdit.PasswordChar 属性 in TEdit.onEnter event causes TEdit cannot show selection and cursor in Delphi XE seattle
set TEdit.PasswordChar property in TEdit.onEnter event causes TEdit can not show selection and cursor in Delphi XE seattle
我在窗体上放置了一个 TEdit 控件作为密码。我的目标是,让 TEdit 控件在未获得焦点时显示星号,以避免其他人看到它,并在获得焦点时显示允许编辑的密码。
为此,我添加了 OnEnter 和 OnExit 处理程序以相应地将 PasswordChar 属性 设置为 #0 和 '*'。
这在 Delphi 7 中运行良好,但在 Delphi XE seattle 中出错,TEdit 控件进入了一个奇怪的状态,它没有显示闪烁的编辑光标,也没有显示突出显示的触发 OnEnter 事件后的蓝色背景选择(其中 PasswordChar 设置为 #0)。
我在调试模式下进入TEdit控件源代码,发现TEdit控件在设置PasswordChar时会重新创建它的一些句柄(我不太了解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
您可以使用 EM_SETPASSWORDCHAR 消息清除 ES_PASSWORD 样式。这使编辑保持正常状态。但随后在 OnExit 中,您需要设置 passwordchar 两次,以便进行编辑以重新创建其 window。或者您可以使用一些 hack 控件来访问 RecreateWnd 过程(因此它不会创建 window 两次)。
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;
我在窗体上放置了一个 TEdit 控件作为密码。我的目标是,让 TEdit 控件在未获得焦点时显示星号,以避免其他人看到它,并在获得焦点时显示允许编辑的密码。
为此,我添加了 OnEnter 和 OnExit 处理程序以相应地将 PasswordChar 属性 设置为 #0 和 '*'。
这在 Delphi 7 中运行良好,但在 Delphi XE seattle 中出错,TEdit 控件进入了一个奇怪的状态,它没有显示闪烁的编辑光标,也没有显示突出显示的触发 OnEnter 事件后的蓝色背景选择(其中 PasswordChar 设置为 #0)。
我在调试模式下进入TEdit控件源代码,发现TEdit控件在设置PasswordChar时会重新创建它的一些句柄(我不太了解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
您可以使用 EM_SETPASSWORDCHAR 消息清除 ES_PASSWORD 样式。这使编辑保持正常状态。但随后在 OnExit 中,您需要设置 passwordchar 两次,以便进行编辑以重新创建其 window。或者您可以使用一些 hack 控件来访问 RecreateWnd 过程(因此它不会创建 window 两次)。
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;