Показать полную графическую версию : Управление клавиатуры/мышки в фоновое приложение (чтоб не влияло на активное приложе)
Управление нажатием кнопок клавиатуры и мышки, передвижение курсора в активном приложении это легко, а как быть со свернутым приложением. Несколько полезных решений для игр было сделано благодаря хорошему гайду .chm, офф форуму и oszone форуму.
Но как передовать нажите/передвижение мышки на фоновое приложение так и не нашел - возможно-ли?
Задача: Онлайн Игра свернута нажатием "кнопкой Windows" или "Alt+tab" и там по центру эккрана происходят клик мышки
Подскажите пожалста, если можно приведите пример кода или описание функций...
WinGetHandle работает но не так как надо сворачивать нелья а только на фоне оставить игру.
#Include <WinAPI.au3>
$hWnd = WinGetHandle("Name game title")
_SendMessage($hWnd, 0x6, 0x1)
ControlSend($hWnd, "", "", "{F1}")
_SendMessage($hWnd, 0x6, 0x1)
Есть ещё фишка, что некоторые игры в свёрнутом состоянии вообще на сообщения не реагируют. Точнее реагируют, но ничего не делают)))
Хадл окна в корейских шрифтах и когда их пытается скрипт считать то одни вопросики.
Наклепал следующее (некоторые строки из ру-боард)
; из нашего процесса берем ид...
$sWindow = _ProcessGetWindow("сclient.exe", 1)
ConsoleWrite($sWindow & @CRLF)
Func _ProcessGetWindow($iPID, $iRet=-1)
Local $aWinList = WinList()
Local $aRet[2]
If IsString($iPID) Then $iPID = ProcessExists($iPID)
For $i = 1 To UBound($aWinList)-1
If WinGetProcess($aWinList[$i][1]) = $iPID Then
$aRet[0] = $aWinList[$i][0] ;Title
$aRet[1] = $aWinList[$i][1] ;WinHandle
If $iRet = 0 Then Return $aRet[0]
If $iRet = 1 Then Return $aRet[1]
Return $aRet
EndIf
Next
Return SetError(1, 0, $aRet)
EndFunc
; отправка нажатия кнопки 4 в окно игры
$hWnd = WinGetHandle("$sWindow")
_SendMessage($hWnd, 0x6, 0x1)
ControlSend($hWnd, "", "", "4")
_SendMessage($hWnd, 0x6, 0x1)
Пробовал макро-автозапись програмку использовать так там непонимает корейского.
Opt("WinTitleMatchMode", 4)
WinWait("ES Update Client","")
ControlClick("ES Update Client","","XYPatcherClass0")
WinWait("????","")
ControlClick("????","","XYElementClient Window0")
ControlClick("????","","XYElementClient Window0")
ControlClick("????","","XYElementClient Window0")
Belfigor
30-05-2009, 06:07
Ты бы лучше название игры давал, было бы более эфективно :). Если разобрался как как получить заголовок игры к которому можно будет обратиться можешь использовать этот код:
;===============================================================================
;
; Function Name: _MouseClickPlus()
; Version added: 0.1
; Description: Sends a click to window, not entirely accurate, but works
; minimized.
; Parameter(s): $Window = Title of the window to send click to
; $Button = "left" or "right" mouse button
; $X = X coordinate
; $Y = Y coordinate
; $Clicks = Number of clicks to send
; Remarks: You MUST be in "MouseCoordMode" 0 to use this without bugs.
; Author(s): Insolence <insolence_9@yahoo.com>
;
;===============================================================================
Func _MouseClickPlus($Window, $Button = "left", $X = "", $Y = "", $Clicks = 1)
Local $MK_LBUTTON = 0x0001
Local $WM_LBUTTONDOWN = 0x0201
Local $WM_LBUTTONUP = 0x0202
Local $MK_RBUTTON = 0x0002
Local $WM_RBUTTONDOWN = 0x0204
Local $WM_RBUTTONUP = 0x0205
Local $WM_MOUSEMOVE = 0x0200
Local $i = 0
Select
Case $Button = "left"
$Button = $MK_LBUTTON
$ButtonDown = $WM_LBUTTONDOWN
$ButtonUp = $WM_LBUTTONUP
Case $Button = "right"
$Button = $MK_RBUTTON
$ButtonDown = $WM_RBUTTONDOWN
$ButtonUp = $WM_RBUTTONUP
EndSelect
If $X = "" OR $Y = "" Then
$MouseCoord = MouseGetPos()
$X = $MouseCoord[0]
$Y = $MouseCoord[1]
EndIf
For $i = 1 to $Clicks
DllCall("user32.dll", "int", "SendMessage", _
"hwnd", WinGetHandle( $Window ), _
"int", $WM_MOUSEMOVE, _
"int", 0, _
"long", _MakeLong($X, $Y))
DllCall("user32.dll", "int", "SendMessage", _
"hwnd", WinGetHandle( $Window ), _
"int", $ButtonDown, _
"int", $Button, _
"long", _MakeLong($X, $Y))
DllCall("user32.dll", "int", "SendMessage", _
"hwnd", WinGetHandle( $Window ), _
"int", $ButtonUp, _
"int", $Button, _
"long", _MakeLong($X, $Y))
Next
EndFunc
Func _MakeLong($LoWord,$HiWord)
Return BitOR($HiWord * 0x10000, BitAND($LoWord, 0xFFFF))
EndFunc
Засылает нажатия лкм, пкм и их перетаскивания в свернутое/скрытое другими окно
Может я чтото не так делаю но код вообще не запускается, в процессах имя приложения ElementClient.exe вот с него берется PID который нужен в дальнейшем для _MouseClickPlus
;===============================================================================
;
; Function Name: _MouseClickPlus()
; Version added: 0.1
; Description: Sends a click to window, not entirely accurate, but works
; minimized.
; Parameter(s): $Window = Title of the window to send click to
; $Button = "left" or "right" mouse button
; $X = X coordinate
; $Y = Y coordinate
; $Clicks = Number of clicks to send
; Remarks: You MUST be in "MouseCoordMode" 0 to use this without bugs.
; Author(s): Insolence <insolence_9@yahoo.com>
;
;===============================================================================
HotKeySet ("{HOME}", "_MouseClickPlus" )
HotkeySet ("{END}", "_MakeLong" )
; из нашего процесса берем ид...
$Window = _ProcessGetWindow("ElementClient.exe", 1)
ConsoleWrite($Window & @CRLF)
Func _ProcessGetWindow($iPID, $iRet=-1)
Local $aWinList = WinList()
Local $aRet[2]
If IsString($iPID) Then $iPID = ProcessExists($iPID)
For $i = 1 To UBound($aWinList)-1
If WinGetProcess($aWinList[$i][1]) = $iPID Then
$aRet[0] = $aWinList[$i][0] ;Title
$aRet[1] = $aWinList[$i][1] ;WinHandle
If $iRet = 0 Then Return $aRet[0]
If $iRet = 1 Then Return $aRet[1]
Return $aRet
EndIf
Next
Return SetError(1, 0, $aRet)
EndFunc
Func _MouseClickPlus($Window, $Button = "left", $X = "", $Y = "", $Clicks = 1000)
Local $MK_LBUTTON = 0x0001
Local $WM_LBUTTONDOWN = 0x0201
Local $WM_LBUTTONUP = 0x0202
Local $MK_RBUTTON = 0x0002
Local $WM_RBUTTONDOWN = 0x0204
Local $WM_RBUTTONUP = 0x0205
Local $WM_MOUSEMOVE = 0x0200
Local $i = 0
Select
Case $Button = "left"
$Button = $MK_LBUTTON
$ButtonDown = $WM_LBUTTONDOWN
$ButtonUp = $WM_LBUTTONUP
Case $Button = "right"
$Button = $MK_RBUTTON
$ButtonDown = $WM_RBUTTONDOWN
$ButtonUp = $WM_RBUTTONUP
EndSelect
If $X = "" OR $Y = "" Then
$MouseCoord = MouseGetPos()
$X = $MouseCoord[0]
$Y = $MouseCoord[1]
EndIf
For $i = 1 to $Clicks
DllCall("user32.dll", "int", "SendMessage", _
"hwnd", WinGetHandle( $Window ), _
"int", $WM_MOUSEMOVE, _
"int", 0, _
"long", _MakeLong($X, $Y))
DllCall("user32.dll", "int", "SendMessage", _
"hwnd", WinGetHandle( $Window ), _
"int", $ButtonDown, _
"int", $Button, _
"long", _MakeLong($X, $Y))
DllCall("user32.dll", "int", "SendMessage", _
"hwnd", WinGetHandle( $Window ), _
"int", $ButtonUp, _
"int", $Button, _
"long", _MakeLong($X, $Y))
Next
EndFunc
Func _MakeLong($LoWord,$HiWord)
Return BitOR($HiWord * 0x10000, BitAND($LoWord, 0xFFFF))
EndFunc
...ммм пока писал, понел что wingethandle нужен не пид а титлы значит его надо сменить на WinGetProcess
По правильному пути пошел хз )) поправьте пожалста...
п.с. решение нашел для uopilot (програмка для написания автоматизированных действий игры) где достаточно указать pid и в фоновом режиме идет нажатия клавишь, независимо что вы делаете в активном/другом приложении. НО предпочтение всетаки отдаю AutoIT так немного освоил и гайды подробнее.
Belfigor
31-05-2009, 12:13
не работал с _ProcessGetWindow не знаю что он возвращает, тебе нужен заголовок окна. Я использовал для EVE Online. Заголовок окна там "EVE". Работали в свернутом режиме нажатия и перетаскивания, но не всегда точно.
Пробывал _MouseClickPlus() в разных приложениях, и ничего, клик вообще не происходит. В чем может быть подвох?
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.