keybd_event: глобальные симуляции нажатий клавиш неожиданно появляются в C # Console - PullRequest
0 голосов
/ 27 апреля 2011

Что происходит, когда вы открываете консоль и удерживаете нажатой кнопку a в течение секунды?

Вывод будет лучше aaaaaaaa +- a few a's.Поэтому, когда я имитирую нажатие кнопки a и отпускание ее через секунду, я нахожу странным, что вывод этого кода:

static void Main(string[] args)
{
    keybd_event(0x41, 0, KEYEVENTF_KEYDOWN, 0);
    Thread.Sleep(1000);
    keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
    Console.ReadLine();
}

является единственным a.Хорошо, хорошо, я могу жить с этим.Я просто сделаю цикл, чтобы повторить это любое количество раз.Предположим, я хочу символ a 5 раз, я ожидаю, что будет достаточно следующего кода:

static void Main(string[] args)
{
    const int VK_A = 0x41;
    for (int i = 0; i < 5; i++)
    {
        keybd_event(VK_A, 0, KEYEVENTF_KEYDOWN, 0);
        keybd_event(VK_A, 0, KEYEVENTF_KEYUP, 0);
        Thread.Sleep(200);
    }
    Console.WriteLine("done");
    Thread.Sleep(4000);
    Console.ReadLine();
}

Я был удивлен, что на выходе получилось

done
aaaaa

Обратите внимание, что "done" до a, что я нахожу странным, и a появляются одновременно, когда достигается Console.ReadLine() .... как будто это утверждение вызывает появление букв .... Если вы хотите попробовать это самостоятельно, вам также необходимо:

[DllImport("user32.dll", EntryPoint = "keybd_event", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern void keybd_event(byte vk, byte bscan, uint flags, int extrainfo);
const int KEYEVENTF_KEYUP = 0x2;
const int KEYEVENTF_KEYDOWN = 0x0;

У меня точно такая же проблема с более новой функцией SendInput.Может кто-нибудь объяснить мне логику этого?

1 Ответ

0 голосов
/ 27 апреля 2011

Похоже, выходной буфер не сбрасывается между нажатиями клавиш. Здесь есть похожий пост:

C # или буфер очистки .NET

В сообщении указывается, что очистка клавиатуры на самом деле невозможна В Интернете есть несколько сообщений о том, как это сделать - большинство из них: http://myarticles -csharpnetstuff.blogspot.com / 2009/09 / tip-flush-keyboard-buffer-in-c.html

И использовать следующий метод (скопировано по ссылке):

private static void FlushKeyboard()
{
     while (Console.In.Peek() != -1)
         Console.In.Read();
}

Мне лично не нравится этот способ, потому что вы заканчиваете тем, что выполняете много ненужных операций чтения. Что именно вы пытаетесь сделать здесь? Действительно ли важно, чтобы строка «aaaa» появлялась перед «done»?

- Дан

...