This library is complimented by my MouseDelta library which can show you what the input looks like coming from a real mouse.
At this level, movement input from the mouse consists of a series of small "delta" packets (eg x:+10, y:0 for a moderate movement to the right) where the timing of the movements can hold meaning. If you use the sample script from MouseDelta, you will note that mouse move messages can happen as frequently as 1ms apart, but in AHK, the Sleep command is only accurate down to ~10ms.
Therefore, it can often be desirable to implement something capable of doing <10ms sleeps, like QPX. This presents a further layer of complexity for novices.
So I decided to wrap the whole thing up in a package that makes it easy for anyone to issue some basic commands, and let the code handle the complexities. If the rate is >= 10ms, it uses Sleep. If below 10ms, it uses QPX. All you need to do is tell it what you want to do, and optionally how many times and and what rate, and it works out the rest.
Currently, I have code in there for move and sending mouse wheel, but ultimately I guess it could wrap anything that mouse_event supports.
Code: Select all
; =========== Sample script ============================================================
#SingleInstance,Force
; Send 2x mouse wheel down rolls at rate of 100ms
F11::
LLMouse.Wheel(-1, 2, 100)
return
; Send 100x 10 unit mouse moves for the x axis at a rate of 2ms
F12::
LLMouse.Move(0, 10, 100, 2)
return
; =======================================================================================
; LLMouse - A library to send Low Level Mouse input
; Note that many functions have time and rate parameters.
; These all work the same way:
; times - How many times to send the requested action. Optional, default is 1
; rate - The rate (in ms) to send the action at. Optional, default rate varies
; Note that if you use a value for rate of less than 10, special code will kick in.
; QPX is used for rates of <10ms as the AHK Sleep command does not support sleeps this short
; More CPU will be used in this mode.
class LLMouse {
static MOUSEEVENTF_MOVE := 0x1
static MOUSEEVENTF_WHEEL := 0x800
; ======================= Functions for the user to call ============================
; Move the mouse
; All values are Signed Integers (Whole numbers, Positive or Negative)
; x - How much to move in the x axis. + is right, - is left
; y - How much to move in the y axis. + is down, - is up
Move(x, y, times := 1, rate := 1){
this._MouseEvent(times, rate, this.MOUSEEVENTF_MOVE, x, y)
}
; Move the wheel
; dir - Which direction to move the wheel. 1 is up, -1 is down
Wheel(dir, times := 1, rate := 10){
static WHEEL_DELTA := 120
this._MouseEvent(times, rate, this.MOUSEEVENTF_WHEEL, , , dir * WHEEL_DELTA)
}
; ============ Internal functions not intended to be called by end-users ============
_MouseEvent(times, rate, dwFlags := 0, dx := 0, dy := 0, dwData := 0){
Loop % times {
DllCall("mouse_event", uint, dwFlags, int, dx ,int, dy, uint, dwData, int, 0)
if (A_Index != times){ ; Do not delay after last send, or if rate is 0
if (rate >= 10){
Sleep % rate
} else {
this._Delay(rate * 0.001)
}
}
}
}
_Delay( D=0.001 ) { ; High Resolution Delay ( High CPU Usage ) by SKAN | CD: 13/Jun/2009
Static F ; www.autohotkey.com/forum/viewtopic.php?t=52083 | LM: 13/Jun/2009
Critical
F ? F : DllCall( "QueryPerformanceFrequency", Int64P,F )
DllCall( "QueryPerformanceCounter", Int64P,pTick ), cTick := pTick
While( ( (Tick:=(pTick-cTick)/F)) <D ) {
DllCall( "QueryPerformanceCounter", Int64P,pTick )
Sleep -1
}
Return Round( Tick,3 )
}
}