0

I'm trying to learn mouse/keyboard emulation using win api.
I found out that it is possible to emulate button click using sendmessage() function.

Well, I get coordinates of "play" button (it is (60;100)) and trying to push this button using the following code:

            int x = 60;
            int y = 100;
            int lParam = ((x << 16) | (y & 0xffff));

            int parentWindow = FindWindow("BaseWindow_RootWnd", "Main Window");//get main winamp window
            MessageBox.Show(parentWindow.ToString());//failed if 0

            SendMessage(parentWindow, WM_LBUTTONDOWN, IntPtr.Zero, new IntPtr(lParam));//send left mouse button down
            SendMessage(parentWindow, WM_LBUTTONUP, IntPtr.Zero, new IntPtr(lParam));//send left mouse button up

But this code has no effect on the winamp.

Can anybody point me on the mistakes i made? Any help is greatly appreciated!

p.s. It's not applicable for me to move mouse to the winamp play button, than do a click, than move it back.
Also for winamp it is impossible to get button's handle. With button handle SendMessage() works fairly well, but with coordinates it doesn't at all.

ADDITION #1

Well, the code above activates winamp window and shows it, if it was minimized. But play button stil don't want to be pushed ;(

ADDITION #2

Here are messages I get after I execute the code above.

Messages in spy++

mr.nothing
  • 5,141
  • 10
  • 53
  • 77
  • See: http://stackoverflow.com/a/4957386/402169. Mouse input is the same as keyboard input in this context. – tenfour Jul 25 '12 at 14:02
  • possible duplicate of [How do I send mouse and keyboard events to another process?](http://stackoverflow.com/questions/1655082/how-do-i-send-mouse-and-keyboard-events-to-another-process) – Deanna Jul 25 '12 at 14:19
  • Why not use the UIAutomation namespace? That's what it's for. – Raymond Chen Jul 26 '12 at 16:20
  • @Deanna, I solved it by myself, just forgot to mark it as an answer, thanks for reminding me. If interested - see answer below. – mr.nothing Jul 31 '12 at 10:30

3 Answers3

2

To let Winamp play/pause the current song, simply send it a Play/Pause message, which is long 40046 as defined in winamp.h. You'll have to send it in a WM_WA_IPC message (which is a user message, also known as WM_USER) instead of a WM_LBUTTONDOWN.

So, something like this should do:

SendMessage(parentWindow, WM_USER, IntPtr.Zero, new IntPtr(40046));

More info here, here and here.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • it's great, but my initial intention was to understand how can mouse/keyboard can be emulated. Thank you, though. – mr.nothing Jul 25 '12 at 15:06
  • 1
    @mr.nothing if it is for learning purposes, why don't you write your own test program that emits all Windows messages it receives? You could also achieve this using `Spy++`. – CodeCaster Jul 25 '12 at 15:11
  • well, I using spy++ already, and when I execute code provided above spy++ detects some strange messages, but they are not WM_LBUTTONDOWN or WM_LBUTTONUP or something like that. Please, see updated topic (screenshot) – mr.nothing Jul 25 '12 at 15:36
1

well, to simulate mouse click in winamp window you need to do exactly what is happening when you just click it with hardware mouse. The following was found out from spy++:
enter image description here

So to emulate mouse click we need to:

  1. Call twice PostMessage() instead of SendMessage() because "P" in the screenshot above tells us that the message was got from the PostMessage() (according to msdn)
  2. The parameters should be the following for the first PostMessage():
    - First parameter - Winamp window handle (in our case it is 005E09FA)
    - Second parameter - the winapi code of the event, when left mouse button is down(WM_LBUTTONDOWN = 0x201)
    - Third parameter - MK_LBUTTON = 0x1 (It seems, it is necessary to pass it. It would be great if somebody can explain why)
    - Fourth parameter - Coordinates of the point where you want to press mouse button (this parameter can be calculated as following - ((Y << 16) | X))
  3. The parameters should be the following for the second PostMessage():
    - First parameter - Winamp window handle (in our case it is 005E09FA)
    - Second parameter - the winapi code of the event, when left mouse button is up (WM_LBUTTONUP = 0x202)
    - Third parameter - 0 or IntPtr.Zero
    - Fourth parameter - Coordinates of the point where you want to release mouse button (need to be as in first PostMessage() if you want your click to have an effect; this parameter can be calculated as following - ((Y << 16) | X))

Thanks everyone for their input!

mr.nothing
  • 5,141
  • 10
  • 53
  • 77
0

You should be using SendInput() to send input to other applications, not faking window messages.

Community
  • 1
  • 1
Deanna
  • 23,876
  • 7
  • 71
  • 156
  • well, I tried it and as I thought it is impossible to make a click without moving mouse cursor. I need to simulate mouse click without moving it. – mr.nothing Jul 25 '12 at 14:52
  • If you simulate only part of mouse input behavior, you're not really simulating it. It's nonsensical to have the mouse click in a place where the cursor is not. – tenfour Jul 25 '12 at 18:44
  • @tenfour, well if we are talking about testing purposes, than it really do have a sense to make a click in a place where the cursor is not, because it allows you to do anything else, when your tests being performed. – mr.nothing Jul 26 '12 at 15:10
  • No, it's not a complete simulation then. You cannot have your cake and eat it too. Maybe you should put it in a VM? – tenfour Jul 26 '12 at 15:52
  • @tenfour, well, maybe there are some hidden pitfalls which i'm not aware of, but it seems that it works for me. Please, see my answer. – mr.nothing Jul 26 '12 at 15:55
  • As you said in another comment, you're interested in a generalize solution. This is a solution that only works in one specific application; others will fail you. For example you haven't bothered to simulate `GetKeyState`, or deal with the mouse coords in the `MSG` structure. Any application relying on these will fail (which is very common). – tenfour Jul 26 '12 at 15:59
  • @tenfour, yes, you're right about generalization. Could you provide any application as an example, where approach I suggested is not working so I can investigate it? – mr.nothing Jul 26 '12 at 17:02