_WinAPI_GetWindowRect ( $hWnd ) et $tagRECT

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Capablanca
Niveau 3
Niveau 3
Messages : 41
Enregistré le : mar. 08 juil. 2014 14:44
Status : Hors ligne

_WinAPI_GetWindowRect ( $hWnd ) et $tagRECT

#1

Message par Capablanca »

Bonjour à tous,
Je sais maintenant comment exploiter _WinAPI_GetWindowRect ( $hWnd ).
Cela marche bien car je peux récupérer les données de REC.

Je vous fournis ce code :

Code : Tout sélectionner

#include-once;inclus les includes une seule fois
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <FontConstants.au3>
#include <WinAPISys.au3>
#include <ColorConstantS.au3>
#include <GuiButton.au3>
#include <Sound.au3>
#include <Array.au3>
#include <APIThemeConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPITheme.au3>
#include <GuiMenu.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
;------------------------------------------------------------------------------------------------------
Global $fen1
;------------------------------------------------------------------------------------------------------
Func Ouvrir_fenetre()
	$fen1=GUICreate("Test",640,480+_WinAPI_GetSystemMetrics($SM_CYMENU),-1,-1,BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_SYSMENU,$WS_SIZEBOX))
	;-------------------------------------------
	GUISetState(@SW_SHOW)
EndFunc
;----------------------------------------------------------------
Func En_avant()
	Ouvrir_fenetre()
	GUIRegisterMsg($WM_SIZING, "WM_SIZING")
	While 1
		$aMsg = GUIGetMsg(1)
		$mousex = _WinAPI_GetMousePosX(True, $fen1);position souris x cliente
		$mousey = _WinAPI_GetMousePosY(True, $fen1);position souris y cliente
		;-----------------Fenêtre principale--------------
		Switch $aMsg[1]
			Case $fen1
				Switch $aMsg[0]
					Case $GUI_EVENT_CLOSE
						Exit
				EndSwitch
		EndSwitch
	WEnd
EndFunc
;----------------------------------------------------------------
Func WM_SIZING($hWnd, $uMsgm, $wParam, $lParam)
    #forceref $uMsgm, $wParam, $lParam
	$tRECT = _WinAPI_GetClientRect($hWnd)
	$Left=DllStructGetData($tRECT, "Left")
    	$Right=DllStructGetData($tRECT, "Right")
    	$Top=DllStructGetData($tRECT, "Top")
	$Bottom=DllStructGetData($tRECT, "Bottom")
	;-------------------------

	;-------------------------
	$WMSZ_LEFT=1
	$WMSZ_RIGHT=2
	$WMSZ_BOTTOMRIGHT=8
	$WMSZ_BOTTOMLEFT=7
	$WMSZ_TOP=3
	$WMSZ_BOTTOM=6
	$WMSZ_TOPRIGHT=5
	$WMSZ_TOPLEFT=4
	;-------------------------
	
	;-------------------------
	$tRECT = 0
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SIZE
;----------------------------------------------------------------
En_avant()
En fait je souhaite que l'utilisateur change la taille de la fenêtre mais de manière proportionnelle.
Donc il faut que je sache ce que l'utilisateur sélectionne.
Je sais que wParam me donnera l'endroit où la fenêtre va être modifié mais je n'ai pas les coordonnées.
Je sais que lParam est un pointeur où se trouve la solution mais je ne sais pas comment exploiter lParam en AutoIt.
Donc il me faudrait lire dans lParam et pouvoir écrire aussi dedans (en fait dans REC).

WinAPI_GetClientRect($hWnd) me donne les coordonnées de REC à l'ouverture de la fenêtre mais il faut que je sache lire dans REC quand l'utilisateur modifie la fenêtre.
Je n'arrive pas à trouver la fonction qui convienne.
Merci à ceux qui savent de me donner une solution.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: _WinAPI_GetWindowRect ( $hWnd ) et $tagRECT

#2

Message par mikell »

Capablanca a écrit : ven. 02 juin 2017 14:32je souhaite que l'utilisateur change la taille de la fenêtre mais de manière proportionnelle.
C'est pas très clair. Si tout ce que tu veux c'est que lors d'un redimensionnement la fenêtre garde toujours les mêmes proportions, tu n'as pas besoin de WinAPI_GetClientRect
Manipuler la structure $tRect dans WM_SIZING est suffisant
Capablanca a écrit : ven. 02 juin 2017 14:32Je sais que lParam est un pointeur où se trouve la solution
Exact, tu dois utiliser ce pointeur dans le DllStructCreate Local $tRect = DllStructCreate($tagRECT, $lParam)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Capablanca
Niveau 3
Niveau 3
Messages : 41
Enregistré le : mar. 08 juil. 2014 14:44
Status : Hors ligne

Re: _WinAPI_GetWindowRect ( $hWnd ) et $tagRECT

#3

Message par Capablanca »

Merci pour la réponse.
Ça marche parfaitement bien mais j'ai quand même besoin de connaître les coordonnées par REC pour mettre la fenêtre proportionnelle.

Voici mon code :

Code : Tout sélectionner

#include-once;inclus les includes une seule fois
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <FontConstants.au3>
#include <WinAPISys.au3>
#include <ColorConstantS.au3>
#include <GuiButton.au3>
#include <Sound.au3>
#include <Array.au3>
#include <APIThemeConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPITheme.au3>
#include <GuiMenu.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
;------------------------------------------------------------------------------------------------------
Global $fen1,$idApropos,$idQuitter
;------------------------------------------------------------------------------------------------------
Func Ouvrir_fenetre()
	$fen1=GUICreate("Test",640,480+_WinAPI_GetSystemMetrics($SM_CYMENU),-1,-1,BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_SYSMENU,$WS_SIZEBOX))
	;-------------------------------------------
	GUISetState(@SW_SHOW)
EndFunc
;----------------------------------------------------------------
Func En_avant()
	Ouvrir_fenetre()
	GUIRegisterMsg($WM_SIZING, "WM_SIZING")
	While 1
		$aMsg = GUIGetMsg(1)
		$mousex = _WinAPI_GetMousePosX(True, $fen1);position souris x cliente
		$mousey = _WinAPI_GetMousePosY(True, $fen1);position souris y cliente
		;-----------------Fenêtre principale--------------
		Switch $aMsg[1]
			Case $fen1
				Switch $aMsg[0]
					Case $GUI_EVENT_CLOSE, $idQuitter
						Exit
						
				EndSwitch
		EndSwitch
	WEnd
EndFunc
;----------------------------------------------------------------
Func WM_SIZING($hWnd, $uMsgm, $wParam, $lParam)
    #forceref $uMsgm, $wParam, $lParam
	;-------------------------On lit REC au début
	Local $tRECT = DllStructCreate($tagRECT)
	DllCall("user32.dll", "int", "GetWindowRect","hwnd", $hWnd,"ptr", DllStructGetPtr($tRECT))
	$Left = DllStructGetData($tRECT, "Left") ; Ou 1 à la place de «Left».
    $Top = DllStructGetData($tRECT, "Top") ; Ou "Top" au lieu de 2.
    $Right = DllStructGetData($tRECT, "Right") ; Ou "Right" au lieu de 3.
    $Bottom = DllStructGetData($tRECT, "Bottom") ; Ou 4 au lieu de "Bottom".
	;-------------------------On lit REC pendant le resize
	Local $tRECT2 = DllStructCreate($tagRECT,$lParam)
	DllCall("user32.dll", "int", "GetWindowRect","hwnd", $hWnd,"ptr",DllStructGetPtr($tRECT))
	$Left2 = DllStructGetData($tRECT2, "Left")
    $Top2 = DllStructGetData($tRECT2, "Top")
    $Right2 = DllStructGetData($tRECT2, "Right")
    $Bottom2 = DllStructGetData($tRECT2, "Bottom")
	;-------------------------
	$long=$right-$left
   	$haut=$bottom-$top
	$ecx=$right2-$left2-$long
    	$ecy=$bottom2-$top2-$haut
	;-------------------------
	$WMSZ_LEFT=1
	$WMSZ_RIGHT=2
	$WMSZ_BOTTOMRIGHT=8
	$WMSZ_BOTTOMLEFT=7
	$WMSZ_TOP=3
	$WMSZ_BOTTOM=6
	$WMSZ_TOPRIGHT=5
	$WMSZ_TOPLEFT=4
 	;-------------------------
	If $wParam=$WMSZ_LEFT Or $wParam=$WMSZ_RIGHT Or $wParam=$WMSZ_BOTTOMRIGHT Or $wParam=$WMSZ_BOTTOMLEFT Then
		$pc=($ecx*100)/$long
		$mt=($haut*$pc)/100
		DllStructSetData($tRECT2,"Bottom",$bottom+$mt)
    ElseIf $wParam=$WMSZ_TOP Or $wParam=$WMSZ_BOTTOM Then
		$pc=($ecy*100)/$haut
		$mt=($long*$pc)/100
		DllStructSetData($tRECT2,"Right",$right+$mt)
    ElseIf $wParam=$WMSZ_TOPRIGHT Or $wParam=$WMSZ_TOPLEFT Then
		$pc=($ecx*100)/$long
		$mt=($haut*$pc)/100
		If $top-$mt<0 Then
			DllStructSetData($tRECT2,"Top",0)
			DllStructSetData($tRECT2,"Bottom",$bottom+$mt)
		Else
			DllStructSetData($tRECT2,"Top",$top-$mt)
		EndIf
    EndIf
	;-------------------------
	$tRECT = 0;on annule la structure
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SIZE
;----------------------------------------------------------------
En_avant()
Maintenant je souhaite pouvoir faire en sorte que la fenêtre ne puisse pas rétrécir ou s'agrandir à volonté mais je limite le minimum et le maximum de la taille de la fenêtre.

Je pense utiliser la structure MINMAXINFO.
et avec la notification :
WM_GETMINMAXINFO

WPARAM wParam
LPARAM lParam;
Parameters

wParam
This parameter is not used.
lParam
Pointer to a MINMAXINFO structure that contains the default maximized position and dimensions, and the default minimum and maximum tracking sizes. An application can override the defaults by setting the members of this structure.

Cela devrait pouvoir se faire.
Merci de m'indiquer, à ceux qui savent, comment améliorer mon programme et faire en sorte que la fenêtre soit limité dans sa taille dans le minimum et le maximum.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: _WinAPI_GetWindowRect ( $hWnd ) et $tagRECT

#4

Message par mikell »

En gros tu as compris le concept mais tu te disperses énormément avec des instructions redondantes ou inutiles
Je t'ai fait un petit exemple de code commenté (ça vaut mieux que de longs discours) - et avec le WM_GETMINMAXINFO

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$hGUI = GUICreate("test", 300, 200, -1, -1, $WS_SIZEBOX)
GUISetState()
$ratio = 300/200   ;largeur/hauteur

GUIRegisterMsg($WM_SIZING, "WM_SIZING")
GUIRegisterMsg($WM_GETMINMAXINFO, "WM_GETMINMAXINFO")

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

#cs
$WMSZ_LEFT=1
$WMSZ_RIGHT=2
$WMSZ_TOP=3
$WMSZ_TOPLEFT=4
$WMSZ_TOPRIGHT=5
$WMSZ_BOTTOM=6
$WMSZ_BOTTOMLEFT=7
$WMSZ_BOTTOMRIGHT=8
#ce

Func WM_SIZING($hWnd, $iMsg, $wParam, $lParam)
; on définit la structure
    Local $tagRECT = "long Left;long Top;long Right;long Bottom"
; on crée la structure avec son pointeur
    Local $tRect = DllStructCreate($tagRECT, $lParam)
; on lit son contenu
    Local $left = DllStructGetData($tRect, "Left")
    Local $top = DllStructGetData($tRect, "Top")
    Local $right = DllStructGetData($tRect, "Right")
    Local $bottom = DllStructGetData($tRect, "Bottom")
; et on fait sa petite cuisine
    Switch $wParam
        Case 1, 2    ; on ajuste la hauteur
            DllStructSetData($tRect, "Bottom", $top + ($right-$left)/$ratio)
        Case 4, 7    ; on ajuste la largeur à gauche
            DllStructSetData($tRect, "Left", $right - ($bottom-$top)*$ratio)
        Case Else   ; on ajuste la largeur à droite
            DllStructSetData($tRect, "Right", $left + ($bottom-$top)*$ratio)
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SIZING

Func WM_GETMINMAXINFO($hWnd, $Msg, $wParam, $lParam)
    $minmaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int",$lParam)
    DllStructSetData($minmaxinfo, 7, 150) ; min X
    DllStructSetData($minmaxinfo, 8, 100) ; min Y
    DllStructSetData($minmaxinfo, 9, 600) ; max X
    DllStructSetData($minmaxinfo, 10, 400) ; max Y
    Return 0
EndFunc
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Capablanca
Niveau 3
Niveau 3
Messages : 41
Enregistré le : mar. 08 juil. 2014 14:44
Status : Hors ligne

Re: _WinAPI_GetWindowRect ( $hWnd ) et $tagRECT

#5

Message par Capablanca »

Merci mikell pour ta réponse.

Je réussi, en fin de compte, tout seul à résoudre mes problèmes.
En fait, beaucoup de choses étaient effectivement inutiles et ne marchaient pas bien.

Voici ce code, qui fonctionne bien :

Code : Tout sélectionner

#include-once;inclus les includes une seule fois
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <FontConstants.au3>
#include <WinAPISys.au3>
#include <ColorConstantS.au3>
#include <GuiButton.au3>
#include <Sound.au3>
#include <Array.au3>
#include <APIThemeConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPITheme.au3>
#include <GuiMenu.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
;------------------------------------------------------------------------------------------------------
Global $fen1,$idApropos,$idQuitter
;------------------------------------------------------------------------------------------------------
Func Ouvrir_fenetre()
	$fen1=GUICreate("Test",640,480+_WinAPI_GetSystemMetrics($SM_CYMENU),-1,-1,BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_CAPTION, $WS_SYSMENU,$WS_SIZEBOX))
	;-------------------------------------------
	GUISetState(@SW_SHOW)
EndFunc
;----------------------------------------------------------------
Func En_avant()
	Ouvrir_fenetre()
	GUIRegisterMsg($WM_GETMINMAXINFO, "WM_GETMINMAXINFO")
	GUIRegisterMsg($WM_SIZING, "WM_SIZING")
	While 1
		$aMsg = GUIGetMsg(1)
		$mousex = _WinAPI_GetMousePosX(True, $fen1);position souris x cliente
		$mousey = _WinAPI_GetMousePosY(True, $fen1);position souris y cliente
		;-----------------Fenêtre principale--------------
		Switch $aMsg[1]
			Case $fen1
				Switch $aMsg[0]
					Case $GUI_EVENT_CLOSE
						Exit
				EndSwitch
		EndSwitch
	WEnd
EndFunc
;----------------------------------------------------------------
Func WM_SIZING($hWnd, $uMsgm, $wParam, $lParam)
    #forceref $uMsgm, $wParam, $lParam
	Static $ARatio1=0,$ARatio2=0
	;-------------------------
	Const $WMSZ_LEFT=1
	Const $WMSZ_RIGHT=2
	Const $WMSZ_BOTTOMRIGHT=8
	Const $WMSZ_BOTTOMLEFT=7
	Const $WMSZ_TOP=3
	Const $WMSZ_BOTTOM=6
	Const $WMSZ_TOPRIGHT=5
	Const $WMSZ_TOPLEFT=4
	;-------------------------
	$RECT=DllStructCreate($tagRECT,$lParam)
	$left=DllStructGetData($RECT,1)
	$top=DllStructGetData($RECT,2)
	$right=DllStructGetData($RECT,3)
	$bottom=DllStructGetData($RECT,4)
	If $ARatio1=0 Then
		$ARatio1=($right-$left)/($bottom-$top)
		$ARatio2=($bottom-$top)/($right-$left)
	Endif
	Switch $wParam
		Case $WMSZ_BOTTOM,$WMSZ_TOP
			$Length=($right-$left)
			$right=$right+(($bottom-$top)*$ARatio1-$Length)/2
			DllStructSetData($RECT,3,$right)
			$left=$left-(($bottom-$top)*$ARatio1-$Length)/2
			DllStructSetData($RECT,1,$left)
		Case $WMSZ_LEFT,$WMSZ_RIGHT
			$Length=($bottom-$top)
			$bottom=$bottom+(($right-$left)*$ARatio2-$Length)/2
			DllStructSetData($RECT,4,$bottom)
			$top=$top-(($right-$left)*$ARatio2-$Length)/2
			DllStructSetData($RECT,2,$top)
		Case $WMSZ_BOTTOMLEFT,$WMSZ_BOTTOMRIGHT
			$bottom=(($right-$left)*($ARatio2))+$top
			DllStructSetData($RECT,4,$bottom)
		Case $WMSZ_TOPLEFT,$WMSZ_TOPRIGHT
 			$top=-($right-$left)*$ARatio2+$bottom
			DllStructSetData($RECT,2,$top)
	EndSwitch
	;-------------------------
	$RECT=0;libère les ressources structures
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SIZE
;----------------------------------------------------------------
Func WM_GETMINMAXINFO($hWnd, $uMsgm, $wParam, $lParam)
    #forceref $uMsgm, $wParam, $lParam
	;-------------------------
	Const $tagMINMAXINFO="struct;long;long;long;long;long;long;long;long;long;long;endstruct"
	$MINMAXINFO=DllStructCreate($tagMINMAXINFO,$lParam)
	DllStructSetData($MINMAXINFO,7,320);minimum en x
	DllStructSetData($MINMAXINFO,8,240);minimum en y
	;---------------------------
	$MINMAXINFO=0
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_GETMINMAXINFO
;----------------------------------------------------------------
En_avant()
La routine pour la fenêtre proportionnelle a été changée car elle ne fonctionnait pas très bien.
J'ai laissé les includes inutiles pour ce programme, pour mon programme à venir.
Pour la structure MINMAXINFO j'ai mis long parce que la structure POINT utilise long.
Mais j'ai vu, par ton exemple, que int fonctionne bien aussi.
Répondre