2008-09-25 3 views
3

В VB6 я использовал вызов Windows API, GetAsyncKeyState, чтобы определить, нажал ли пользователь клавишу ESC, чтобы они могли выйти из длинного цикла.Есть ли замена .Net для GetAsyncKeyState?

Declare Function GetAsyncKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer 

Есть ли эквивалент в чистом .NET, который требует прямого вызова API?

ответ

1

В зависимости от требуемого использования Есть несколько вариантов, в том числе ссылаясь на то же самое как описано выше). из консольного приложения:

bool exitLoop = false; 
for(int i=0;i<bigNumber && !exitLoop;i++) 
{ 
    // Do Stuff. 
    if(Console.KeyAvailable) 
    { 
     // Read the key and display it (false to hide it) 
     ConsoleKeyInfo key = Console.ReadKey(true); 
     if(ConsoleKey.Escape == key.Key) 
     { 
      exitLoop=false; 
     } 
    } 
} 

Если вы работаете в форме окна, каждая форма имеет ряд связанных ключевых событий, которые вы можете прослушать и при необходимости отрегулировать (Упрощенные большую часть логики):

public partial class Form1 : Form 
{ 
    private bool exitLoop; 
    public Form1() 
    { 
     InitializeComponent(); 
     this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp); 
    } 
    public void doSomething() 
    { 
     // reset our exit flag: 
     this.exitLoop = false; 
     System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(delegate(object notUsed) 
      { 
       while (!exitLoop) 
       { 
        // Do something 
       } 
      })); 
    } 
    private void Form1_KeyUp(object sender, KeyEventArgs e) 
    { 
     if (Keys.Escape == e.KeyCode) 
     { 
      e.Handled = true; 
      this.exitLoop = true; 
     } 
    } 

} 

Обратите внимание, что это очень упрощено - он не обрабатывает какие-либо обычные проблемы с потоками или что-то в этом роде. Как отмечалось в комментариях, первоначальный раунд не затронул эту проблему, я добавил быстрый небольшой призыв ThreadPool для потоковой работы фона. Также обратите внимание, что проблема с прослушиванием ключевых событий заключается в том, что другие элементы управления могут их обрабатывать, поэтому вам нужно убедиться, что вы зарегистрировались для события на правильном контроле. Если приложение формы окна - это направление, в котором вы направляетесь, вы также можете попытаться ввести себя в сам цикл сообщений ...

public override bool PreProcessMessage(ref Message msg) 
{ 
    // Handle the message or pass it to the default handler... 
    base.PreProcessMessage(msg); 
} 
+0

Я не думаю, что это сработает, потому что событие KeyUp не собирается для запуска, когда выполняется цикл doSomething. – 2008-09-25 16:19:39