Delphi InputBox for password entry?
Asked Answered
S

6

17

Inputbox:

answer:=Inputbox('a','b','c');

works good, but I'm looking for a masked one, like a password box where you only see little stars instead of the typed characters.

Slicer answered 26/2, 2009 at 16:32 Comment(0)
N
30

You can send a Windows message to the edit control created by InputBox, that will flag the edit control for password entry. Code below taken from http://www.swissdelphicenter.ch/en/showcode.php?id=1208:

const
   InputBoxMessage = WM_USER + 200;

type
   TForm1 = class(TForm)
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   private
     procedure InputBoxSetPasswordChar(var Msg: TMessage); message InputBoxMessage;
   public
   end;

var
   Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.InputBoxSetPasswordChar(var Msg: TMessage);
var
   hInputForm, hEdit, hButton: HWND;
begin
   hInputForm := Screen.Forms[0].Handle;
   if (hInputForm <> 0) then
   begin
     hEdit := FindWindowEx(hInputForm, 0, 'TEdit', nil);
     {
       // Change button text:
       hButton := FindWindowEx(hInputForm, 0, 'TButton', nil);
       SendMessage(hButton, WM_SETTEXT, 0, Integer(PChar('Cancel')));
     }
     SendMessage(hEdit, EM_SETPASSWORDCHAR, Ord('*'), 0);
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   InputString: string;
begin
   PostMessage(Handle, InputBoxMessage, 0, 0);
   InputString := InputBox('Input Box', 'Please Enter a Password', '');
end;
Nihilism answered 26/2, 2009 at 18:6 Comment(2)
Wow! elegant way to defer execution :-)Jadwiga
This might be a dump question, but how do you know Screen.Forms[0] is the form created by InputBox?Cavalla
F
43

In XE2, InputBox() and InputQuery() were updated to natively support masking the TEdit input, although that feature has not been documented yet. If the first character of the APrompt parameter is set to any value < #32 then the TEdit.PasswordChar will be set to *, eg:

answer := InputBox('a', #31'b', 'c');
Flickertail answered 14/1, 2014 at 20:2 Comment(2)
Now that's intuitive!Pelmas
They went to the trouble of expanding InputQuery() (which InputBox() uses internally) with new parameters for multi-prompts and an OnCloseQuery callback, but they couldn't be bothered to create a new parameter for specifying password masking? The multi-prompts support per-prompt masking, but they could have made that interface more intuitive. Instead of using an array of strings with special lead characters, they should have used an array of records containing string/mask pairs. That would even have allowed future fields to be added for finer control over the TEdit controls. But nope.Flickertail
N
30

You can send a Windows message to the edit control created by InputBox, that will flag the edit control for password entry. Code below taken from http://www.swissdelphicenter.ch/en/showcode.php?id=1208:

const
   InputBoxMessage = WM_USER + 200;

type
   TForm1 = class(TForm)
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   private
     procedure InputBoxSetPasswordChar(var Msg: TMessage); message InputBoxMessage;
   public
   end;

var
   Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.InputBoxSetPasswordChar(var Msg: TMessage);
var
   hInputForm, hEdit, hButton: HWND;
begin
   hInputForm := Screen.Forms[0].Handle;
   if (hInputForm <> 0) then
   begin
     hEdit := FindWindowEx(hInputForm, 0, 'TEdit', nil);
     {
       // Change button text:
       hButton := FindWindowEx(hInputForm, 0, 'TButton', nil);
       SendMessage(hButton, WM_SETTEXT, 0, Integer(PChar('Cancel')));
     }
     SendMessage(hEdit, EM_SETPASSWORDCHAR, Ord('*'), 0);
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   InputString: string;
begin
   PostMessage(Handle, InputBoxMessage, 0, 0);
   InputString := InputBox('Input Box', 'Please Enter a Password', '');
end;
Nihilism answered 26/2, 2009 at 18:6 Comment(2)
Wow! elegant way to defer execution :-)Jadwiga
This might be a dump question, but how do you know Screen.Forms[0] is the form created by InputBox?Cavalla
S
9

InputBox calls the InputQuery function in Dialogs, which creates the form dynamically. You could always make a copy of this function and change the TEdit's PasswordChar property.

Sandeesandeep answered 26/2, 2009 at 17:24 Comment(0)
P
3

I don't think that Delphi includes such a thing out of the box. Maybe you can find one at http://www.torry.net/ or elsewhere in the net. Otherwise just write one yourself - shouldn't be that hard. :-) You can even look at the source code if you have a "big enough" Delphi version.

Uli.

Pelmas answered 26/2, 2009 at 17:18 Comment(0)
C
1

In case someone still needs a simple solution, here it is:

InputQuery('MyCaption', #0 + 'MyPrompt', Value); // <-- the password char '*' is used

That works because the InputQuery function has the following nested function:

function GetPasswordChar(const ACaption: string): Char;
begin
  if (Length(ACaption) > 1) and (ACaption[1] < #32) then
    Result := '*'
  else
    Result := #0;
end;

And it's called for every prompt:

PasswordChar := GetPasswordChar(APrompts[I]);

Therefore, if the first character in the APrompts is < #32 (ex. #0), the password char of the TEdit will be '*'.

Tested on Delphi 10.4. I'm not sure when was this introduced, I skipped from D6 straight to 10.4 and haven't tested on D6.

Canticle answered 17/12, 2021 at 10:4 Comment(0)
J
0

You can use InputQuery instead of InputBox. When the TRUE argument is set, password field will be masked.

InputQuery('Authenticate', 'Password:',TRUE, value);     

Some resource here; http://lazarus-ccr.sourceforge.net/docs/lcl/dialogs/inputquery.html

Jabe answered 27/7, 2018 at 10:15 Comment(1)
Note: Does not work for Delphi. Seems to be a Lazarus-Only thing.Predicant

© 2022 - 2024 — McMap. All rights reserved.