C# 向游戏窗口发送键盘宏命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/407020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 02:10:59  来源:igfitidea点击:

Sending Keyboard Macro Commands to Game Windows

c#apikeyboardsendkeys

提问by

I wanna do a macro program for a game. But there is a problem with sending keys to only game application (game window). I am using keybd_eventAPI for sending keys to game window. But I only want to send keys to the game window, not to explorer or any opened window while my macro program is running. When I changed windows its still sending keys. I tried to use Interaction.Appwith Visual Basic.dllreference. But Interaction.Apponly Focus the game window.

我想做一个游戏的宏程序。但是仅将密钥发送到游戏应用程序(游戏窗口)存在问题。我正在使用keybd_eventAPI 将密钥发送到游戏窗口。但是我只想将键发送到游戏窗口,而不是在我的宏程序运行时发送到资源管理器或任何打开的窗口。当我更改 Windows 时,它仍在发送密钥。我试图使用Interaction.AppVisual Basic.dll参考。但Interaction.App只聚焦游戏窗口。

I couldn't find anything about my problem. Can anyone help me? Thanx

我找不到任何关于我的问题的信息。谁能帮我?谢谢

回答by Tom Anderson

Are you retrieving the handle of the window all the time, or are you remembering it?

您是一直在检索窗口的句柄,还是在记住它?

If you use the FindWindow() API, you can simply store the Handle and use the SendMessage API to send key/mouse events manually.

如果您使用 FindWindow() API,您可以简单地存储句柄并使用 SendMessage API 手动发送键/鼠标事件。

回答by Lasse V. Karlsen

If you want to communicate with a game, you typically will have to deal with DirectInput, not the normal keyboard API's.

如果您想与游戏进行通信,您通常必须处理 DirectInput,而不是普通的键盘 API。

回答by Tom Anderson

FindWindow API:
http://www.pinvoke.net/default.aspx/user32.FindWindowEx

FindWindow API:http://www.pinvoke.net/default.aspx/user32.FindWindowEx

SendMessage API:
http://www.pinvoke.net/default.aspx/user32/SendMessage.html

SendMessage API:http:
//www.pinvoke.net/default.aspx/user32/SendMessage.html

VB

VB

Private Const WM_KEYDOWN As Integer = &H100
Private Const WM_KEYUP As Integer = &H101

C#

C#

private static int WM_KEYDOWN = 0x100
private static int WM_KEYUP = 0x101

回答by Tom Anderson

class SendKeySample
{
    private static Int32 WM_KEYDOWN = 0x100;
    private static Int32 WM_KEYUP = 0x101;

    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("user32.dll", SetLastError = true)]
    static extern bool PostMessage(IntPtr hWnd, int Msg, System.Windows.Forms.Keys wParam, int lParam);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

    public static IntPtr FindWindow(string windowName)
    {
        foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
        {
            if (p.MainWindowHandle != IntPtr.Zero && p.MainWindowTitle.ToLower() == windowName.ToLower())
                return p.MainWindowHandle;
        }

        return IntPtr.Zero;
    }

    public static IntPtr FindWindow(IntPtr parent, string childClassName)
    {
        return FindWindowEx(parent, IntPtr.Zero, childClassName, string.Empty);
    }

    public static void SendKey(IntPtr hWnd, System.Windows.Forms.Keys key)
    {
        PostMessage(hWnd, WM_KEYDOWN, key, 0);

    }
}

Calling Code

呼叫代码

        var hWnd = SendKeySample.FindWindow("Untitled - Notepad");
        var editBox = SendKeySample.FindWindow(hWnd, "edit");

        SendKeySample.SendKey(editBox, Keys.A);

回答by Tom Anderson

i fixed my problem. in this field ;

我解决了我的问题。在这个领域里 ;

PostMessage(hWnd, WM_KEYDOWN, key, {have to give lParam of the key});

PostMessage(hWnd, WM_KEYDOWN, key, {必须给出键的 lParam});

otherwise it does not work.And we can control of ChildWindow Class with Spy++ tool of Microsoft.

否则它不起作用。我们可以用微软的Spy++工具控制ChildWindow类。

Thanks everyone for helping.

感谢大家的帮助。