C# – Send keys spacebar to windows

When I wrote a bot for game online to buff blood and mana when I let my character auto play. To buff blood and mana, we can put blood and mana item into shortcut key and press this short key to use item. Therefore we can come to the idea that we can make an auto buff blood and mana tool. The main idea consists of these steps:
– Read information of blood and mana from memory of process game.
– If value is smaller than a threshold, then send short-key, which is relevant to blood and mana items, to the game windows
To read information of character you can use Cheat Engine to locate the memory address and read info out and it’s not the theme of this blog. Maybe I will discuss this theme later in another blog. In this blog, I would like to discuss only about how we send keys to game. Normally, we can use SendKeys.Send command but for some games, this command does not work. In this example, I would like to use PostMessage API to send key to window.
First, we list all opened windows, of course, including our game window and save the list into combo box.

private void RefreshActiveWindows()
{
	List<string> lstActiveWnd = ModelData.ListAllActiveWindows(this.Handle);
	cbWindowsTitle.Items.Clear();
	foreach (string strTemp in lstActiveWnd)
	{
		cbWindowsTitle.Items.Add(strTemp);
	}
}

public static List<string> ListAllActiveWindows(IntPtr ipMainHandle)
{
	List<string> lstReturn = new List<string>();
	IntPtr ipDeskWndHandle = NativeWin32.GetDesktopWindow();
	IntPtr ipChildHandle = NativeWin32.GetWindow(ipDeskWndHandle, (uint)NativeWin32.GetWindow_Cmd.GW_CHILD);
	while (ipChildHandle != IntPtr.Zero)
	{
		if (ipChildHandle == ipMainHandle)
		{
			ipChildHandle = NativeWin32.GetWindow(ipChildHandle, (uint)NativeWin32.GetWindow_Cmd.GW_HWNDNEXT);
		}

		if (NativeWin32.IsWindowVisible(ipChildHandle))
		{
			StringBuilder sbTitle = new StringBuilder(1024);
			NativeWin32.GetWindowText(ipChildHandle, sbTitle, sbTitle.Capacity);
			String sWinTitle = sbTitle.ToString();
			if (sWinTitle.Length > 0)
			{
				lstReturn.Add(sWinTitle);
			}
		}
		ipChildHandle = NativeWin32.GetWindow(ipChildHandle, (uint)NativeWin32.GetWindow_Cmd.GW_HWNDNEXT);
	}
	return lstReturn;
}

After the user chooses the game window through combo box, click Start button, we should get the handle of game window and send key to it through Timer component. In this example I will send a space bar key continuously.

private void btnBrowse_Click(object sender, EventArgs e)
{
	if (btnBrowse.Text == "Start")
	{
		if (cbWindowsTitle.Text == "")
		{
			ErrorManager.ShowError("Please choose the process of game");
		}
		else
		{
			m_ipHandle = NativeWin32.FindWindow(null, cbWindowsTitle.Text);
			m_mdData = new ModelData(m_ipHandle);
			tmTimer.Start();
		}
		btnBrowse.Text = "Click x to stop";
	}
	else
	{
		tmTimer.Stop();
		btnBrowse.Text = "Start";
	}
}

private void tmTimer_Tick(object sender, EventArgs e)
{
	m_mdData.BuffPet();
}

The core function for sending key which uses PostMessage is in code snippet below

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

Keys keySpace;
const uint WM_KEYDOWN = 0x100;
const uint WM_KEYUP = 0x101;
public void BuffPet()
{  
	keySpace = Keys.Space;
	PostMessage(m_ipHandle, WM_KEYDOWN, (uint)keySpace, 0);
	Thread.Sleep(100);
	PostMessage(m_ipHandle, WM_KEYUP, (uint)keySpace, 0);
	//System.Windows.Forms.SendKeys.Send("");
}

The source code of class NativeWin32 you can see here “NativeWin32.cs”

Leave a Reply

Your email address will not be published. Required fields are marked *