4

I am trying to send a message to a game (to automate text commands), the problem is that I can't figure out how to use the information from spy++ to write a C# sendmessage function.

I was able to use spy++ to get 00220540 S WM_SETCURSOR hwnd:0024052C nHittest:HTCLIENT wMouseMsg:WM_MOUSEMOVE

Could anyone provide a breakdown of what this means, and how to send the message to the game in c#?

EDIT:

I found out that I was looking at the wrong process. Instead of looking at the javaw.exe, I was looking at the actual game.

Here is the code for pressing t:

<00919> 0038062A WM_INPUT nInputCode:RIM_INPUT hRawInput:189E0973
<00920> 0024052 P WM_KEYUP nVirtKey:'T' cRepeat:1 ScanCode:14fExtended:0fAltDown:0fRepeat:1fUp:1
peterh
  • 11,875
  • 18
  • 85
  • 108
Jess
  • 8,628
  • 6
  • 49
  • 67

1 Answers1

8

So lets start with the signature for SendMessage, from Pinvoke.net:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

It taks a window handle, hWnd, a message ID, Msg, and two generic parameters wParam and lParam which change meaing based on the message ID.

What spy++ is showing you is the parameters that were sent to SendMessage. As you can see it doesn't show you wParam and lParam, but hwnd, nHittest, and wMouseMsg. That's because Spy++ knows what the wParam and lParam parameters actually mean for a WM_SETCURSOR message and is decoding them for you.

So decoding each piece of the what Spy++ has sent:

  1. 00220540 - the window handle receiving the message - the hWnd parameter.
  2. S - It means it was sent via SendMessage() and not posted via PostMessage(). See http://msdn.microsoft.com/en-us/library/aa265147(v=vs.60).aspx
  3. WM_SETCURSOR - The message ID - the Msg parameter.
  4. hwnd:0024052C - handle of the Window containing the cursor - the wParam parameter.
  5. nHittest:HTCLIENT - the hit test code - the low word of the lParam parameter.
  6. wMouseMsg:WM_MOUSEMOVE - the mouse message - the high word of the lParam parameter.

The way you would go about sending the message to a window is:

enum WindowMessages {
    WM_SETCURSOR  = 0x0020,
    WM_MOUSEMOVE  = 0x0200,
    ....
}

enum HitTestCodes {
    HTCLIENT = 1,
    ....
}

....
IntPtr hWnd = [get your window handle some how]
int lParam = ((int)WindowMessages.WM_MOUSEMOVE) << 16 + (int)HitTestCodes.HTCLIENT;
SendMessage(hWnd, (uint)WindowMessages.WM_SETCURSOR, hWnd, (IntPtr)lParam);

For understanding what other messages mean you can do a search on Msdn.com for the messsage in the Windows documentation.

So after answering all of that I don't think this will have anything to do with sending keys to the game you are trying to control. WM_SETCURSOR doesn't have anything to do with keyboard input.

shf301
  • 31,086
  • 2
  • 52
  • 86
  • Thanks for the brake down, that is very helpful. The game is coded in java. When I press t (to bring up the message area), it gives the above message. But when I type, I get nothing. Could this be going through the java runtime? – Jess Feb 02 '11 at 04:30
  • I don't know if it has anything to do with the java runtime. Sending fake keyboard and mouse input is not a reliable process on Windows. The only thing I could suggest is making sure that the correct window has focus before calling SendKeys - since input is always sent to the focused window. – shf301 Feb 02 '11 at 04:44
  • I modified my post, I was looking at the wrong process, if you could explain that message, I would be very greatful. – Jess Feb 02 '11 at 04:57
  • 1
    You can decode what the messages mean by searching for the WM_INPUT and WM_KEYUP message ID's. Receiving a WM_INPUT may means that it uses raw input which is why SendKeys isn't working. In any case you can't (reliably) send key strokes via window messages: http://blogs.msdn.com/b/oldnewthing/archive/2010/12/21/10107494.aspx – shf301 Feb 02 '11 at 06:05