Search code examples
c#objective-cwinapipostmessage

PostMessage and SendMessage WM_SETCURSOR, WM_LBBUTTONDOWN/UP etc all send xPox0, yPos0


I'm writing a C# program to send clicks from a window to another. I'm using SendMessage and PostMessage from the winapi. SendMessage works fine for keyboard events but when I try using it to send mouse events its always sending mouse coordinates 0,0. I can verify with spy++ that the application is receiving the events but the x and y are at (0,0) and the app thinks the mouse is offscreen NCHITTEST=NOTCLIENT.

The code is as follows:

PostMessage(appWin, (int)WMessages.WM_MOUSEMOVE, 0, MakeDword(300, 200));

Where PostMessage is declared as:

[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
protected static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);

Where appWin is the handle to the window(verified with spy++ that its receiving the events). The window has no controls at all. I've also tried multiple macros MakeLParam, MakeDword, done it by hand, etc. I'm using Windows7.

I spent most of last night/this morning away trying to find the problem but I have not been able to. While there are many posts online regarding Post/SendMessage, I was only able to find one where the similar problem came up and there were no answers.

To summarize the problem: Does anyone know why SendMessage would be sending the proper message to the application window but instead of passing it the x and y coordinates given its always passing (0,0)?

Thanks!


Solution

  • I think I can finally see what's wrong with your code.

    [DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)] 
    static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);
    

    The issue is that long is 64 bits wide in C#. In a 32 bit process this is incorrect since those parameters should be 32 bits wide. I would have expected you to have seen a stack imbalance warning when run through the debugger.

    The correct declaration is:

    static extern bool PostMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);
    

    You most definitely don't need to switch to native C++ code to get this to work.