Re: [BIG Tuto] Détection du client + Initialisation des case
[tab]1/- DETECTION DU CLIENT[/tab]
[tab][/tab][tab][/tab]1a - Récupérer la fenêtre active
Nous allons créer une fonction qui, lorsque nous l'appellerons, récupérera la classe, le titre, et le handle de la fenêtre active, comparera avec ceux d'une fenêtre Dofus, et renverra le résultat.
Elle créera des variables $hHwnd_Active, $sTitle, et $sClass auxquelles nous voudrons accéder en Global. Donc ajoutez ces 3 variables dans les déclarations des variables en haut du fichier :
Global $sTitle, _
$hHwnd_Active, _
$sClass
Cette fonction, je l'appellerai SetWnd :
Func SetWnd()
$hHwnd_Active = WinGetHandle("[ACTIVE]")
$sTitle = WinGetTitle($hHwnd_Active)
$sClass = GetClassName($hHwnd_Active)
Debug("Handle => " & $hHwnd_Active & @CRLF & _
"Title => " & $sTitle & @CRLF & _
"ClassName => " & $sClass)
Switch $sClass
Case "ApolloRuntimeContentWindow"
Switch $sTitle
Case "Dofus"
SetError(1)
Return $sTitle
Case Else
Return $hHwnd_Active
EndSwitch
Case Else
SetError(2)
Return $sClass
EndSwitch
EndFunc
$hHwnd_Active = WinGetHandle("[ACTIVE]") récupère le handle de la fenêtre active. D'où l'intérêt d'attribuer cette fonction SetWnd à un raccourci clavier.
$sTitle = WinGetTitle($hHwnd_Active) récupère le titre de cette fenêtre active.
$sClass = GetClassName($hHwnd_Active) récupère le nom de la classe.
D'ailleurs, voici cette fonction GetClassName, que j'ai récupéré sur le net :
Cliquez pour révéler
Cliquez pour masquer
Func GetClassName($hWnd)
Local $aResult, $Length, $stText, $Text
$Length = 4096
$stText = DllStructCreate ("char[" & $Length & "]")
$aResult = DllCall("User32.dll", "int", "GetClassName", "hwnd", $hWnd, "ptr", DllStructGetPtr($stText), "int", $Length)
$Text = DllStructGetData($stText,1)
$stText = 0
Return $Text
EndFunc
Ensuite, on vérifie si la classe est bien "ApolloRuntimeContentWindow", qui est la classe de D. Si c'est le cas, on vérifie que le personnage est connecté en vérifiant le titre (qui ne doit donc pas être D.)
Bien sûr, remplacez les D. par le nom du jeu.
Bien, maintenant nous avons une fonction qui vérifie si tout est correct. Si la classe ne correspond pas, alors on initialise @error à 2 et on retourne la classe. Si le titre est mauvais, on initialise @error à 1, et on retourne le titre. En revanche, si tout est correct, on retourne le handle de la fenêtre, donc du jeu.
Attachons donc cette fonction à un raccourci clavier, pour tester si tout est correct. Tapez ce code sous le premier raccourci.
HotKeySet("{F2}", "SetWnd")
Lorsque vous appuyez sur F2, vous voyez, dans la console AutoIt, les informations de la fenêtre. Soit son handle, son titre, et sa classe.
[tab][/tab][tab][/tab]1b - Récupérer la position et les mesures de la fenêtre
Maintenant que nous avons le handle de la bonne fenêtre, nous devons récupérer sa position, et ses mesures, pour savoir où nous devrons cliquer, etc.
Nous appellerons cette fonction GetClientMeasures(). Nous aurons besoin d'inclure, pour son fonctionnement, deux fichiers. Tout en haut de votre fichier, tapez ces lignes :
#include <WinAPI.au3>
#include <WindowsConstants.au3>
Ensuite, créons notre fonction :
Func GetClientMeasures()
EndFunc
Premièrement, nous allons enregistrer dans une variable $aMeasures les mesures du client, et dans une autre variable $aClient_Pos la position de ce client.
$aMeasures = WinGetClientSize($sTitle)
$aClient_Pos = WinGetPos($sTitle)
$aMeasures et $aClient_Pos sont des Arrays. $aMeasures est un Array de 2 lignes. La première contient la largeur, la seconde la hauteur. Nous allons donc, pour une meilleure lisibilité pour la suite, enregistrer ces valeurs dans des variables séparées, en Global :
Global $iClient_Width = $aMeasures[0]
Global $iClient_Height = $aMeasures[1]
Le problème maintenant, est que nous voulons récupérer la taille du client sans les bords. Il existe une fonction qui devrait nous retourner la largeur d'un bord, mais après différents tests avec différentes personnes, la valeur n'est jamais exacte. Alors je vous donne le code, mais vous devrez certainement l'adapter chez vous.
/!\ C'est très important pour la suite !!
$iBorderSize_Y = _WinAPI_GetSystemMetrics($SM_CYEDGE) + 2
$iBorderSize_X = _WinAPI_GetSystemMetrics($SM_CXEDGE) + 2
$iHeight_TitleBar = _WinAPI_GetSystemMetrics($SM_CYCAPTION) + $iBorderSize_Y
C'est les " + 2" que vous devrez modifier chez vous.
Comme vous l'aurez certainement deviné, le client commence à $aClient_Pos[0]. Mais comme nous ne voulons pas des bords, alors nous pouvons en déduire qu'il commence à $aClient_Pos[0] + $iBorderSize_X. Nous devons maintenant calculer la position X de fin. Nous avons la largeur de la fenêtre, la largeur d'un bord, et la position X de départ. Donc nous pouvons en déduire que :
Global $iClient_Left = $aClient_Pos[0] + $iBorderSize_X
Global $iClient_Right = $iClient_Left + $iClient_Width
Nous devons faire la même chose pour Y. Je vous donne le code, à mon avis ça ne sera pas utile d'expliquer :
Global $iClient_Top = $aClient_Pos[1] + $iHeight_TitleBar
Global $iClient_Bottom = $iClient_Top + $iClient_Height
Je vais vous donner une fonction que j'ai créée pour que que vous voyiez le résultat. Elle dessine sur l'écran soit un rectangle, soit les diagonales, soit une ligne, soit une zone qui est un mélange d'un rectangle et de deux diagonales. Elle vérifie si la variable $bDebug_Lines est sur True ou False, donc vous devez créer cette variable. Créez-la près des autres variables de debug :
$bDebug_Lines = True
Et donc, la fonction DrawLines au complet. Je ne l'expliquerai pas, c'est juste un utilitaire, et c'est hyper simple :
Cliquez pour révéler
Cliquez pour masquer
Func DrawLines($iXS, $iYS, $iXE, $iYE, $sWhat = "line", $cColor = 0x000000)
Switch $bDebug
Case True
Switch $bDebug_Lines
Case True
Global $hDC = _WinAPI_GetWindowDC($sTitle) ;; On récupère le handle du context
Global $hPen = _WinAPI_CreatePen($PS_SOLID, 2, $cColor) ;; On crée notre Pen avec la couleur passée en paramètre
Global $obj_orig = _WinAPI_SelectObject($hDC, $hPen) ;; On assemble le tout
Switch $sWhat
Case "line"
_WinAPI_DrawLine($hDC, $iXS, $iYS, $iXE, $iYE)
Case "zone"
DrawLines($iXS, $iYS, $iXE, $iYE, "quad", $cColor)
DrawLines($iXS, $iYS, $iXE, $iYE, "diagonale", $cColor)
Case "diagonale"
_WinAPI_DrawLine($hDC, $iXS, $iYS, $iXE, $iYE) ;; De haut à gauche jusque bas à droite
_WinAPI_DrawLine($hDC, $iXE, $iYS, $iXS, $iYE) ;; De bas à droite jusque haut à gauche
Case "quad"
_WinAPI_DrawLine($hDC, $iXS, $iYS, $iXE, $iYS) ;; De haut à gauche jusque haut à droite ---
_WinAPI_DrawLine($hDC, $iXE, $iYS, $iXE, $iYE) ;; De haut à droite jusque bas à droite |
_WinAPI_DrawLine($hDC, $iXE, $iYE, $iXS, $iYE) ;; De bas à droite jusque bas à gauche ___
_WinAPI_DrawLine($hDC, $iXS, $iYE, $iXS, $iYS) ;; De bas à gauche jusque haut à gauche |
Case "else"
Debug("La forme que vous essayez de créer n'existe pas")
EndSwitch
Case False
Debug("Le debug Lines n'est pas activé")
EndSwitch
Case False
Debug("Le debug n'est pas activé")
EndSwitch
EndFunc
Appelez donc cette fonction à la fin de GetClientMeasures() :
DrawLines($iClient_Left, $iClient_Top, $iClient_Right, $iClient_Bottom, "zone", 0x0000FF)
Vous voyez, c'est très simple. Maintenant que notre fonction GetClientMeasures est terminée, nous pouvons créer un raccourci qui l'appellera. Ajoutez donc sous les autres HotKeySet :
HotKeySet("{F3}", "GetClientMeasures")
Voilà, nous avons terminé la partie 1b ! Vous devriez avoir ce code. Si ce n'est pas le cas, c'est que vous avez dû louper quelque chose, auquel cas il vaudrait mieux que vous preniez ce code ! :P
Cliquez pour révéler
Cliquez pour masquer
#include <WinAPI.au3>
#include <WindowsConstants.au3>
Global $bDebug = True, _
$bDebug_Console = True, _
$bDebug_Tray = True, _
$bDebug_Lines = True
Global $sTitle, _
$hHwnd_Active, _
$sClass
HotKeySet("{ESC}", "Quit")
HotKeySet("{F2}", "SetWnd")
HotKeySet("{F3}", "GetClientMeasures")
While 1
Sleep(250)
WEnd
Func GetClientMeasures()
$aMeasures = WinGetClientSize($sTitle)
$aClient_Pos = WinGetPos($sTitle)
Global $iClient_Width = $aMeasures[0]
Global $iClient_Height = $aMeasures[1]
$iBorderSize_Y = _WinAPI_GetSystemMetrics($SM_CYEDGE) + 2
$iBorderSize_X = _WinAPI_GetSystemMetrics($SM_CXEDGE) + 2
$iHeight_TitleBar = _WinAPI_GetSystemMetrics($SM_CYCAPTION) + $iBorderSize_Y
Global $iClient_Left = $aClient_Pos[0] + $iBorderSize_X
Global $iClient_Right = $iClient_Left + $iClient_Width
Global $iClient_Top = $aClient_Pos[1] + $iHeight_TitleBar
Global $iClient_Bottom = $iClient_Top + $iClient_Height
DrawLines($iClient_Left, $iClient_Top, $iClient_Right, $iClient_Bottom, "zone", 0x0000FF)
Return 1
EndFunc
Func SetWnd()
$hHwnd_Active = WinGetHandle("[ACTIVE]")
$sTitle = WinGetTitle($hHwnd_Active)
$sClass = GetClassName($hHwnd_Active)
Debug("Handle => " & $hHwnd_Active & @CRLF & _
"Title => " & $sTitle & @CRLF & _
"ClassName => " & $sClass)
Switch $sClass
Case "ApolloRuntimeContentWindow"
Switch $sTitle
Case "Dofus"
SetError(1)
Return $sTitle
Case Else
Return $hHwnd_Active
EndSwitch
Case Else
SetError(2)
Return $sClass
EndSwitch
EndFunc
Func GetClassName($hWnd)
Local $aResult, $Length, $stText, $Text
$Length = 4096
$stText = DllStructCreate ("char[" & $Length & "]")
$aResult = DllCall("User32.dll", "int", "GetClassName", "hwnd", $hWnd, "ptr", DllStructGetPtr($stText), "int", $Length)
$Text = DllStructGetData($stText,1)
$stText = 0
Return $Text
EndFunc
Func DrawLines($iXS, $iYS, $iXE, $iYE, $sWhat = "line", $cColor = 0x000000)
Switch $bDebug
Case True
Switch $bDebug_Lines
Case True
Global $hDC = _WinAPI_GetWindowDC($sTitle) ;; On récupère le handle du context
Global $hPen = _WinAPI_CreatePen($PS_SOLID, 2, $cColor) ;; On crée notre Pen avec la couleur passée en paramètre
Global $obj_orig = _WinAPI_SelectObject($hDC, $hPen) ;; On assemble le tout
Switch $sWhat
Case "line"
_WinAPI_DrawLine($hDC, $iXS, $iYS, $iXE, $iYE)
Case "zone"
DrawLines($iXS, $iYS, $iXE, $iYE, "quad", $cColor)
DrawLines($iXS, $iYS, $iXE, $iYE, "diagonale", $cColor)
Case "diagonale"
_WinAPI_DrawLine($hDC, $iXS, $iYS, $iXE, $iYE) ;; De haut à gauche jusque bas à droite
_WinAPI_DrawLine($hDC, $iXE, $iYS, $iXS, $iYE) ;; De bas à droite jusque haut à gauche
Case "quad"
_WinAPI_DrawLine($hDC, $iXS, $iYS, $iXE, $iYS) ;; De haut à gauche jusque haut à droite ---
_WinAPI_DrawLine($hDC, $iXE, $iYS, $iXE, $iYE) ;; De haut à droite jusque bas à droite |
_WinAPI_DrawLine($hDC, $iXE, $iYE, $iXS, $iYE) ;; De bas à droite jusque bas à gauche ___
_WinAPI_DrawLine($hDC, $iXS, $iYE, $iXS, $iYS) ;; De bas à gauche jusque haut à gauche |
Case "else"
Debug("La forme que vous essayez de créer n'existe pas")
EndSwitch
Case False
Debug("Le debug Lines n'est pas activé")
EndSwitch
Case False
Debug("Le debug n'est pas activé")
EndSwitch
EndFunc
Func Debug($sMessage)
Switch $bDebug
Case True
Switch $bDebug_Console
Case True
ConsoleWrite("->=======================================================================" & @LF)
ConsoleWrite($sMessage & @LF)
ConsoleWrite("->=======================================================================" & @LF & @LF)
EndSwitch
Switch $bDebug_Tray
Case True
TrayTip("DEBUG", $sMessage, 2)
EndSwitch
EndSwitch
EndFunc
Func Quit()
Debug("ESCAPE key pressed : Exiting")
Sleep(1500)
Exit
EndFunc