What could cause mouse clicks sent by PostMessage to be ignored?

10,139

Solution 1

     public void SendClick(WMessages type, Point pos)
{
    switch(type)
    {
        case WMessages.WM_LBUTTONDOWN:
            PostMessage(new HandleRef(null, this.process.MainWindowHandle),
                (UInt32)WMessages.WM_LBUTTONDOWN, (IntPtr)0x1,
                (IntPtr)((pos.Y << 16) | (pos.X & 0xFFFF)));
            return;
        case WMessages.WM_LBUTTONUP:
            PostMessage(new HandleRef(null, this.process.MainWindowHandle),
                (UInt32)WMessages.WM_LBUTTONDOWN, (IntPtr)0x1, // <--(2) but you are telling to do WM_LBUTTONDOWN
                (IntPtr)((pos.Y << 16) | (pos.X & 0xFFFF)));
            return;
        default:
            return;
    }
}

SendClick(WMessages.WM_LBUTTONDOWN, Cursor.Position);
SendClick(WMessages.WM_LBUTTONUP, Cursor.Position); // <--(1) you are sending WM_LBUTTONUP

so just read (1) first then (2) and your problem is solved

Solution 2

Did you try a SendMessage call, instead of PostMessage? SendMessage immediately calls the handler for the Window. PostMessage puts the message on a list for later processing.

Share:
10,139
mina
Author by

mina

Updated on August 21, 2022

Comments

  • mina
    mina over 1 year

    I was looking for a way to send mouse clicks to a background application on Windows (ie. by handle), The test window I used to confirm my code was working accepts and processes the clicks, but my target application does not (even though Spy++ shows the messages).

    What could be causing this? And is there a work-around?

    here's the C# code i'm using.

    public enum WMessages : int
    {
        WM_LBUTTONDOWN = 0x201,
        WM_LBUTTONUP = 0x202,
    
        WM_KEYDOWN = 0x100,
        WM_KEYUP = 0x101,
    
        WH_KEYBOARD_LL = 13,
        WH_MOUSE_LL = 14,
    }
    
    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("user32.dll", SetLastError = true)]
    private static extern int PostMessage(HandleRef hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
    
    public void SendClick(WMessages type, Point pos)
    {
        switch(type)
        {
            case WMessages.WM_LBUTTONDOWN:
                PostMessage(new HandleRef(null, this.process.MainWindowHandle),
                    (UInt32)WMessages.WM_LBUTTONDOWN, (IntPtr)0x1,
                    (IntPtr)((pos.Y << 16) | (pos.X & 0xFFFF)));
                return;
            case WMessages.WM_LBUTTONUP:
                PostMessage(new HandleRef(null, this.process.MainWindowHandle),
                    (UInt32)WMessages.WM_LBUTTONDOWN, (IntPtr)0x1,
                    (IntPtr)((pos.Y << 16) | (pos.X & 0xFFFF)));
                return;
            default:
                return;
        }
    }
    
    SendClick(WMessages.WM_LBUTTONDOWN, Cursor.Position);
    SendClick(WMessages,WM_LBUTTONUP, Cursor.Position);
    

    Is this possible to achieve? Is there a better way of acheiving this?

    Note: The above code doesn't work when the application is active and the mouse is hovered in the correct location, either. I'm also looking specifically send input to a background application, so SendInput and others are out of the question.

    Thanks

  • Sergey Skoblikov
    Sergey Skoblikov over 12 years
    SendMessage just freezes the calling process while calling PostMessage-like machinery to send message to the target process. The call is immediate only if windows are in the same process. Besides, SendMessage fails in message handlers called from SendMessage calls from different processes - to prevent deadlocks when processes wait for each other. Keep in mind that COM calls for COM objects in another pocesses use SendMessage internally - so don't call SendMessage directly in COM objects methods.... Gosh, Win32 is a holy mess...