-
Jul 17th, 2011, 10:32 PM
#1
Thread Starter
New Member
Way to temporarily block mouse movement? Trouble with Post/SendMessage
So I have been working on some code that is a supplement to a video game that I play (doesn't really give me an advantage, I'm against cheating) as recreational programming to get me to learn more things which apparently is working immensely.
The video game is called DoTA which is a custom map in Warcraft 3.
What I am trying to do is to make a program that can manually click the skills when the user presses the key they bound to that skill. This allows for more precise skill usage as keybindings in the game change randomly which causes chaos.
I first tried using mouse_event to move, click down, click up, return back to original location. This worked, but I ran into a problem that occurred if mouse movement by the user was happening while the code was being ran. The problem mainly would cause the mouse to move off the skill before clicking or even after the mouse down event.
So then I looked into SendMessage and PostMessage but it took a while before I could fully grasp everything about the functions mostly due to many examples posted online being different from one another as far as the declarations.
I now have matched the output that happens according to Spy++ when I actually click the mouse myself with various PostMessage and SendMessages, but am still having an odd problem:
I provide the coordinates to click on say Button 1. Spy++ tells me it is clicking it properly, but I do not actually get a click. However, if I manually move my mouse over that button, even on the very corners of it, and then press the key, it clicks it (although it also seems to work on one other button in the game.) Other than that, it will not click any other button besides the one that the coordinates are over.
The game does not have any child windows so it doesn't seem like I can get the handle of the actual buttons themselves.
Any advice or links to additional reading would be sincerely appreciated.
P.S. I have been turned away before for using a video game as an example while being accused of cheating and it really de-motivated me. I am completely against cheating, but I love video games and figured it would be very fun to code for something I love.
Here is what I have as test coding to figure this all out (the sleep time in between mdown and mup is because the game doesn't register if clicked too fast):
Code:
Option Explicit On
Imports System.Runtime.InteropServices 'MarshalAs, Marshal
'Imports System.Reflection 'assembly
Public Class Form1
Public Declare Function PostMessageLong Lib "user32" Alias "PostMessageA" _
(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
<DllImport("user32.dll")> _
Shared Function WindowFromPoint(ByVal pnt As Point) As IntPtr
End Function
Public Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Int32) As UShort
Declare Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
Public Const WM_LBUTTONUP As Integer = &H202
Public Const WM_LBUTTONDOWN As Integer = &H201
Public Const MK_LBUTTON As Long = Keys.LButton
Public Const WM_ACTIVATE As Integer = &H6
Public Const WM_SETCURSOR As Long = &H20
Public Const WM_NCHITTEST = &H84
Public Const WM_MOUSEMOVE As Long = &H200
Public Const BM_CLICK As Integer = &HF5&
Function MakeDWord(ByVal LoWord As Integer, ByVal HiWord As Integer) As Long
MakeDWord = (HiWord * &H10000) Or (LoWord And &HFFFF&)
End Function
Private Sub clickButton(ByVal window As IntPtr)
PostMessageLong(window, WM_LBUTTONDOWN, MK_LBUTTON, MakeDWord(1500, 500))
End Sub
Dim Q As Boolean = False
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If GetAsyncKeyState(Keys.Q) Then
If Q = False Then
If GetAsyncKeyState(Keys.Q) Then
Q = True
Dim MousePosX As Integer = Windows.Forms.Cursor.Position.X
Dim MousePosY As Integer = Windows.Forms.Cursor.Position.Y
Dim MoveMouseX As Integer = 1842
Dim MoveMouseY As Integer = 876
Windows.Forms.Cursor.Position = New Point(MoveMouseX, MoveMouseY)
Dim hwnd As IntPtr
hwnd = FindWindow(vbNullString, "Warcraft III")
Dim button As Integer = &H1
Dim nobutton As Long = &H0
SendMessage(hwnd, WM_LBUTTONDOWN, button, MakeDWord(1842, 876))
Application.DoEvents()
Sleep(25)
SendMessage(hwnd, WM_LBUTTONUP, nobutton, MakeDWord(1842, 876))
Application.DoEvents()
Windows.Forms.Cursor.Position = New Point(MousePosX, MousePosY)
End If
End If
ElseIf CStr(GetAsyncKeyState(Keys.Q)) = "0" Then
Q = False
End If
End Sub
End Class
'Dim tempclick As Long = &H2540473
'Dim convert As Long = hwnd
'If convert <> "0" Then
' MsgBox("works...")
'Else
' MsgBox("doesn't work...")
'End If
'SendMessage(hwnd, BM_CLICK, &H1, MakeDWord(1842, 876))
'Application.DoEvents()
'SendMessage(hwnd, WM_ACTIVATE, &H1, &H0)
'Application.DoEvents()
'Sleep(25)
'SendMessage(hwnd, &H20, hwnd, &H2010001)
'Application.DoEvents()
'Sleep(25)
'PostMessageLong(hwnd, WM_LBUTTONDOWN, button, MakeDWord(1527, 876))
'Application.DoEvents()
'Sleep(25)
'SendMessage(hwnd, WM_SETCURSOR, hwnd, CLng(&H2010001))
'Application.DoEvents()
'Sleep(25)
'PostMessageLong(hwnd, WM_LBUTTONUP, &H0, MakeDWord(1527, 876))
'Application.DoEvents()
'Sleep(25)
'SendMessage(hwnd, &H20, hwnd, &H2000001)
'Application.DoEvents()
'Sleep(25)
'PostMessageLong(hwnd, &H200, &H0, MakeDWord(1527, 876))
'Application.DoEvents()
'Sleep(25)
I was thinking that if there was a way to maybe pause control from being able to move the mouse that I could just revert back to the original mouse_event code as well, but I haven't found anything that can take away control like that (actually, I wouldn't even want that posted TBH as it could be used for malicious stuff).
I thank you in advance even for just reading this.
EDIT:
The code at the bottom is just stuff I was using to match what happens when I actually click according to Spy++.
Last edited by ashih313; Jul 17th, 2011 at 10:36 PM.
-
Jul 17th, 2011, 10:57 PM
#2
Re: Way to temporarily block mouse movement? Trouble with Post/SendMessage
In VB6/WinXP I used the BlockInput API and it worked really well to temp disable the mouse and keyboard from the user. See notes at the bottom of that page for .Net & Vista.
-
Jul 17th, 2011, 11:29 PM
#3
Thread Starter
New Member
Re: Way to temporarily block mouse movement? Trouble with Post/SendMessage
Originally Posted by Edgemeal
In VB6/WinXP I used the BlockInput API and it worked really well to temp disable the mouse and keyboard from the user. See notes at the bottom of that page for .Net & Vista.
You, you, you...I love you, you.
Would have been nice to get PostMessage to work, but I don't think I will run into very many programs with as many limitations as Warcraft 3 in the future.
Thank you so much. I have been at this for 3 weeks now.
Tags for this Thread
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
|