2010-09-08 8 views
8

Estoy escribiendo una aplicación de consola usando BDE 2006 y quiero que pueda solicitar una cadena de contraseña y enmascararla con "*" mientras el usuario escribe. He buscado pero no he podido encontrar ejemplos de cómo hacerlo. Todo lo que vi fue cómo hacer esto en TEdit. ¿Alguna sugerencia sobre cómo lograr esto?Entrada de máscara de contraseña en una aplicación de consola

Gracias de antemano,

Nic

+0

si no se va a utilizar un TEdit, lo que el control es lo que desea utilizar para el usuario que escriba el nombre de usuario y contraseña? – Leslie

+2

En una ventana de consola. Él lo menciona. – zz1433

Respuesta

8

Aquí es una solución de trabajo:

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. 

actualización: Tenga en cuenta que el código anterior se encarga de las teclas de retroceso visualmente, pero los mantiene incrustada en la contraseña, que podría no ser lo que quieres.
En ese caso el siguiente código filtrarlos:

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

¿No es más fácil simplemente no agregar el # 8 moviendo 'result: = result + c' a la cláusula else, en lugar de agregarlo primero y luego eliminarlo? –

+0

querrá eliminar el carácter anterior si hacen un retroceso. –

+0

Ah, sí, ya veo lo que quieres decir. –

2

Esto funciona.

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. 
Cuestiones relacionadas