PostMessage到底能不能发送组合键?
最近在写一个向指定窗口发送按键的UDF,打算用PostMessage完全实现Send函数所有功能。但是被组合键郁闷到了。比如发送大写字母A,应该是先WM_KEYDOWN一次VK_SHIFT,再WM_KEYDOWN一次VK_A,最后WM_KEYUP释放两个键。但是最终结果,窗口只出现一个小写字母a。也就是说,窗口根本不管之前发送的VK_SHIFT。
用Spy++查看键盘消息,发现手动按键和程序发送一模一样(见下)。就是结果不一样。。。
google一下“PostMessage 组合键”,发现csdn,看雪,vbgood几个地方早有人讨论这个问题,结论是PostMessage按键时,窗口是直接读取当前VK_SHIFT状态,而不管之前是否收到VK_SHIFT的WM_KEYDOWN消息。解决方法有几个。一是keybd_event(SendInput,或者au3的Send也行)先发送一个VK_SHIFT按下消息,再发送按键,缺点是这会影响到同时运行的别的程序。还有更复杂的,hook几个返回键盘状态的api,让它们返回VK_SHIFT已被按下的假象,缺点就不用说了,太复杂,从效率来说还不如直接Send。
没信心了,现在在尝试WM_HOTKEY。如果有朋友也研究过这个问题,请指点一下。
Spy++拦截到的消息,模拟对象为记事本。WM_CHAR是自动产生的,可以看出结果不一样。
手动按键:
<00001> 00020470 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00002> 00020470 P WM_KEYDOWN nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00003> 00020470 P WM_CHAR chCharCode:'0041' (65) cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00004> 00020470 P WM_KEYUP nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<00005> 00020470 P WM_KEYUP nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:1
程序发送:
<00006> 00020470 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00007> 00020470 P WM_KEYDOWN nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00008> 00020470 P WM_CHAR chCharCode:'0061' (97) cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<00009> 00020470 P WM_KEYUP nVirtKey:'A' cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<00010> 00020470 P WM_KEYUP nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:1 http://blogs.msdn.com/oldnewthing/archive/2005/05/30/423202.aspx
You can't simulate keyboard input with PostMessage
汗~~~几天前搜索相关资料时就发现这篇文章了,只是英文基础太差,当时就没细看。今天又读了一遍,才明白这个问题无解。原来这几天我是在扮演阿汤哥,上演一出“不可能的任务”。。。 额 不用封装了 有人写好了 直接用就是了
http://www.shynd.com/scripts/PostMessage_UDF.au3
至于组合键 你看下里面好像有shift的 3# sxd
PostMessage_UDF写得太简单了。比如功能键,它只支持ENTER、TAB、ESC、F5、F12这5个,还有4个不兼容Send的光标键。组合键只考虑SHIFT,而且经测试是无效的。按键等待,它只用1而不用au3定义的SendKeyDelay等参数。
它上面的注释写明了Written by Shynd for use with DA,这个DA是Dark Ages,一款2D网游。所以它里面那些_MouseUseSpell等函数其实是针对Dark Ages游戏里操作设计的,我刚开始还想了大半天,搞不懂它为什么要去点547, 400这个坐标。里面可用的就是_MouseClick、_SendKeys、_SendText这3个,而且还都存在一些问题。
我就是看了PostMessage_UDF才想到写一个能完全实现Send函数所有功能的UDF。为此还创建了一个包含Send定义、按键虚拟码、扫描码对应关系的190项数组,完成了扩展键、ALT键、重复按键、发送ASC字符、保持CapsLock状态等一大堆杂七杂八的功能。只是没想到会卡在组合键上,最后才知道这是PostMessage做不到的事。。。白白浪费了3天时间啊。。。 是的 那些他针对da用的 usespell的 就无视了
把你写好的发上来吧 如果做不到组合键,能起的作用实在太小,废品就不发了。。。 不小啊 后台按键 后台鼠标 都是游戏要用到的功能 加上后台找色 一个简单的辅助 就完成了
不过我用shynd写的那个UDF也能实现后台按键 鼠标 至于你说的 写的太简单 是说的哪方面呢? 7# sxd
额,我还是放出代码吧。组合键暂时用Send发送组合键消息来代替。代码只是半成品,还没怎么优化,感觉太复杂了,我自己都头晕。。。#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
$iY = $aPos
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
$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] Then ExitLoop
Next
$sStr = ""
If $iIndex > UBound($aVKList) - 1 Then ContinueLoop
$iModifier = BitOR($iModifier, $aVKList[$iIndex])
Switch $iIndex
Case 0 To 3 ; modifier key
ContinueLoop
Case 4 To 13 ; modifier key down or up
$iModifier = 0
$sRepeat = StringRegExpReplace($aVKList[$iIndex], "^{[[:graph:]]+(DOWN|UP)}$", "\1")
$sRepeat = StringLower($sRepeat)
Case 14 ; send the ASCII characters
$iModifier = $aVKList[$iIndex]
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
$iVSCCode = $aVKList
$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]
$iVSCCode = $aVKList[$iIndex]
$iExtend = $aVKList[$iIndex]
$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], 1) & $sRepeat & "}"
Send($sRepeat)
Case $iModifier <> 0 AND $iMode = 2 ; post WM_HOTKEY message
$iVKCode = $aVKList[$iIndex]
$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]
$iVSCCode = $aVKList[$iIndex]
$iExtend = $aVKList[$iIndex]
$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
$iVSCCode = $aVKList
$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] Then ExitLoop
Next
$iVSCCode = $aVKList[$iIndex]
$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 = [ _
["!", 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] = _MapVirtualKey($aVKList[$i], $MAPVK_VK_TO_VSC, $hUser32)
$aVKList[$i] = BitOR($aVKList[$i], 0)
$aVKList[$i] = BitOR($aVKList[$i], 0)
Next
$aVKList = $aVKList ; 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] = $sChar
$aVKList[$i - 33 + 97] = $iVKCode
$aVKList[$i - 33 + 97] = $iVSCCode
$aVKList[$i - 33 + 97] = 0
$aVKList[$i - 33 + 97] = 0
If BitAND($iHiWord, 1) Then $aVKList[$i - 33 + 97] = BitOR($aVKList[$i - 33 + 97], 4) ; SHIFT key is pressed
If BitAND($iHiWord, 2) Then $aVKList[$i - 33 + 97] = BitOR($aVKList[$i - 33 + 97], 2) ; CTRL key is pressed
If BitAND($iHiWord, 4) Then $aVKList[$i - 33 + 97] = BitOR($aVKList[$i - 33 + 97], 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
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
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
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
EndFunc ;==>_GetKeyState 有个问题我用postmessage的时候 无法实现双击 click设置2的话 只是快速点2下 无法形成双击
如何解决呢 本帖最后由 sensel 于 2009-5-23 19:38 编辑
9# sxd
确实如此。有一个折衷的办法,直接发送WM_LBUTTONDBLCLK之类的消息产生双击。
但是如果$iClicks = 3该怎么办呢?是发送一个双击再跟一个单击,还是直接发送3个单击?
PostMessage限制实在太多了,我总觉得不实用。 改了一下_WinMouseClick,用BUTTONDBLCLK发送双击。使用先双击再单击的方法。Func _WinMouseClick($hWnd, $sButton = "left", $iX = "", $iY = "", $iClicks = 1)
Local $hUser32, $ilParam, $bButton, $bButtonDown, $bButtonUp, $bButtonDblClk
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_LBUTTONDBLCLK = 0x0203
Local Const $WM_RBUTTONDOWN = 0x0204
Local Const $WM_RBUTTONUP = 0x0205
Local Const $WM_RBUTTONDBLCLK = 0x0206
Local Const $WM_MBUTTONDOWN = 0x0207
Local Const $WM_MBUTTONUP = 0x0208
Local Const $WM_MBUTTONDBLCLK = 0x0209
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
$bButtonDblClk = $WM_LBUTTONDBLCLK
Case "right"
$bButton = $MK_RBUTTON
$bButtonDown = $WM_RBUTTONDOWN
$bButtonUp = $WM_RBUTTONUP
$bButtonDblClk = $WM_RBUTTONDBLCLK
Case "middle"
$bButton = $MK_MBUTTON
$bButtonDown = $WM_MBUTTONDOWN
$bButtonUp = $WM_MBUTTONUP
$bButtonDblClk = $WM_MBUTTONDBLCLK
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
$iY = $aPos
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 Int($iClicks / 2)
_PostMessage($hWnd, $WM_MOUSEMOVE, 0, $ilParam, $hUser32)
_PostMessage($hWnd, $bButtonDblClk, $bButton, $ilParam, $hUser32)
Sleep($iDelay)
Next
If Mod($iClicks, 2) Then
_PostMessage($hWnd, $WM_MOUSEMOVE, 0, $ilParam, $hUser32)
_PostMessage($hWnd, $bButtonDown, $bButton, $ilParam, $hUser32)
Sleep($iDownDelay)
_PostMessage($hWnd, $bButtonUp, $bButton, $ilParam, $hUser32)
EndIf
DllClose($hUser32)
Return 1
EndFunc ;==>_WinMouseClick au3 往游戏辅助 外挂 方面发展下 还是有必要的
希望可以研究下 后台找图 找色 正在研究QQ农场的后台操作,这个flash的类句柄怎么获得啊? alt+组合键可以吗? 人气太淡了。
页:
[1]
2