9

I have an inputbox and would like the user to enter a password, but at the same time hide it.

Is this possible?

This is my code so far:

var password : string;
begin
 password := InputBox('Password: ', 'Please enter your password: ', password)
end;
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
delphi_coder
  • 177
  • 1
  • 3
  • 10

6 Answers6

16

You 'cannot' use InputBox for this, because, well... clearly this function doesn't hide the text.

The standard Windows edit control has a 'password mode', though. To test this, simply add a TEdit to a form and set its PasswordChar to *.

If you want to use such an edit in an input box, you have to write this dialog yourself, like my 'super input dialog':

type
  TMultiInputBox = class
  strict private
    class var
      frm: TForm;
      lbl: TLabel;
      edt: TEdit;
      btnOK,
      btnCancel: TButton;
      shp: TShape;
      FMin, FMax: integer;
      FTitle, FText: string;
    class procedure SetupDialog;
    class procedure ValidateInput(Sender: TObject);
  public
    class function TextInputBox(AOwner: TCustomForm; const ATitle,
      AText: string; var Value: string): boolean;
    class function NumInputBox(AOwner: TCustomForm; const ATitle,
      AText: string; AMin, AMax: integer; var Value: integer): boolean;
    class function PasswordInputBox(AOwner: TCustomForm; const ATitle,
      AText: string; var Value: string): boolean;
  end;

class procedure TMultiInputBox.SetupDialog;
begin
  frm.Caption := FTitle;
  frm.Width := 512;
  frm.Position := poOwnerFormCenter;
  frm.BorderStyle := bsDialog;
  lbl := TLabel.Create(frm);
  lbl.Parent := frm;
  lbl.Left := 8;
  lbl.Top := 8;
  lbl.Width := frm.ClientWidth - 16;
  lbl.Caption := FText;
  edt := TEdit.Create(frm);
  edt.Parent := frm;
  edt.Top := lbl.Top + lbl.Height + 8;
  edt.Left := 8;
  edt.Width := frm.ClientWidth - 16;
  btnOK := TButton.Create(frm);
  btnOK.Parent := frm;
  btnOK.Default := true;
  btnOK.Caption := 'OK';
  btnOK.ModalResult := mrOk;
  btnCancel := TButton.Create(frm);
  btnCancel.Parent := frm;
  btnCancel.Cancel := true;
  btnCancel.Caption := 'Cancel';
  btnCancel.ModalResult := mrCancel;
  btnCancel.Top := edt.Top + edt.Height + 16;
  btnCancel.Left := frm.ClientWidth - btnCancel.Width - 8;
  btnOK.Top := btnCancel.Top;
  btnOK.Left := btnCancel.Left - btnOK.Width - 4;
  frm.ClientHeight := btnOK.Top + btnOK.Height + 8;
  shp := TShape.Create(frm);
  shp.Parent := frm;
  shp.Brush.Color := clWhite;
  shp.Pen.Style := psClear;
  shp.Shape := stRectangle;
  shp.Align := alTop;
  shp.Height := btnOK.Top - 8;
  shp.SendToBack;
end;

class function TMultiInputBox.TextInputBox(AOwner: TCustomForm; const ATitle,
  AText: string; var Value: string): boolean;
begin
  FTitle := ATitle;
  FText := AText;

  frm := TForm.Create(AOwner);
  try
    SetupDialog;
    edt.NumbersOnly := false;
    edt.PasswordChar := #0;
    edt.Text := Value;
    edt.OnChange := nil;
    result := frm.ShowModal = mrOK;
    if result then Value := edt.Text;
  finally
    frm.Free;
  end;
end;

class function TMultiInputBox.PasswordInputBox(AOwner: TCustomForm;
  const ATitle, AText: string; var Value: string): boolean;
begin
  FTitle := ATitle;
  FText := AText;

  frm := TForm.Create(AOwner);
  try
    SetupDialog;
    edt.NumbersOnly := false;
    edt.PasswordChar := '*';
    edt.Text := Value;
    edt.OnChange := nil;
    result := frm.ShowModal = mrOK;
    if result then Value := edt.Text;
  finally
    frm.Free;
  end;
end;

class procedure TMultiInputBox.ValidateInput(Sender: TObject);
var
  n: integer;
begin
  btnOK.Enabled := TryStrToInt(edt.Text, n) and InRange(n, FMin, FMax);
end;

class function TMultiInputBox.NumInputBox(AOwner: TCustomForm; const ATitle,
  AText: string; AMin, AMax: integer; var Value: integer): boolean;
begin
  FMin := AMin;
  FMax := AMax;
  FTitle := ATitle;
  FText := AText;

  frm := TForm.Create(AOwner);
  try
    SetupDialog;
    edt.NumbersOnly := true;
    edt.PasswordChar := #0;
    edt.Text := IntToStr(value);
    edt.OnChange := ValidateInput;
    result := frm.ShowModal = mrOK;
    if result then Value := StrToInt(edt.Text);
  finally
    frm.Free;
  end;
end;

Try it:

procedure TForm1.Button1Click(Sender: TObject);
var
  str: string;
begin
  str := '';
  if TMultiInputBox.PasswordInputBox(Self, 'Password',
    'Please enter your password:', str) then
    ShowMessageFmt('You entered %s.', [str]);
end;

Screenshot

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • Thanks, that will do. Another quick question? How do I let text dissapear inside an editbox? Say I have: "Enter Password Here" and when the user clicks on it, it goes away. Is this possible? – delphi_coder Jun 14 '11 at 17:58
  • 1
    That's also easy: simply set the `TextHint` property of the `TEdit` to `'Enter Password Here'`. – Andreas Rejbrand Jun 14 '11 at 17:59
  • 7
    @delphi_coder: Welcome on SO! The phrase "another quick question" should in most cases lead to another question on SO. – jpfollenius Jun 14 '11 at 18:04
  • 2
    If your version of Delphi doesn't have the `HintText` property, you can also accomplish it by sending the [`EM_SETCUEBANNER`](http://msdn.microsoft.com/en-us/library/bb761639.aspx) message to the `TEdit` control: `SendMessage(Edit1.Handle, $1501, 0, LParam(PWideChar('Enter Password Here')));` Note that your Delphi app has to have runtime themes enabled for this to work. – afrazier Jun 14 '11 at 18:05
  • @Smasher: Thanks. Will remember that for future use. Didn't seem like a big enough question to start a whole new question – delphi_coder Jun 14 '11 at 18:15
  • Remember that TextHint is only shown when you have Themes on. When you go back to Windows Classic mode on your system, TextHints on TEdits go away, because that's how they wrote MS Common Controls! – Warren P Jun 16 '11 at 00:10
5

This looks like it was answered here:

Delphi InputBox for password entry?

Community
  • 1
  • 1
Mattl
  • 1,588
  • 3
  • 24
  • 49
3

Don't use an InputBox. Create a dialog yourself and make sure to set TEdit.PasswordChar to something other than #0.

It may also be possible to get a handle to the InputBox's Edit control and set the PasswordChar via a Windows message, but I don't know how to do that off the top of my head (especially since the InputBox is a blocking call).

Delphi XE also has a Password Dialog form available to use when creating a new form. Older versions probably do too, XE just happens to be what I have running right now. (Edit Delphi 2007 also has it. 2007 & XE are the only versions of Delphi I have installed right now though, so I can't verify any other versions.)

afrazier
  • 4,784
  • 2
  • 27
  • 30
2
const
  InputBoxMessage = WM_USER + 200;
type
  TForm1 = class(TForm)
  ...
    procedure InputBoxSetPasswordChar(var Msg: TMessage); message InputBoxMessage;
    function GetPassword: String;
  ...
  end;
...
procedure TForm1.InputBoxSetPasswordChar(var Msg: TMessage);
var
  hInputForm, hEdit: HWND;
begin
  hInputForm := Screen.Forms[0].Handle;
  if (hInputForm <> 0) then
  begin
    hEdit := FindWindowEx(hInputForm, 0, 'TEdit', nil);
    SendMessage(hEdit, EM_SETPASSWORDCHAR, Ord('*'), 0);
  end;
end;

function TForm1.GetPassword: String;
begin
  PostMessage(Handle, InputBoxMessage, 0, 0);
  Result := InputBox('Title', 'Password:', '');
end;
Branko
  • 1,384
  • 1
  • 16
  • 35
0

I think you also need to set:

  Echomode := eemPassword

At least for TdlcxLabeledDBTextEdit.

Tone Škoda
  • 1,463
  • 16
  • 20
-1
procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if checkbox1.checked = true then
    edit1.passwordchar := '*'
   else
    edit1.PasswordChar := #0;
  end;
end;
Toribio
  • 3,963
  • 3
  • 34
  • 48
Wallace
  • 1
  • 1