2010-04-09 5 views
0

Приведенный ниже код я скопирован с MSDN с небольшим количеством модификации:SendKeys проблема с .NET программы

[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); 
} 

Проблема заключается порядковый номер в блокноте не является непрерывно. Первый щелчок всегда показывает 0 (как и ожидалось). но из второго щелчка результат непредсказуем (но последовательность все еще в порядке, например, 3, 4, 5, 10, 14, 15, ....)

Если я нажимаю кнопку достаточно быстро, я смог получить результат в непрерывном порядке (0,1,2,3,4, ....), но иногда он производит более двух одинаковых чисел (например, 0,1,2,3,3,3,4, 5,6,6,6,7,8,9, ...)

+0

Удалите вызов Sleep(), я не могу заставить его потерпеть неудачу, не уйдя. –

ответ

2

SetForegroundWindow не собирается ждать, пока указанное окно окажется на переднем плане. Это просто «начинает» процесс. Поэтому вполне возможно, что ваш SendKeys.SendWait не отправляет ключ в окно, которое вы ожидаете от него.

Другая проблема, не совсем связанная с тем, что вы видите, заключается в том, что у вас есть вызов Thread.Sleep в обработчике событий. Это обычно считается плохой практикой: вы не должны блокировать поток пользовательского интерфейса. Это делает ваше приложение неприемлемым.

+0

Вы и SLaks правы с помощью SetForegroundWindow(). Если я переместил Sleep() сразу после SetForegroundWindow(), все будет хорошо. О Sleep() и UI, если я удалю sleep() после SetForegroundWindow(), как это сделать правильно? – user397232

+0

Лучший способ сделать это, я думаю, будет на фоновом потоке. Остановите операцию с BackgroundWorker, которая выполняет обработку в другом потоке. Таким образом, вы можете делать все сон() и все, что вам нужно, и никогда не связывает поток пользовательского интерфейса. Вам просто понадобится немного дополнительной логики в обработчике «Click», чтобы он не пытался запустить новый запрос до тех пор, пока предыдущий не завершится. –

1

Первая проблема возникает из-за того, что SetForegroundWindow может вернуться до того, как фокус был переключен, поэтому Sendkeys может работать, когда блокнот не активен.

Смежные вопросы