#include-once
#include <WinAPI.au3>
Func _WinMouseClick($hWnd, $sButton = "left", $iX = "", $iY = "", $iClicks = 1)
Local $hUser32, $ilParam, $bButton, $bButtonDown, $bButtonUp
Local $aPos, $iMode, $iDelay, $iDownDelay
Local Const $MK_LBUTTON = 0x0001
Local Const $MK_RBUTTON = 0x0002
Local Const $MK_MBUTTON = 0x0010
Local Const $WM_MOUSEMOVE = 0x0200
Local Const $WM_LBUTTONDOWN = 0x0201
Local Const $WM_LBUTTONUP = 0x0202
Local Const $WM_RBUTTONDOWN = 0x0204
Local Const $WM_RBUTTONUP = 0x0205
Local Const $WM_MBUTTONDOWN = 0x0207
Local Const $WM_MBUTTONUP = 0x0208
If NOT IsHWnd($hWnd) OR NOT WinExists($hWnd) Then Return SetError(1, 0, 0)
Switch StringLower($sButton)
Case "left", ""
$bButton = $MK_LBUTTON
$bButtonDown = $WM_LBUTTONDOWN
$bButtonUp = $WM_LBUTTONUP
Case "right"
$bButton = $MK_RBUTTON
$bButtonDown = $WM_RBUTTONDOWN
$bButtonUp = $WM_RBUTTONUP
Case "middle"
$bButton = $MK_MBUTTON
$bButtonDown = $WM_MBUTTONDOWN
$bButtonUp = $WM_MBUTTONUP
Case Else
Return SetError(2, 0, 0)
EndSwitch
If NOT StringIsInt($iX) OR NOT StringIsInt($iY) Then
$iMode = Opt("MouseCoordMode", 0)
$aPos = MouseGetPos()
Opt("MouseCoordMode", $iMode)
$iX = $aPos[0]
$iY = $aPos[1]
EndIf
$ilParam = _WinAPI_MakeLong($iX, $iY)
$iClicks = Int($iClicks)
If $iClicks < 1 Then $iClicks = 1
$iDelay = Opt("MouseClickDelay", 10)
Opt("MouseClickDelay", $iDelay)
$iDownDelay = Opt("MouseClickDownDelay", 10)
Opt("MouseClickDownDelay", $iDownDelay)
$hUser32 = DllOpen("user32.dll")
If $hUser32 = -1 Then Return SetError(3, 0, 0)
For $i = 1 To $iClicks
_PostMessage($hWnd, $WM_MOUSEMOVE, 0, $ilParam, $hUser32)
_PostMessage($hWnd, $bButtonDown, $bButton, $ilParam, $hUser32)
Sleep($iDownDelay)
_PostMessage($hWnd, $bButtonUp, $bButton, $ilParam, $hUser32)
If $i < $iClicks Then Sleep($iDelay)
Next
DllClose($hUser32)
Return 1
EndFunc ;==>_WinMouseClick
Func _WinSendKeys($hWnd, $sKeys, $iMode = 1)
Local $hUser32, $ilParam, $iVKCode, $iVSCCode, $iExtend, $iModifier = 0, $iIndex
Local $iCapslock, $iDelay, $iDownDelay, $iKeyState, $fAltDown = False, $sRepeat, $sStr = ""
Local Const $bAltDown = 0x20000000, $bRepeat = 0x40000000, $bKeyUp = 0x80000000
Local Const $WM_KEYDOWN = 0x0100
Local Const $WM_KEYUP = 0x0101
Local Const $WM_CHAR = 0x0102
Local Const $WM_SYSKEYDOWN = 0x0104
Local Const $WM_SYSKEYUP = 0x0105
Local Const $WM_HOTKEY = 0x0312
If NOT IsHWnd($hWnd) OR NOT WinExists($hWnd) Then Return SetError(1, 0, 0)
If $sKeys == "" Then Return SetError(2, 0, 0)
If $iMode <> 2 Then $iMode = 1
$hUser32 = DllOpen("user32.dll")
If $hUser32 = -1 Then Return SetError(3, 0, 0)
Local Const $aVKList = _MakeVKList()
$iCapslock = Opt("SendCapslockMode", 1)
$iVKCode = $aVKList[23][1]
$iKeyState = BitAND(_GetKeyState($iVKCode, $hUser32), 1)
$iCapslock = BitAND($iCapslock, $iKeyState)
If $iCapslock = 1 Then
Opt("SendCapslockMode", 0)
Send("{CAPSLOCK off}")
Opt("SendCapslockMode", 1)
EndIf
$iDelay = Opt("SendKeyDelay", 0)
$iDownDelay = Opt("SendKeyDownDelay", 0)
For $j = 1 To StringLen($sKeys)
$sRepeat = "1"
$sStr &= StringMid($sKeys, $j, 1)
If StringLeft($sStr, 1) = "{" Then
If StringRight($sStr, 1) <> "}" Then ContinueLoop
If StringRegExp($sStr, "(?i)^{[[:graph:]]+ (\d+|down|up|on|off|toggle)}$") Then
$sRepeat = StringRegExpReplace($sStr, "^({[[:graph:]]+) (.+)(})$", "\2")
$sStr = StringRegExpReplace($sStr, "^({[[:graph:]]+) (.+)(})$", "\1\3")
$sRepeat = StringLower($sRepeat)
EndIf
If StringRegExp($sStr, "^{[^!#\+\^\{\}]}$") Then
$sStr = StringRegExpReplace($sStr, "^{(.)}$", "\1")
Else
$sStr = StringUpper($sStr)
EndIf
If $sStr = "{ASC}" AND NOT StringIsDigit($sRepeat) Then ContinueLoop
EndIf
For $iIndex = 0 To UBound($aVKList) - 1
If $sStr == $aVKList[$iIndex][0] Then ExitLoop
Next
$sStr = ""
If $iIndex > UBound($aVKList) - 1 Then ContinueLoop
$iModifier = BitOR($iModifier, $aVKList[$iIndex][4])
Switch $iIndex
Case 0 To 3 ; modifier key
ContinueLoop
Case 4 To 13 ; modifier key down or up
$iModifier = 0
$sRepeat = StringRegExpReplace($aVKList[$iIndex][0], "^{[[:graph:]]+(DOWN|UP)}$", "\1")
$sRepeat = StringLower($sRepeat)
Case 14 ; send the ASCII characters
$iModifier = $aVKList[$iIndex][4]
Case 23, 71, 72 ; toggled key
If StringRegExp($sRepeat, "^on|off|toggle$") Then
$sRepeat = " " & $sRepeat
Else
$sRepeat = ""
EndIf
Case Else
If NOT StringRegExp($sRepeat, "^\d+|down|up$") Then $sRepeat = "1"
EndSwitch
If ($iModifier <> 0 AND $iMode = 1) OR $iIndex = 14 Then
If BitAND($iModifier, 8) Then Send("{LWINDOWN}")
If BitAND($iModifier, 4) Then Send("{SHIFTDOWN}")
If BitAND($iModifier, 2) Then Send("{CTRLDOWN}")
If BitAND($iModifier, 1) Then
Send("{ALTDOWN}")
$iVKCode = $aVKList[0][1]
$iVSCCode = $aVKList[0][2]
$ilParam = BitOR(_WinAPI_MakeLong(1, $iVSCCode), $bAltDown)
_PostMessage($hWnd, $WM_SYSKEYDOWN, $iVKCode, $ilParam, $hUser32)
$fAltDown = True
EndIf
Sleep($iDownDelay)
EndIf
Select
Case $iIndex = 14 ; send the ASCII characters
For $i = 1 To StringLen($sRepeat)
$iIndex = Number(StringMid($sRepeat, $i, 1))
$iIndex += 44
$iVKCode = $aVKList[$iIndex][1]
$iVSCCode = $aVKList[$iIndex][2]
$iExtend = $aVKList[$iIndex][3]
$ilParam = BitOR(_WinAPI_MakeLong(1, $iVSCCode), $iExtend, $bAltDown)
_PostMessage($hWnd, $WM_SYSKEYDOWN, $iVKCode, $ilParam, $hUser32)
Sleep($iDownDelay)
_PostMessage($hWnd, $WM_SYSKEYUP, $iVKCode, BitOR($ilParam, $bRepeat, $bKeyUp), $hUser32)
Sleep($iDelay)
Next
Case $iIndex = 23 OR $iIndex = 71 OR $iIndex = 72 ; toggled key
$sRepeat = StringTrimRight($aVKList[$iIndex][0], 1) & $sRepeat & "}"
Send($sRepeat)
Case $iModifier <> 0 AND $iMode = 2 ; post WM_HOTKEY message
$iVKCode = $aVKList[$iIndex][1]
$ilParam = _WinAPI_MakeLong($iModifier, $iVKCode)
If StringIsDigit($sRepeat) Then
$iIndex = Number($sRepeat)
Else
$iIndex = 1
EndIf
For $i = 1 To $iIndex
_PostMessage($hWnd, $WM_HOTKEY, 0, $ilParam, $hUser32)
Sleep($iDelay)
Next
Case Else
$iVKCode = $aVKList[$iIndex][1]
$iVSCCode = $aVKList[$iIndex][2]
$iExtend = $aVKList[$iIndex][3]
$ilParam = BitOR(_WinAPI_MakeLong(1, $iVSCCode), $iExtend)
If $fAltDown Then $ilParam = BitOR($ilParam, $bAltDown)
If StringIsDigit($sRepeat) Then
$iIndex = Number($sRepeat)
Else
$iIndex = 1
EndIf
For $i = 1 To $iIndex
If $sRepeat <> "up" Then
If $fAltDown Then
_PostMessage($hWnd, $WM_SYSKEYDOWN, $iVKCode, $ilParam, $hUser32)
Else
_PostMessage($hWnd, $WM_KEYDOWN, $iVKCode, $ilParam, $hUser32)
EndIf
Sleep($iDownDelay)
EndIf
If $sRepeat <> "down" Then
If $fAltDown Then
_PostMessage($hWnd, $WM_SYSKEYUP, $iVKCode, BitOR($ilParam, $bRepeat, $bKeyUp), $hUser32)
Else
_PostMessage($hWnd, $WM_KEYUP, $iVKCode, BitOR($ilParam, $bRepeat, $bKeyUp), $hUser32)
EndIf
Sleep($iDelay)
EndIf
Next
EndSelect
If ($iModifier <> 0 AND $iMode = 1) OR $iIndex = 14 Then
If BitAND($iModifier, 1) Then
$iVKCode = $aVKList[0][1]
$iVSCCode = $aVKList[0][2]
$ilParam = BitOR(_WinAPI_MakeLong(1, $iVSCCode), $bRepeat, $bKeyUp)
_PostMessage($hWnd, $WM_SYSKEYUP, $iVKCode, $ilParam, $hUser32)
$fAltDown = False
Send("{ALTUP}")
EndIf
If BitAND($iModifier, 2) Then Send("{CTRLUP}")
If BitAND($iModifier, 4) Then Send("{SHIFTUP}")
If BitAND($iModifier, 8) Then Send("{LWINUP}")
Sleep($iDownDelay)
$iModifier = 0
EndIf
Next
Opt("SendKeyDelay", $iDelay)
Opt("SendKeyDownDelay", $iDownDelay)
If $iCapslock = 1 Then
Opt("SendCapslockMode", 0)
Send("{CAPSLOCK on}")
Opt("SendCapslockMode", 1)
EndIf
DllClose($hUser32)
Return 1
EndFunc ;==>_WinSendKeys
Func _WinSendText($hWnd, $sText)
Local $hUser32, $ilParam, $iVSCCode, $iDelay, $sChr, $iAsc, $iIndex
Local Const $WM_CHAR = 0x0102
If NOT IsHWnd($hWnd) OR NOT WinExists($hWnd) Then Return SetError(1, 0, 0)
If $sText == "" Then Return SetError(2, 0, 0)
$hUser32 = DllOpen("user32.dll")
If $hUser32 = -1 Then Return SetError(3, 0, 0)
Local Const $aVKList = _MakeVKList()
$iDelay = Opt("SendKeyDelay", 5)
Opt("SendKeyDelay", $iDelay)
For $i = 1 To StringLen($sText)
$sChr = StringMid($sText, $i, 1)
$iAsc = Asc($sChr)
If $iAsc < 32 OR $iAsc > 126 Then ContinueLoop
If StringRegExp($sChr, "^[!#\+\^\{\}]$") Then $sChr = "{" & $sChr & "}"
For $iIndex = 97 To UBound($aVKList) - 1
If $sChr == $aVKList[$iIndex][0] Then ExitLoop
Next
$iVSCCode = $aVKList[$iIndex][2]
$ilParam = _WinAPI_MakeLong(1, $iVSCCode)
_PostMessage($hWnd, $WM_CHAR, $iAsc, $ilParam, $hUser32)
Sleep($iDelay)
Next
DllClose($hUser32)
Return 1
EndFunc ;==>_WinSendText
Func _MakeVKList()
Local $hUser32, $sChar, $iVKCode, $iVSCCode, $iHiWord
Local Const $MAPVK_VK_TO_VSC = 0
Local Const $MAPVK_VSC_TO_VK = 1
Local Const $bExtend = 0x1000000
Local $aVKList[191][5] = [ _
["!", 0x12, 0, 0, 1], _ ; MOD_ALT
["+", 0x10, 0, 0, 4], _ ; MOD_SHIFT
["^", 0x11, 0, 0, 2], _ ; MOD_CONTROL
["#", 0x5B, 0, 0, 8], _ ; MOD_WIN
["{ALTDOWN}", 0x12], _ ; VK_MENU
["{ALTUP}", 0x12], _ ; VK_MENU
["{SHIFTDOWN}", 0x10], _ ; VK_SHIFT
["{SHIFTUP}", 0x10], _ ; VK_SHIFT
["{CTRLDOWN}", 0x11], _ ; VK_CONTROL
["{CTRLUP}", 0x11], _ ; VK_CONTROL
["{LWINDOWN}", 0x5B, 0, $bExtend], _ ; VK_LWIN
["{LWINUP}", 0x5B, 0, $bExtend], _ ; VK_LWIN
["{RWINDOWN}", 0x5C, 0, $bExtend], _ ; VK_RWIN
["{RWINUP}", 0x5C, 0, $bExtend], _ ; VK_RWIN
["{ASC}", 0x12, 0, 0, 1], _ ; VK_MENU
["{BREAK}", 0x03, 0, $bExtend, 2], _ ; VK_CANCEL
["{BACKSPACE}", 0x08], _ ; VK_BACK
["{BS}", 0x08], _ ; VK_BACK
["{TAB}", 0x09], _ ; VK_TAB
["{ENTER}", 0x0D], _ ; VK_RETURN
["{NUMPADENTER}", 0x0D, 0, $bExtend], _ ; VK_RETURN
["{ALT}", 0x12], _ ; VK_MENU
["{PAUSE}", 0x13], _ ; VK_PAUSE
["{CAPSLOCK}", 0x14], _ ; VK_CAPITAL
["{ESCAPE}", 0x1B], _ ; VK_ESCAPE
["{ESC}", 0x1B], _ ; VK_ESCAPE
["{SPACE}", 0x20], _ ; VK_SPACE
["{PGUP}", 0x21, 0, $bExtend], _ ; VK_PRIOR
["{PGDN}", 0x22, 0, $bExtend], _ ; VK_NEXT
["{END}", 0x23, 0, $bExtend], _ ; VK_END
["{HOME}", 0x24, 0, $bExtend], _ ; VK_HOME
["{LEFT}", 0x25, 0, $bExtend], _ ; VK_LEFT
["{UP}", 0x26, 0, $bExtend], _ ; VK_UP
["{RIGHT}", 0x27, 0, $bExtend], _ ; VK_RIGHT
["{DOWN}", 0x28, 0, $bExtend], _ ; VK_DOWN
["{PRINTSCREEN}", 0x2C], _ ; VK_SNAPSHOT
["{INSERT}", 0x2D, 0, $bExtend], _ ; VK_INSERT
["{INS}", 0x2D, 0, $bExtend], _ ; VK_INSERT
["{DELETE}", 0x2E, 0, $bExtend], _ ; VK_DELETE
["{DEL}", 0x2E, 0, $bExtend], _ ; VK_DELETE
["{LWIN}", 0x5B, 0, $bExtend], _ ; VK_LWIN
["{RWIN}", 0x5C, 0, $bExtend], _ ; VK_RWIN
["{APPSKEY}", 0x5D, 0, $bExtend], _ ; VK_APPS
["{SLEEP}", 0x5F], _ ; VK_SLEEP
["{NUMPAD0}", 0x60], _ ; VK_NUMPAD0
["{NUMPAD1}", 0x61], _ ; VK_NUMPAD1
["{NUMPAD2}", 0x62], _ ; VK_NUMPAD2
["{NUMPAD3}", 0x63], _ ; VK_NUMPAD3
["{NUMPAD4}", 0x64], _ ; VK_NUMPAD4
["{NUMPAD5}", 0x65], _ ; VK_NUMPAD5
["{NUMPAD6}", 0x66], _ ; VK_NUMPAD6
["{NUMPAD7}", 0x67], _ ; VK_NUMPAD7
["{NUMPAD8}", 0x68], _ ; VK_NUMPAD8
["{NUMPAD9}", 0x69], _ ; VK_NUMPAD9
["{NUMPADMULT}", 0x6A], _ ; VK_MULTIPLY
["{NUMPADADD}", 0x6B], _ ; VK_ADD
["{NUMPADSUB}", 0x6D], _ ; VK_SUBTRACT
["{NUMPADDOT}", 0x6E], _ ; VK_DECIMAL
["{NUMPADDIV}", 0x6F, 0, $bExtend], _ ; VK_DIVIDE
["{F1}", 0x70], _ ; VK_F1
["{F2}", 0x71], _ ; VK_F2
["{F3}", 0x72], _ ; VK_F3
["{F4}", 0x73], _ ; VK_F4
["{F5}", 0x74], _ ; VK_F5
["{F6}", 0x75], _ ; VK_F6
["{F7}", 0x76], _ ; VK_F7
["{F8}", 0x77], _ ; VK_F8
["{F9}", 0x78], _ ; VK_F9
["{F10}", 0x79], _ ; VK_F10
["{F11}", 0x7A], _ ; VK_F11
["{F12}", 0x7B], _ ; VK_F12
["{NUMLOCK}", 0x90, 0, $bExtend], _ ; VK_NUMLOCK
["{SCROLLLOCK}", 0x91], _ ; VK_SCROLL
["{LSHIFT}", 0xA0], _ ; VK_LSHIFT
["{RSHIFT}", 0xA1], _ ; VK_RSHIFT
["{LCTRL}", 0xA2], _ ; VK_LCONTROL
["{RCTRL}", 0xA3, 0, $bExtend], _ ; VK_RCONTROL
["{LALT}", 0xA4], _ ; VK_LMENU
["{RALT}", 0xA5, 0, $bExtend], _ ; VK_RMENU
["{BROWSER_BACK}", 0xA6], _ ; VK_BROWSER_BACK
["{BROWSER_FORWARD}", 0xA7], _ ; VK_BROWSER_FORWARD
["{BROWSER_REFRESH}", 0xA8], _ ; VK_BROWSER_REFRESH
["{BROWSER_STOP}", 0xA9], _ ; VK_BROWSER_STOP
["{BROWSER_SEARCH}", 0xAA], _ ; VK_BROWSER_SEARCH
["{BROWSER_FAVORITES}", 0xAB], _ ; VK_BROWSER_FAVORITES
["{BROWSER_HOME}", 0xAC], _ ; VK_BROWSER_HOME
["{VOLUME_MUTE}", 0xAD], _ ; VK_VOLUME_MUTE
["{VOLUME_DOWN}", 0xAE], _ ; VK_VOLUME_DOWN
["{VOLUME_UP}", 0xAF], _ ; VK_VOLUME_UP
["{MEDIA_NEXT}", 0xB0], _ ; VK_MEDIA_NEXT_TRACK
["{MEDIA_PREV}", 0xB1], _ ; VK_MEDIA_PREV_TRACK
["{MEDIA_STOP}", 0xB2], _ ; VK_MEDIA_STOP
["{MEDIA_PLAY_PAUSE}", 0xB3], _ ; VK_MEDIA_PLAY_PAUSE
["{LAUNCH_MAIL}", 0xB4], _ ; VK_LAUNCH_MAIL
["{LAUNCH_MEDIA}", 0xB5], _ ; VK_LAUNCH_MEDIA_SELECT
["{LAUNCH_APP1}", 0xB6], _ ; VK_LAUNCH_APP1
["{LAUNCH_APP2}", 0xB7]] ; VK_LAUNCH_APP2
$hUser32 = DllOpen("user32.dll")
If $hUser32 = -1 Then Return SetError(1, 0, 0)
For $i = 0 To 96
$aVKList[$i][2] = _MapVirtualKey($aVKList[$i][1], $MAPVK_VK_TO_VSC, $hUser32)
$aVKList[$i][3] = BitOR($aVKList[$i][3], 0)
$aVKList[$i][4] = BitOR($aVKList[$i][4], 0)
Next
$aVKList[22][2] = $aVKList[71][2] ; PAUSE key scan code is equal to NUM LOCK key
For $i = 33 To 126 ; printing characters, excluding space
$iVSCCode = _OemKeyScan($i, $hUser32)
If $iVSCCode = -1 Then ContinueLoop
$iHiWord = _WinAPI_HiWord($iVSCCode)
$iVSCCode = _WinAPI_LoWord($iVSCCode)
$iVKCode = _MapVirtualKey($iVSCCode, $MAPVK_VSC_TO_VK, $hUser32)
If $iVKCode = 0 Then ContinueLoop
$sChar = Chr($i)
If StringRegExp($sChar, "^[!#\+\^\{\}]$") Then $sChar = "{" & $sChar & "}"
$aVKList[$i - 33 + 97][0] = $sChar
$aVKList[$i - 33 + 97][1] = $iVKCode
$aVKList[$i - 33 + 97][2] = $iVSCCode
$aVKList[$i - 33 + 97][3] = 0
$aVKList[$i - 33 + 97][4] = 0
If BitAND($iHiWord, 1) Then $aVKList[$i - 33 + 97][4] = BitOR($aVKList[$i - 33 + 97][4], 4) ; SHIFT key is pressed
If BitAND($iHiWord, 2) Then $aVKList[$i - 33 + 97][4] = BitOR($aVKList[$i - 33 + 97][4], 2) ; CTRL key is pressed
If BitAND($iHiWord, 4) Then $aVKList[$i - 33 + 97][4] = BitOR($aVKList[$i - 33 + 97][4], 1) ; ALT key is pressed
Next
DllClose($hUser32)
Return $aVKList
EndFunc ;==>_MakeVKList
Func _PostMessage($hWnd, $iMsg, $iwParam, $ilParam, $vUser32 = "user32.dll")
Local $aResult
$aResult = DllCall($vUser32, "int", "PostMessage", "hwnd", $hWnd, "uint", $iMsg, "wparam", $iwParam, "lparam", $ilParam)
If @error Then Return SetError(@error, 0, 0)
Return $aResult[0]
EndFunc ;==>_PostMessage
Func _MapVirtualKey($iuCode, $iuMapType = 0, $vUser32 = "user32.dll")
Local $aResult
$aResult = DllCall($vUser32, "uint", "MapVirtualKey", "uint", $iuCode, "uint", $iuMapType)
If @error Then Return SetError(@error, 0, 0)
Return $aResult[0]
EndFunc ;==>_MapVirtualKey
Func _OemKeyScan($iwOemChar, $vUser32 = "user32.dll")
Local $aResult
$aResult = DllCall($vUser32, "dword", "OemKeyScan", "short", $iwOemChar)
If @error Then Return SetError(@error, 0, 0)
Return $aResult[0]
EndFunc ;==>_OemKeyScan
Func _GetKeyState($inVirtKey, $vUser32 = "user32.dll")
Local $aResult
$aResult = DllCall($vUser32, "short", "GetKeyState", "int", $inVirtKey)
If @error Then Return SetError(@error, 0, 0)
Return $aResult[0]
EndFunc ;==>_GetKeyState