|
-
May 27th, 2007, 04:50 PM
#1
Thread Starter
Hyperactive Member
[RESOLVED] Automating mouse clicks (but that one's for the gurus)
This is the code I use to simulate a mouse click within my VB app:
Code:
Declare Sub mouse_event Lib "user32.dll" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
mouse_event MOUSEEVENTF_MOVE Or MOUSEEVENTF_ABSOLUTE, 16000, 38000, 0, 0
mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
This works great to click wherever I want on the screen, and I've been using this solutions for years now. The problem is that if I minimize my application, it will, obviously, keep on clicking on my desktop!
I've searched the forums here and I couldn't find a solution to this. I am actually pretty pessimistic as to if it can be done in any way.
I'd like my app to do the mouse clicks & moves in background, allowing me to use the computer at the same time without affecting my mouse. In other words, the mouse clicks & moves are executed on an app that DOESN'T have the focus.
Also, in case it helps, all those mouse clicks & moves are to be executed on a WebBrowser control within my VB app. So if the fact that I only need this through the WebBrowser brings up some other possible solutions, please let me know. (Note that I am familiar with clicking links or dealing with elements within the WebBrowser - that won't help in that case).
I'll have to use such a solution in many different situations, but a good example would be to 'cheat' a flash game and prank one of my friend.
Thanks in advance to all of you VB lords/gurus.
Last edited by Krass; May 27th, 2007 at 04:53 PM.
Chris
-
May 27th, 2007, 05:01 PM
#2
Re: Automating mouse clicks (but that one's for the gurus)
you are in luck there is a different way to do it. You can simulate a mouse click on anything with a window handle by the following code
Code:
Public Const WM_LBUTTONDOWN = &H201
Public Const WM_LBUTTONUP = &H202
Call PostMessage(hwnd&, WM_LBUTTONDOWN, 0&, 0&)
Call PostMessage(hwnd&, WM_LBUTTONUP, 0&, 0&)
this adds a message to to message queue of whatever you want to click on and convinces it it HAS been clicked on. It can also simulate keypresses with the proper codes.
-
May 27th, 2007, 05:36 PM
#3
Re: Automating mouse clicks (but that one's for the gurus)
after carefully reading your post again, i see you not only need to click the window but tell it where to click. well this will help for that:
wParam A combination of one or more of the following constants indicating the state of the shift, control keys, and other mouse buttons:
MK_CONTROL: The control key is down.
MK_LBUTTON: The left mouse button is down.
MK_MBUTTON: The middle mouse button is down.
MK_RBUTTON: The right mouse button is down.
MK_SHIFT: The shift key is down.
lParam
Low word: The X coordinate of the cursor in window client coordinates.
High word: The Y coordinate of the cursor in window client coordinates.
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As _
Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
-
May 27th, 2007, 11:41 PM
#4
Thread Starter
Hyperactive Member
Re: Automating mouse clicks (but that one's for the gurus)
Hi. Thank you for your reply.
I havn't used PostMessage a lot so I tried to start with a simple test: clicking a button on my vb form. (even tho, later on, I'll want my app to deal with absolutely no control - simply click here and there).
Code:
Call PostMessage(Me.cmdTest.hwnd, WM_LBUTTONDOWN, MK_LBUTTON, 0&)
Call PostMessage(Me.cmdTest.hwnd, WM_LBUTTONUP, MK_LBUTTON, 0&)
It doesn't work but it's interesting to see that the button actually gets the focus... but doens't fire the msgbox. Any idea?
Later on, when this is gonna work, I'm then gonna try to make my mouse click in a minimized & unfocussed paint application. I think i'm starting to figure out how to use dword for the lparam. 
THANKS!
-
May 28th, 2007, 01:11 AM
#5
Re: Automating mouse clicks (but that one's for the gurus)
i dont know if this will help but you shouldn't be using mk_lbutton. That parameter is for OTHER mouse buttons pressed. So they may be cancelling.
Also if you are trying to double-click sending a WM_LBUTTONDBLCLK message to a control will cause the control to behave as if it had actually been double-clicked. In order to use this successfully, you should simulate the entire sequence that is received by a control being double-clicked. This consists of a WM_LBUTTONDOWN message followed by a WM_LBUTTONUP message, a WM_LBUTTONDBLCLK message, and a WM_LBUTTONUP message.
Now that i think of it this is probably why it didn't work:
did you call doevents afterwards? You must do so to give windows a chance to process message queues. And finally, if postmessage is giving you problems, try sendmessage. But i recommend you stick with postmessage because sendmessage waits on the called window to process the message before giving control back.
Last edited by Lord Orwell; May 28th, 2007 at 01:15 AM.
Reason: left out important info
-
May 28th, 2007, 01:29 AM
#6
Hyperactive Member
Re: Automating mouse clicks (but that one's for the gurus)
I bomb out on CALL PostMessage
Is that not supported in VB5 or is that some library I need to include?
Mac
Oops nevermind, I found
Private Declare Function PostMessage Lib "user32" _
Alias "PostMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Long) As Long
Last edited by Mr.Mac; May 28th, 2007 at 01:37 AM.
Reason: Found answer elsewhere
-
May 28th, 2007, 01:43 AM
#7
Re: Automating mouse clicks (but that one's for the gurus)
 Originally Posted by Lord Orwell
Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As _
Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
put that in a .bas file or in the declares section of your form.
It should work fine in vb5. it will NOT work in vb4
-
May 28th, 2007, 01:47 AM
#8
Hyperactive Member
Re: Automating mouse clicks (but that one's for the gurus)
 Originally Posted by Lord Orwell
put that in a .bas file or in the declares section of your form.
It should work fine in vb5. it will NOT work in vb4
Thanks! (Actually I already found that via yahoo/google, but thanks anyway)
I got the same result even with
Private Sub Command1_Click()
DoEvents
Call PostMessage(Me.cmdTest.hwnd, WM_LBUTTONDOWN, 0&, 0&)
DoEvents
Call PostMessage(Me.cmdTest.hwnd, WM_LBUTTONUP, 0&, 0&)
DoEvents
End Sub
Namely; it just gives focus to cmdTest.
Mac
-
May 28th, 2007, 01:55 AM
#9
Re: Automating mouse clicks (but that one's for the gurus)
i will toy with it myself. But it will take a while. I have to reboot into a different OS.
-
May 28th, 2007, 02:32 AM
#10
Re: Automating mouse clicks (but that one's for the gurus)
the code works properly. It just needs to be put in a loop and called a few times. I don't know if the postmessage needs to be posted a bunch of times or we need to just call doevents a bunch of times but you can try both. I wrote two apps and called a command button on the 2nd from the first one with a postmessage mouse click (and to be safe i followed it up with a virtual key space) and it clicked it until i ran out of stack space because every click opened up a message box.
-
May 28th, 2007, 03:52 PM
#11
Thread Starter
Hyperactive Member
Re: I lost access to a thread
Hi people.
I am the one who started the deleted thread last night. I was trying to figure out how to simulate mouse clicks in webbrowser within a VB form. Lord_Orwell was the main helper of the thread, who continued to supply his help to me in private. (btw, my thing is still not working!) I'm not giving up.
The thread was deleted because of the example I gave on using such a method. Sounded like "Simulating mouse clicks on a webpage running a flash game so I can cheat the game and prank my friend". That was only a very good example and is no where near what I intend of doing.
Simulating such clicks is easy using this method:
Code:
mouse_event MOUSEEVENTF_MOVE Or MOUSEEVENTF_ABSOLUTE, 16000, 38000, 0, 0
mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
DoEvents
...But that method is no longer good for me since I want to keep my app MINIMIZED and unfocused. I know about filling textboxes, enumerating elements of a webpage, enumerating links and cliking them.. Those solutions are of no help right now.
Some solutions were proposed:
Code:
For x = 0 To 10000
dword = MakeWord(CLng(Rnd * 32000), CLng(Rnd * 32000))
PostMessage hWnd, WM_LBUTTONDOWN, 0&, dword
PostMessage hWnd, WM_LBUTTONUP, 0&, dword
PostMessage hWnd, WM_LBUTTONDOWN, MK_LBUTTON, dword
PostMessage hWnd, WM_LBUTTONUP, MK_LBUTTON, dword
Next x
...here I have 2 pairs of PostMessage. Only because I was trying different things. None of the methods seems to work. I simply load up a webpage (www.google.com) and select some text with the mouse. If the thing would be working, the text would get UNSELECTED, right?.. or, with luck, it would be clicking some of the links on the webpage.
I've tried different ways to retrieving the hWnd based on this post http://www.vbforums.com/showthread.php?t=468596
I may be using it wrong, but I've been testing different ways for 6-7 hours now, and I just can't do it.
If a guru could try that out on his VB and pack the files for me, I'd be very happy to give a look at how it's done (if you manage to get it working!).
Hope I can end up with a working solution..
Thanks!
Last edited by Krass; May 28th, 2007 at 03:55 PM.
Reason: typo
Chris
-
May 28th, 2007, 03:59 PM
#12
Thread Starter
Hyperactive Member
Re: I lost access to a thread
Also, Mr.Mac, I can't remember what you were trying to do, but, for myself, I was doing basic tests and was wondering why a button on my VB forms couldn't be clicked using this method. The button was only getting FOCUS without being click, this solved it:
Code:
Call PostMessage(cmdTest.hwnd, WM_LBUTTONDOWN, 0&, 0&)
DoEvents
Call PostMessage(cmdTest.hwnd, WM_LBUTTONUP, 0&, 0&)
DoEvents
Call PostMessage(cmdTest.hwnd, WM_KEYDOWN, VK_SPACE, 0&)
Call PostMessage(cmdTest.hwnd, WM_KEYUP, VK_SPACE, 0&)
I don't even think the DoEvents are required to make it work. When the button gets the focus, sending VK_SPACE will simply click it. I got that working but couldn't go much further and click straight in a webbrowser.
Hope that helped you.
Last edited by Krass; May 28th, 2007 at 04:01 PM.
Reason: messed up the code
Chris
-
May 30th, 2007, 11:41 AM
#13
Re: Automating mouse clicks (but that one's for the gurus)
what happened? Was it UNdeleted?
-
May 30th, 2007, 12:59 PM
#14
Thread Starter
Hyperactive Member
Re: Automating mouse clicks (but that one's for the gurus)
Hi there.
Yup, the thread was undeleted. But before I start a new one, I'll first ask you something. I'll forget about the webbrowser for now since my problem begins at the postmessage statement. Here's what I've done:
Code:
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, y As Single)
MsgBox "x: " & X & " y: " & y
End Sub
Private Sub Command2_Click()
Call PostMessage(Me.hwnd, WM_LBUTTONDOWN, 0&, MakeDWord(200, 200))
Call PostMessage(Me.hwnd, WM_LBUTTONUP, 0&, 0&)
End Sub
When clicking Command2, the Form_MouseDown even *IS* fired, but always white those coords: x: -45600 y:285. No matter what value I send to MakeDWord, I end up with -45600,285. I tried the MakeDWord on the BUTTONUP call, too, but that doesn't change anything.
Code:
Private Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Function MakeDWord(LoWord As Integer, HiWord As Integer) As Long
MakeDWord = (HiWord * &H10000) Or (LoWord And &HFFFF&)
End Function
...Am I missing something here?
Thanks for any input...
-
May 30th, 2007, 01:28 PM
#15
Thread Starter
Hyperactive Member
Re: Automating mouse clicks (but that one's for the gurus)
Using winspector, I've been spying on the form. Here are the results:
When manually cliking the form:
Code:
WM_LBUTTONDOWN - Mouse coordinates: 325,184
WM_LBUTTONDOWN - Mouse coordinates: 325,184, Button pressed: MK_LBUTTON
WM_LBUTTONUP - wParam: 0x00000001, lParam: 0x00b80145
WM_LBUTTONUP - wParam: 0x00000000, lParam: 0x00b80145
when using Command2_Click
Code:
WM_LBUTTONDOWN - Mouse coordinates: -3200, 19
WM_LBUTTONDOWN - Mouse coordinates: -3200, 19
WM_LBUTTONUP - wParam: 0x00000000, lParam: 0x0013f380
WM_LBUTTONUP - wParam: 0x00000000, lParam: 0x0013f380
Even tho the 2nd solution shows -3200, 19, the msgbox still shows "-45600,285" - OH, actually I just noticed the msgbox now shows "-48000,285" (I think those numbers changed because I've closed and rerunned my VB app).
Odd.
-
May 30th, 2007, 01:50 PM
#16
Re: Automating mouse clicks (but that one's for the gurus)
try using sendmessage and sending the window a bm_click message.
-
May 30th, 2007, 01:52 PM
#17
Re: Automating mouse clicks (but that one's for the gurus)
Private Const BM_CLICK = &HF5
Call SendMessage(Command1.hWnd, BM_CLICK, 0, ByVal 0&)
-
May 30th, 2007, 01:55 PM
#18
Thread Starter
Hyperactive Member
Re: Automating mouse clicks (but that one's for the gurus)
Hi - thanks for the feedback.
I am no longer dealing with buttong clicks I am trying to click on the form, anywhere on the form. Where there's no button and no control at all.
The Form_MouseDown will msgbox the values of the x,y clicked by the postmessage. It's the MakeDWord part that seems to be sending wrong x,y coords, like my previous post says......
-
May 30th, 2007, 04:06 PM
#19
Re: Automating mouse clicks (but that one's for the gurus)
well in that case it looks like this is totally wrong: * &h100000
isn't a double word the same as two longs? I ask merely for information.
-
May 30th, 2007, 04:07 PM
#20
Re: Automating mouse clicks (but that one's for the gurus)
Last edited by Lord Orwell; May 30th, 2007 at 04:12 PM.
-
May 30th, 2007, 04:16 PM
#21
Thread Starter
Hyperactive Member
Re: Automating mouse clicks (but that one's for the gurus)
It now works. I had something wrong:
Code:
Call PostMessage(Me.hwnd, WM_LBUTTONDOWN, 0&, MakeDWord(200, 200))
should have read:
Code:
Call PostMessage(Me.hwnd, WM_LBUTTONDOWN, 0&, ByVal MakeDWord(200, 200))
Thanks!
(Edit: I'm continuing this thread on thread #471163)
-
May 30th, 2007, 04:24 PM
#22
Re: [RESOLVED] Automating mouse clicks (but that one's for the gurus)
could you post a completed code segment? This is something i would like to mess with myself.
-
May 30th, 2007, 04:28 PM
#23
Thread Starter
Hyperactive Member
Re: [RESOLVED] Automating mouse clicks (but that one's for the gurus)
Well, all I had working this far is clicking the form.
My post #14 shows exactly the code I used to make the postmessage click on the form, and the form reacting, msgbox'ing the x/y coords sent by the postmessage.
The only error was the missign "ByVal" in:
Code:
Call PostMessage(Me.hwnd, WM_LBUTTONDOWN, 0&, ByVal MakeDWord(200, 200))
Please tell me if you need any other info
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|