Войти

Показать полную графическую версию : Управление клавиатуры/мышки в фоновое приложение (чтоб не влияло на активное приложе)


kagorec
26-05-2009, 19:35
Управление нажатием кнопок клавиатуры и мышки, передвижение курсора в активном приложении это легко, а как быть со свернутым приложением. Несколько полезных решений для игр было сделано благодаря хорошему гайду .chm, офф форуму и oszone форуму.
Но как передовать нажите/передвижение мышки на фоновое приложение так и не нашел - возможно-ли?
Задача: Онлайн Игра свернута нажатием "кнопкой Windows" или "Alt+tab" и там по центру эккрана происходят клик мышки
Подскажите пожалста, если можно приведите пример кода или описание функций...

kagorec
27-05-2009, 16:22
WinGetHandle работает но не так как надо сворачивать нелья а только на фоне оставить игру.
#Include <WinAPI.au3>

$hWnd = WinGetHandle("Name game title")
_SendMessage($hWnd, 0x6, 0x1)
ControlSend($hWnd, "", "", "{F1}")
_SendMessage($hWnd, 0x6, 0x1)

SyDr
27-05-2009, 17:15
Есть ещё фишка, что некоторые игры в свёрнутом состоянии вообще на сообщения не реагируют. Точнее реагируют, но ничего не делают)))

kagorec
27-05-2009, 18:00
Хадл окна в корейских шрифтах и когда их пытается скрипт считать то одни вопросики.
Наклепал следующее (некоторые строки из ру-боард)
; из нашего процесса берем ид...
$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

Засылает нажатия лкм, пкм и их перетаскивания в свернутое/скрытое другими окно

kagorec
31-05-2009, 05:01
Может я чтото не так делаю но код вообще не запускается, в процессах имя приложения 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". Работали в свернутом режиме нажатия и перетаскивания, но не всегда точно.

r35p3ct
24-09-2009, 20:00
Пробывал _MouseClickPlus() в разных приложениях, и ничего, клик вообще не происходит. В чем может быть подвох?




© OSzone.net 2001-2012