Как симулировать удерживаемые клавиши с помощью VB.NET или C #?

Как я могу отправить ключи в другое приложение, чтобы они удерживались? Я хочу что-то вроде

keystate(keys.A) = down (удерживать кнопку)

а также

keystate(keys.A) = up (отпустить кнопку)

мне все равно, если его C # или Visual Basic я их знаюиспользуя визуальную студию
 Jon15 июл. 2016 г., 19:06
В цикле Update () игры вы можете проверить состояние ключа и соответственно переместить автомобиль.
 Ares15 июл. 2016 г., 19:12
Есть много игр, которые тупо требуют от вас удерживать клавиши. Или, может быть, он хочет автоматизировать использование приложения. В любом случае я подробно описал оба возможных случая, повторяющиеся клавиши и удерживаемые клавиши.
 Ares15 июл. 2016 г., 19:07
@Mangist Что-то говорит мне, что это не для его собственной игры. Он пытается отправить нажатия клавиш в другую игру.
 Jon15 июл. 2016 г., 19:11
@ Возможно, вы правы, но не знаете, какова будет цель.

Ответы на вопрос(3)

Решение Вопроса

SendKeys.Send

https://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send(v=vs.110).aspx

Если хотитеудерживать ключи, вам нужно импортировать вызов библиотеки User32:

Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)

Вам также понадобится MapVirtualKey. Это передает раскладку ключей на вашей физической плате (ориентированную на драйвер) в виртуальный набор ключей, который не зависит от аппаратного обеспечения (ориентирован на программное обеспечение).

<DllImport("User32.dll", SetLastError:=False, CallingConvention:=CallingConvention.StdCall, _
       CharSet:=CharSet.Auto)> _
Public Shared Function MapVirtualKey(ByVal uCode As UInt32, ByVal uMapType As MapVirtualKeyMapTypes) As UInt32
End Function

Затем просто сделайте что-то вроде этого:

Private Sub HoldKeyDown(ByVal key As Byte, ByVal durationInSeconds As Integer)
    Dim targetTime As DateTime = DateTime.Now().AddSeconds(durationInSeconds)
    keybd_event(key, MapVirtualKey(key, 0), 0, 0) ' Down
    While targetTime.Subtract(DateTime.Now()).TotalSeconds > 0
        Application.DoEvents()
    End While
    keybd_event(key, MapVirtualKey(key, 0), 2, 0) ' Up
End Sub
 Ares15 июл. 2016 г., 19:27
Imports System.Runtime.InteropServices это то, что вам нужно
 123neri12315 июл. 2016 г., 19:42
работа спасибо !!!
 Ares15 июл. 2016 г., 20:07
Я согласен, что это решение имеет недостатки, но, учитывая сложность введения другого потока, я думаю, что это будет работать для целей аскера.
 Ares15 июл. 2016 г., 19:26
Просто поместите эти два метода в начало вашего класса. Возможно, вам придется сделать несколько импортов, чтобы заставить его работать.
 Ares15 июл. 2016 г., 19:17
Я обновил это. Пожалуйста, не забудьте пометить это как принятое, если это сработало для вас.
 Visual Vincent15 июл. 2016 г., 20:12
Нету. Все обрабатывается одинаково (обработчик событий все еще метод).
 123neri12315 июл. 2016 г., 19:32
действительно спасибо за вашу помощь, все еще есть некоторые проблемы, такие как keybd_event (key, MapVirtualKey (key, error), 0, 0) 'Вниз * проблема в ошибке, ее 0 и его значение int не может измениться ..
 123neri12315 июл. 2016 г., 19:25
Можете ли вы объяснить мне, где я помещаю часть DllImport?
 Visual Vincent15 июл. 2016 г., 20:09
Это не так сложно на самом деле. Вы можете даже использовать лямбды ради простоты, если вы / OP используете .NET 4.0 или выше. Дело в том, что это, скорее всего, израсходует много ресурсов процессора, тем более что задержки нет, иDoEvents() вызов может вызвать проблемы. --- Кроме того, это довольно хорошее решение! Хорошая работа!
 Ares15 июл. 2016 г., 19:35
Вы должны оставить это как ноль. Если вы хотите изменить, какой ключ изменяется, передайте другойkey в функцию.
 123neri12315 июл. 2016 г., 19:14
MapVirtualKey?
 Visual Vincent15 июл. 2016 г., 20:05
Ты не должен звонитьApplication.DoEvents() чтобы приложение оставалось отзывчивым. Вместо этого используйте поток или задачу.
 Ares15 июл. 2016 г., 20:11
Поведение было бы другим, если бы это было вызвано событием? Например, если это было в методе, обрабатывающем событие OnClick.

(Visul Studio) код

Imports System..InteropServices

Public Class Form1
    Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)


    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    End Sub

    <DllImport("User32.dll", SetLastError:=False, CallingConvention:=CallingConvention.StdCall, _
           CharSet:=CharSet.Auto)> _
    Public Shared Function MapVirtualKey(ByVal uCode As UInt32, ByVal uMapType As UInt32) As UInt32
    End Function

    Private Sub HoldKeyDown(ByVal key As Byte, ByVal durationInSeconds As Integer)
        Dim targetTime As DateTime = DateTime.Now().AddSeconds(durationInSeconds)
        keybd_event(key, MapVirtualKey(key, 0), 0, 0) ' Down
        While targetTime.Subtract(DateTime.Now()).TotalSeconds > 0
            Application.DoEvents()
        End While
        keybd_event(key, MapVirtualKey(key, 0), 2, 0) ' Up
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        HoldKeyDown(Keys.A, 5)
    End Sub
End Class

которая будет перемещать автомобиль по форме, основываясь на нажатых на клавиатуре клавишах влево / вправо / вверх / вниз. Я установил цикл обновления игры на 30 кадров в секунду, но вы можете изменить это с помощью другого Thread.Sleep ():

в моей форме есть метка "lblCar", положение которой я перемещаю в каждом цикле обновления игры.

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(GameUpdate));
        }

        private bool leftPressed;
        private bool rightPressed;
        private bool upPressed;
        private bool downPressed;

        private void GameUpdate(object state)
        {
            bool gameRunning = true;

            do
            {
                if (leftPressed)
                {
                    BeginInvoke(new Action(() => { lblCar.Location = new Point(lblCar.Location.X - 1, lblCar.Location.Y); }));
                }
                if (rightPressed)
                {
                    BeginInvoke(new Action(() => { lblCar.Location = new Point(lblCar.Location.X + 1, lblCar.Location.Y); }));
                }
                if (upPressed)
                {
                    BeginInvoke(new Action(() => { lblCar.Location = new Point(lblCar.Location.X, lblCar.Location.Y - 1); }));
                }
                if (downPressed)
                {
                    BeginInvoke(new Action(() => { lblCar.Location = new Point(lblCar.Location.X, lblCar.Location.Y + 1); }));
                }

                Thread.Sleep(33); // 30 frames per second
            } while (gameRunning);
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Left: leftPressed = true; break;
                case Keys.Right: rightPressed = true; break;
                case Keys.Up: upPressed = true; break;
                case Keys.Down: downPressed = true; break;
                default: break;
            }
        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Left: leftPressed = false; break;
                case Keys.Right: rightPressed = false; break;
                case Keys.Up: upPressed = false; break;
                case Keys.Down: downPressed = false; break;
                default: break;
            }
        }
    }

Ваш ответ на вопрос