简体   繁体   English

GetAsyncKeyState是否有.Net替换?

[英]Is there .Net replacement for GetAsyncKeyState?

In VB6, I used a call to the Windows API, GetAsyncKeyState , to determine if the user has hit the ESC key to allow them to exit out of a long running loop. 在VB6中,我使用了对Windows API GetAsyncKeyState的调用来确定用户是否已经按下ESC键以允许它们退出长时间运行的循环。

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

Is there an equivalent in pure .NET that does require a direct call to the API? 在纯.NET中是否存在需要直接调用API的等效项?

You can find the P/Invoke declaration for GetAsyncKeyState from http://pinvoke.net/default.aspx/user32/GetAsyncKeyState.html 您可以从http://pinvoke.net/default.aspx/user32/GetAsyncKeyState.html找到GetAsyncKeyState的P / Invoke声明。

Here's the C# signature for example: 以下是C#签名:

[DllImport("user32.dll")]
static extern short GetAsyncKeyState(int vKey);

Depending on your desired use there are a couple of options, including invoking the same method as described above). 根据您的需要,有几个选项,包括调用与上述相同的方法。 From a console app: 从控制台应用程序:

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

If you are working on a windows form, every form has a number of key related events you can listen to and handle as necessary (Simplified most of the logic): 如果您正在处理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;
        }
    }

}

Note that this is very simplified - it doesn't handle any of the usual threading issues or anything like that. 请注意,这非常简单 - 它不处理任何常见的线程问题或类似的问题。 As was pointed out in the comments, the original go-round didn't address that problem, I added a quick little ThreadPool call to thread the background work. 正如评论中指出的那样,原始的回合没有解决这个问题,我添加了一个快速的小ThreadPool调用来处理后台工作。 Also note, that the problem with listening for the key events is that other controls may actually handle them, so you need to make sure that you register for the event on the correct control(s). 另请注意,侦听键事件的问题是其他控件实际上可能会处理它们,因此您需要确保在正确的控件上注册事件。 If a windows form application is the direction you are heading, you can also attempt to inject yourself into the message loop itself... 如果Windows窗体应用程序是您前进的方向,您还可以尝试将自己注入消息循环本身...

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM