Вопрос

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

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

Есть ли эквивалент в чистом виде ?СЕТЬ, для которой требуется прямой вызов API?

Это было полезно?

Решение

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

Вот, например, сигнатура C #:

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

Другие советы

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

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 Form, вы также можете попытаться внедриться в сам цикл обмена сообщениями...

public override bool PreProcessMessage(ref Message msg)
{
  // Handle the message or pass it to the default handler...
  base.PreProcessMessage(msg);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top