2015-04-19 9 views
5

Ho un'applicazione winform ScreenLocker. È a schermo intero e trasparente. Sblocca lo schermo quando l'utente preme Ctrl+Alt+Shift+P.Tieni traccia se un utente ha digitato una "parola" specifica su un WinForm

Ma lo voglio più dinamico. Vorrei lasciare che un utente impostasse la propria password in un file di configurazione.

Ad esempio, ha impostato la password mypass. Il mio problema è: come posso verificare se ha digitato "Mypass" su quel modulo?

Non desidero avere alcuna casella di testo o pulsante sul modulo. Aiuto per favore.

Ecco il mio attuale code-

public frmMain() 
    { 
     InitializeComponent(); 
     this.KeyPreview = true; 

     this.WindowState = FormWindowState.Normal; 
     this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
     this.Bounds = Screen.PrimaryScreen.Bounds; 
     this.ShowInTaskbar = false; 
     double OpacityValue = 4.0/100; 
     this.Opacity = OpacityValue; 
    } 

    private void OnKeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.P && e.Modifiers == (Keys.Control | Keys.Shift | Keys.Alt)) 
     { 
      this.Close(); 
     } 
    } 
+0

Perché non mostrano semplicemente una casella di testo e il pulsante quando l'utente preme 'Ctrl + Alt + Maiusc + P', e lo hanno inserire la sua password lì? –

+0

Non sono un esperto in materia, ma mi sembra che la struttura di estensione reattiva possa essere utile per risolvere il tuo problema. Vedi questo articolo https://blogs.endjin.com/2014/04/event-stream-manipulation-using-rx-part-1/ –

+0

Come fermerai l'utente premendo Ctrl + alt + del e uccidendo il tuo programma di blocco dello schermo? –

risposta

2

È possibile memorizzare le lettere digitate in una variabile, quindi controllare su Inserisci evento keydown. Ecco il lavoro Sample-

public partial class Form1 : Form 
{ 

    String pass = String.Empty; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_KeyPress(object sender, KeyPressEventArgs e) 
    { 
     string value = e.KeyChar.ToString(); 
     pass += value; 
    } 

    private void Form1_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode==Keys.Enter) 
     { 
      //Now check the password with your config file. 
      //You may have to reset the variable if the pass does not match with the config. 
     } 
    } 
} 
+0

grazie. Penso che sia il più semplice, anche se pienamente funzionante. +1 –

+0

Non funziona se l'utente preme alcuni altri tasti e quindi la password corretta. Dai un'occhiata alla soluzione che ho fornito. –

+0

@PaoloCosta Perché dovrebbe? dì che la tua password è Paolo. staresti bene con qualcuno che accedesse al tuo computer digitando aHbarthAbat ** Paolo ** Hargh? –

0

Questo è il lavoro

public partial class LockScreen : Form 
{ 
Timer checkTimer; 
string curPass = ""; 
string pass = "mypass"; // take it from your config file 
public LockScreen() 
{ 
    InitializeComponent(); 
    this.KeyPreview = true; 

    this.WindowState = FormWindowState.Normal; 
    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
    this.Bounds = Screen.PrimaryScreen.Bounds; 
    this.ShowInTaskbar = false; 
    double OpacityValue = 4.0/100; 
    this.Opacity = OpacityValue; 

    // Add a keypress event 
    this.KeyPress += LockScreen_KeyPress; 

    checkTimer = new Timer(); 
    checkTimer.Interval = 1000; 
    checkTimer.Tick += checkTimer_Tick; 
} 

void LockScreen_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    checkTimer.Stop(); 
    curPass += e.KeyChar.ToString(); 

    if (curPass == pass)  
     this.Close(); 
    else 
     checkTimer.Start(); 
} 

void checkTimer_Tick(object sender, EventArgs e) 
{ 
    curPass = ""; //resets every second 
} 
} 
+0

Cosa succede se l'utente non può digitare la sua password entro un secondo? Mi piace usare il timer, ma penso che dovrebbe essere un po 'più lungo. –

+0

non è necessario digitare l'intera password in un secondo. Dovrebbe almeno premere un tasto in un secondo – Sayka

+0

riavviando il timer, andrà di nuovo per altri 1000 ms. – Sayka

0
private const string Password = "Foobar"; 
private readonly StringBuilder _builder = new StringBuilder(); 

private void LockForm_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    //Check if the key pressed is a control character (e.g. alt/enter et cetera) 
    //and return if that is the case 
    //Also make sure to reset the stringbuilder's buffer now and then, 
    //if too much input is generated 
    _builder.Append(e.KeyChar); 

    if (_builder.ToString().EndsWith(Password)) 
    { 
     //Correct password has been entered 
    } 
} 
+0

È solo una password, che un umano non è andando a memorizzare tenendolo lungo 1024. Troppo input per un computer in questo caso può essere più di un milione. – Sayka

+0

@Sayka È solo una nota che ho aggiunto per l'OP da considerare; è molto probabile che questo non sarebbe mai diventato un problema, ma perché mantenere una stringa enorme quando guarderai solo gli ultimi X caratteri di esso? –

2

Penso che la soluzione più elegante e robusto è quello di utilizzare il framework di estensione reattiva.

PM> Install-Package Rx-Main 

I tasti premuti vengono memorizzati in una sequenza osservabile bufferizzata. Quando il buffer corrisponde alla password viene presa un'azione (nell'esempio si tratta di una finestra di messaggio)

private void Form1_Load(object sender, EventArgs e) 
    { 
     string password = "test"; 
     var keypressed = Observable.FromEventPattern<KeyPressEventHandler, KeyPressEventArgs>(
       handler => handler.Invoke, 
       h => this.KeyPress += h, 
       h => this.KeyPress -= h); 


     var keyDownSequence = keypressed.Select(p => p.EventArgs.KeyChar); 

     var checkPasswordSequence = from n in keyDownSequence.Buffer(password.Length, 1) 
            where string.Join("", n.ToArray()) == password 
            select n; 

     checkPasswordSequence.Subscribe(x => MessageBox.Show(string.Join("", x.ToArray()))); 
    } 
Problemi correlati