2010-09-08 4 views
8

J'écris une application console à l'aide de BDE 2006 et je souhaite qu'elle puisse demander une chaîne de mot de passe et la masquer avec "*" lorsque l'utilisateur tape. J'ai regardé autour mais je ne pourrais pas trouver des exemples de comment faire ceci. Tout ce que j'ai vu était comment le faire dans TEdit. Des conseils sur la façon d'accomplir cela?Saisie d'un mot de passe de masque dans une application de console

Merci à l'avance,

Nic

+0

si vous ne comptez pas utiliser un TEdit, quel contrôle voulez-vous utiliser pour l'utilisateur de saisir le nom d'utilisateur et mot de passe? – Leslie

+2

Dans une fenêtre de console. Il le mentionne. – zz1433

Répondre

8

est ici une solution de travail:

program Project2; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils, Windows; 

function GetPassword(const InputMask: Char = '*'): string; 
var 
    OldMode: Cardinal; 
    c: char; 
begin 
    GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), OldMode); 
    SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), OldMode and not (ENABLE_LINE_INPUT or ENABLE_ECHO_INPUT)); 
    try 
    while not Eof do 
    begin 
     Read(c); 
     if c = #13 then // Carriage Return 
     Break; 
     Result := Result + c; 
     if c = #8 then // Back Space 
     Write(#8) 
     else 
     Write(InputMask); 
    end; 
    finally 
    SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), OldMode); 
    end; 
end; 

begin 
    try 
    Writeln(Format(sLineBreak + 'pswd=%s',[GetPassword])); 
    Readln; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 

Mise à jour: Notez que le code ci-dessus traite les backspaces visuellement, mais les garde incorporé dans le mot de passe, ce qui pourrait ne pas être ce que vous voulez.
Dans ce cas, le code suivant les filtrer:

if c = #13 then // Carriage Return 
    Break; 
    if (c = #8) and (Length(Result) > 0) then // Back Space 
    begin 
    Delete(Result, Length(Result), 1); 
    Write(#8); 
    end 
    else 
    begin 
    Result := Result + c; 
    Write(InputMask); 
    end; 
+0

N'est-il pas plus facile de ne pas ajouter # 8 en déplaçant 'result: = result + c' à la clause else, au lieu de l'ajouter en premier, puis de le supprimer? –

+0

vous voudrez supprimer le caractère précédent s'ils font un retour arrière. –

+0

Ah, oui, je vois ce que tu veux dire. –

2

Cela fonctionne.

program Project2; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils, Windows; 

const 
    BUF_LEN = 1024; 

var 
    amt, i, cmode: cardinal; 
    buf: packed array[0..BUF_LEN - 1] of char; 

begin 
    try 

    Write('Enter password: '); 
    GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), cmode); 
    SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), cmode and not ENABLE_ECHO_INPUT); 
    ReadConsole(GetStdHandle(STD_INPUT_HANDLE), @buf[0], BUF_LEN, amt, nil); 
    SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), cmode); 

    Writeln; 
    Writeln; 

    Writeln('You entered: '); 
    for i := 0 to amt - 3 do 
     Write(buf[i]); 
    Writeln; 
    Writeln; 

    Writeln('Done'); 
    Readln; 

    except 
    on E:Exception do 
    begin 
     Writeln(E.Classname, ': ', E.Message); 
     Readln; 
    end; 
    end; 
end. 
Questions connexes