Reputation: 103
I placed a TEdit control on a form, for a password. My aim is, let the TEdit control show asterisks when it's not focused, to avoid other people seeing it, and reveal the password to allow editing when focused.
To achieve this, I added OnEnter and OnExit handler to set PasswordChar property to #0 and '*' accordingly.
This worked well in Delphi 7, but went wrong in Delphi XE seattle, the TEdit control went into a strange state that it didn't show the blinking edit cursor, nor the highlighted blue backgrounded selection after the OnEnter event triggered (in which the PasswordChar is set to #0).
I stepped into the TEdit control source code in debug mode, and found the TEdit control will recreate its some handle (I don't know much of Windows API) when setting PasswordChar. I guess this caused the problem, but not sure, and don't know how to avoid it.
Please help me out of this, I've tried a lot and didn't find a way.
Here is the simplest test program:
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
Upvotes: 1
Views: 2813
Reputation: 516
You can clear ES_PASSWORD style with EM_SETPASSWORDCHAR message. This keeps edit in a normal state. But then in OnExit you need to set passwordchar twice in order to edit to recreate its window. Or you could use some hack control to get access to RecreateWnd procedure (so it wouldn't create it's window twice).
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;
Upvotes: 1