problema Sendkeys da programma .NET
Domanda
il codice qui sotto ho copiato da MSDN con un po 'di modifica:
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
DllImport("User32")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
int cnt = 0;
private void button1_Click(object sender, EventArgs e)
{
IntPtr calculatorHandle = FindWindow("Notepad", "Untitled - Notepad");
if (calculatorHandle == IntPtr.Zero)
{
MessageBox.Show("Calculator is not running.");
return;
}
SetForegroundWindow(calculatorHandle);
SendKeys.SendWait(cnt.ToString());
SendKeys.SendWait("{ENTER}");
cnt++;
SendKeys.Flush();
System.Threading.Thread.Sleep(1000);
}
Il problema è la sequenza numero nel blocco note non è continuo. Il primo clic si traduce sempre 0 (come previsto). ma dal secondo clic, il risultato è imprevedibile (ma la sequenza è ancora in ordine, ad esempio 3, 4, 5, 10, 14, 15, ....)
Se si fa clic sul pulsante di abbastanza veloce, sono stato in grado di ottenere il risultato in ordine continuo (0,1,2,3,4, ....), ma a volte produce più di 2 stessi numeri (ad esempio 0, 1,2,3,3,3,4,5,6,6,6,7,8,9, ...)
Soluzione
Il SetForegroundWindow
non ha intenzione di aspettare fino a quando la finestra specificata è in realtà in primo piano. Solo che "prende il via" il processo. Quindi è molto probabile che il vostro SendKeys.SendWait
non sta inviando la chiave per la finestra che ci si aspetta che sia.
Un altro problema, non proprio in relazione a quello che stiamo vedendo è che hai una chiamata al Thread.Sleep
nel vostro gestore di eventi. Questo è generalmente considerato una cattiva pratica: non si dovrebbe bloccare il thread dell'interfaccia utente. Rende l'applicazione appaiono non risponde.
Altri suggerimenti
Il primo problema si verifica perché SetForegroundWindow
può restituire prima della messa a fuoco è stato acceso, così Sendkeys
potrebbe eseguito quando notepad non è attivo.