Page 1 sur 1
[..] Déplacer deux fenêtres en même temps
Posté : mer. 21 mai 2014 16:12
par pumilio
Bonjour,
Est-il possible de déplacer la fenêtre d'un logiciel (notepad.exe par exemple) en même temps qu'une Gui ?
Je souhaiterais que lorsque je déplace ma Gui sur l'écran avec la souris cela fasse également bouger la fenêtre notepad.exe en parallèle (même mouvement, même nombre de pixel) ? Je n'ai pas trouvé de piste de départ

.
Merci.
Re: [..] Déplacer deux fenêtres en même temps
Posté : mer. 21 mai 2014 16:32
par TommyDDR
Vous pouvez utiliser GUIRegisterMsg dans cet exemple j'ai utilisé le paramètre envoyé à WM_COMMAND pour récupérer la position x et y de la zone cliente de la fenêtre déplacée, cela ne correspond dont pas à la position de la fenêtre dans son ensemble, mais rien ne vous empêche de récupérer sa position avec WinGetPos.
► Afficher le textecode
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#pragma compile(Icon, C:\Program Files (x86)\AutoIt3\Icons\au3.ico)
Opt("MustDeclareVars", 1)
Opt("GuiOnEventMode", 1)
Opt("WinTitleMatchMode", 2)
Global $gui
Global $taille[2] = [300, 300]
$gui = GUICreate("", $taille[0], $taille[1])
GUISetOnEvent($GUI_EVENT_CLOSE, "quit", $gui)
GUISetState(@SW_SHOW, $gui)
GUIRegisterMsg($WM_MOVE, WM_MOVE)
While(True)
Sleep(10)
WEnd
Func WM_MOVE($hWnd, $msg, $wParam, $lParam)
Local $y = _WinAPI_HiWord($lParam)
Local $x = _WinAPI_LoWord($lParam)
Local $notepad = WinGetHandle("Notepad")
If($x > 60000) Then $x -= 0x10000
If($y > 60000) Then $y -= 0x10000
ConsoleWrite($notepad & @LF)
WinMove($notepad, "", $x+303, $y-25)
EndFunc
Func quit()
Exit
EndFunc
Re: [..] Déplacer deux fenêtres en même temps
Posté : mer. 21 mai 2014 23:05
par jguinch
La solution proposée par Tommy est pour moi la meilleure.
Juste une remarque, concernant la position de la fenêtre : lorsque Aero est activé, les coordonnées renvoyées par WinGetPos (ou autre) ne correspondent pas exactement à la taille et position de la fenêtre.
Utiliser
_WinGetPosEx() à la place si besoin.
► Afficher le texteavec _WinGetPosEx
Code : Tout sélectionner
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("MustDeclareVars", 1)
Opt("GuiOnEventMode", 1)
Run("notepad.exe")
WinWait("[CLASS:Notepad]")
Global $hNotepad = WinGetHandle("[CLASS:Notepad]")
Global $gui
Global $taille[2] = [300, 300]
$gui = GUICreate("", $taille[0], $taille[1])
GUISetOnEvent($GUI_EVENT_CLOSE, "quit", $gui)
GUISetState(@SW_SHOW, $gui)
GUIRegisterMsg($WM_MOVE, WM_MOVE)
While(True)
Sleep(10)
WEnd
Func WM_MOVE($hWnd, $msg, $wParam, $lParam)
Local $aPos = _WinGetPosEx($gui)
If NOT IsArray($aPos) Then Return
WinMove($hNotepad, "", $aPos[0] + $aPos[2] , $aPos[1])
EndFunc
Func quit()
WinClose($hNotepad)
Exit
EndFunc
; #FUNCTION# =======================================================
; Name...........: _WinGetPosEx
; Description ...: Retrieves Window size and position similar to WinGetPos() but regards possible Aero effects on Vista and Win7
; Syntax.........: _WinGetPosEx($hWnd)
; Parameters ....: $hWnd - Handle to Window to measure
; Return values .: Success: Returns a 4-element array containing the following information:
; $array[0] = X position
; $array[1] = Y position
; $array[2] = Width
; $array[3] = Height
; Sets @extended = 0 for Aero effect is OFF for $hWnd
; = 1 for Aero effect is ON for $hWnd
;
; Failure: Returns 0 and sets @error to 1 if windows is not found.
; Author ........: KaFu
; Link ..........; http://msdn.microsoft.com/en-us/library/aa969515%28VS.85%29.aspx
; Example .......; Yes
; ==================================================================
Func _WinGetPosEx($hWnd)
If Not IsHWnd($hWnd) Then Return SetError(1, 0, 0)
Local $aPos[4], $tRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
Local Const $DWMWA_EXTENDED_FRAME_BOUNDS = 9
DllCall("dwmapi.dll", "hwnd", "DwmGetWindowAttribute", "hwnd", WinGetHandle($hWnd), "dword", $DWMWA_EXTENDED_FRAME_BOUNDS, "ptr", DllStructGetPtr($tRect), "dword", DllStructGetSize($tRect))
If @error Then Return SetError(0, 0, WinGetPos($hWnd))
Local $iRectLeft = DllStructGetData($tRect, "Left")
Local $iRectTop = DllStructGetData($tRect, "Top")
Local $iRectRight = DllStructGetData($tRect, "Right")
Local $iRectBottom = DllStructGetData($tRect, "Bottom")
If Abs($iRectLeft) + Abs($iRectTop) + Abs($iRectRight) + Abs($iRectBottom) > 0 Then
$aPos[0] = $iRectLeft
$aPos[1] = $iRectTop
$aPos[2] = $iRectRight - $iRectLeft
$aPos[3] = $iRectBottom - $iRectTop
Return SetError(0, 1, $aPos)
EndIf
Return SetError(0, 0, WinGetPos($hWnd))
EndFunc ;==>_WinGetPosEx
@Tommy : je n'ai pas compris les deux test suivants

:
If($x > 60000) Then $x -= 0x10000
If($y > 60000) Then $y -= 0x10000
Re: [..] Déplacer deux fenêtres en même temps
Posté : jeu. 22 mai 2014 00:23
par TommyDDR
c'est quand la fenêtre est en position négative wParam renvoie 0xFFFF (65535) pour -1 par exemple donc j’enlève 0x10000 (65536) pour repasser en négatif.
Essaye en enlevant les lignes et passe la fenêtre en négatif sur les x, tu verras notepad disparaitre ^^.
Je dois t'avouer que le 60000 est purement arbitraire.
(Merci pour _WinGetPosEx() )
Re: [..] Déplacer deux fenêtres en même temps
Posté : jeu. 22 mai 2014 10:58
par pumilio
Merci à vous deux,
J'ai pu parfaitement adapter le code de TommyDDR sur mon projet. je voulais également tester celui de jguinch. Il fonctionne mais je rencontre une difficulté : notepad doit impérativement être lancé en premier pour que ça fonctionne. Dans mon cas de figure il s'ouvre après (manuellement par exemple). J'ai tenté de trouver la solution mais je n'ai pas réussi. Comment faire ?
De plus je souhaiterais que notepad reste toujours devant la Gui. En utilisant WinSetOnTop c'est un peu trop radical. Dans ce cas notepad reste devant toutes les fenêtres qui peuvent s'afficher à l'écran. Est-il possible de gérer ce cas de figure ?
Merci.