Есть ли замена .Net для GetAsyncKeyState? - PullRequest
3 голосов
/ 25 сентября 2008

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

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

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

Ответы [ 2 ]

3 голосов
/ 25 сентября 2008

Вы можете найти объявление P / Invoke для GetAsyncKeyState от http://pinvoke.net/default.aspx/user32/GetAsyncKeyState.html

Вот подпись C #, например:

[DllImport("user32.dll")]
static extern short GetAsyncKeyState(int vKey);
1 голос
/ 25 сентября 2008

В зависимости от вашего желаемого использования, есть несколько вариантов, включая вызов того же метода, который описан выше). Из консольного приложения:

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...