2008-09-25 100 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; 
     } 
    } 
} 

如果您在Windows窗体上的工作,各种形式都有一批重点相关的事件,你可以听,并根据需要处理(最简化的逻辑):

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调用来进行后台工作。还要注意,监听关键事件的问题在于其他控件可能实际处理它们,因此您需要确保您在正确的控件上注册该事件。如果一个Windows窗体应用程序是你的方向,你也可以尝试注入自己的消息循环本身...

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