0

I want to write a program in C# where I first set a hotkey and then start it by button. After that I want to tab into a game (focus on the game) and press my hotkey in the game. This should be recognized by my Windows Forms and then send keystrokes to the game.

For example: I start my Windows Forms, set the hotkey to CTRL and press the button "Start". The event KeyDown of my StartButton is now active. I tab into my game and when I press my hotkey CTRL, I want it to press "wasd" in the game, for example, every time I press my hotkey.

My problem: I have tried extremely hard and can't get it to catch while I am in the game my hotkey. I press CTRL, but my Windows Forms application doesn't get it.

GetForegroundWindow() == _gameWindowHandle

is always false. But I do not understand why.

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace SendKeystrokesTry
{
    public partial class MainForm : Form
    {
        private const int WM_KEYDOWN = 0x0100;
        private const int WM_KEYUP = 0x0101;
        private Keys _hotkey;
        private bool _enabled = false;
        private Process _gameProcess = Process.GetProcessesByName("notepad++").FirstOrDefault();
        private IntPtr _gameWindowHandle;

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        [DllImport("user32.dll")]
        private static extern IntPtr PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);


        public MainForm()
        {
            InitializeComponent();
        }

        private void btnSetHotkey_Click(object sender, EventArgs e)
        {
            this.KeyPreview = true;
            this.KeyDown += new KeyEventHandler(btnSetHotkey_KeyDown); // Hinzufügen des neuen Event-Handlers
        }


        private void btnSetHotkey_KeyDown(object sender, KeyEventArgs e)
        {
            if (this._hotkey != Keys.None) // Hotkey gesetzt
            {
                this.KeyDown -= new KeyEventHandler(btnSetHotkey_KeyDown);
                this.KeyPreview = false;
            }
            else // Hotkey nicht gesetzt
            {
                this._hotkey = e.KeyCode;
                tbHotkey.Text = this._hotkey.ToString();
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (this._hotkey != Keys.None)
            {
                this._enabled = true;
                this.KeyPreview = true;
                this.KeyDown += new KeyEventHandler(btnStart_KeyDown); // Hinzufügen des neuen Event-Handlers

                if (this._gameProcess != null)
                {
                    this._gameWindowHandle = this._gameProcess.MainWindowHandle;
                    tbContent.Text = _gameProcess.ToString();
                }
                else
                {
                    MessageBox.Show("The game process was not found.");
                    this.Close();
                }
            }
        }

        private void btnStart_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == this._hotkey)
            {
                HandleHotkey();
            }
        }

        private void HandleHotkey()
        {

            if (this._enabled && GetForegroundWindow() == _gameWindowHandle)
            {
                SendMessage(_gameWindowHandle, WM_KEYDOWN, (IntPtr)Keys.W, IntPtr.Zero);

                Thread.Sleep(1000);

                SendMessage(_gameWindowHandle, WM_KEYUP, (IntPtr)Keys.W, IntPtr.Zero);
            }
        }
    }
}

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
goat
  • 9
  • 1
  • 1
    The problem is that you need the key to to go a Window handle that may not just be the Application Window. For example in notepad you have to have the window handle of the Text Component. – Erik Philips Apr 13 '23 at 08:23

0 Answers0