[R]Coller / détacher / bouger des fenetres façon winamp ou koda

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
lerin57
Niveau 4
Niveau 4
Messages : 97
Enregistré le : mer. 30 sept. 2009 12:50
Status : Hors ligne

[R]Coller / détacher / bouger des fenetres façon winamp ou koda

#1

Message par lerin57 »

Mesdames, Messieurs, bonjour.

Je vais détailler mon besoin :

Les plus nostalgiques se rappellerons peut être l’interface basique de Winamp, composée de plusieurs fenêtres que l’on pouvait attacher façon magnet, ou détacher via leur barres de titres respectives.
Lorsque ces fenetres sont attachées, il est possible de les déplacer ensembles, simplement en faisant un glisser – déplacer à partie de la barre de titre de la fenêtre principales.

Ceux qui utilisent toujours koda auront remarqués que les 4 fenêtres-menus de bases bougent de la même façon.
Dans mon exemple, je prends deux fenêtres en mode pop-up, que je vais déplacer via un contrôle « image ».

Voici mon début de code :

Code : Tout sélectionner

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

;============================= Variables ==========================

Global $My_1st_GUI    ;=> ces variables sont une composante génériques, mais necessaires ...
Global $My_2nd_GUI    ;=> ...pour la fonction WinS_SetPosition($My_1st_GUI, $My_2nd_GUI)

;==================================================================

;============================= Variables ==========================
; Je crée ma première fenêtre $Gui_01
;==================================================================

#Region ### START Koda GUI section ### Form=
Global $GUI_01 = GUICreate("GUI 01", 252, 202, -1, -1, $WS_POPUP, BitOR($WS_EX_CONTEXTHELP,$WS_EX_WINDOWEDGE))
Global $Pic1 = GUICtrlCreatePic("", 8, 8, 185, 41, -1, BitOR($WS_EX_CLIENTEDGE,$GUI_WS_EX_PARENTDRAG))
Global $Label1 = GUICtrlCreateLabel("Gui 01", 72, 88, 97, 41, BitOR($SS_CENTER,$SS_CENTERIMAGE))
GUICtrlSetFont(-1, 24, 400, 0, "MS Sans Serif")
Global $ButtonClose_1 = GUICtrlCreateButton("X", 200, 8, 43, 41)
GUICtrlSetFont(-1, 18, 800, 0, "MS Sans Serif")
GUISetState(@SW_HIDE)
#EndRegion ### END Koda GUI section ###

;============================= Variables ==========================
; Je crée ma deuxième fenêtre $Gui_02
;==================================================================

#Region ### START Koda GUI section ### Form=
Global $GUI_02 = GUICreate("GUI 01", 252, 202, 732, 576, $WS_POPUP, BitOR($WS_EX_CONTEXTHELP,$WS_EX_WINDOWEDGE))
Global $Pic2 = GUICtrlCreatePic("", 8, 8, 185, 41, -1, BitOR($WS_EX_CLIENTEDGE,$GUI_WS_EX_PARENTDRAG))
Global $Label2 = GUICtrlCreateLabel("Gui 02", 72, 88, 97, 41, BitOR($SS_CENTER,$SS_CENTERIMAGE))
GUICtrlSetFont(-1, 24, 400, 0, "MS Sans Serif")
Global $ButtonClose_2 = GUICtrlCreateButton("X", 200, 8, 43, 41)
GUICtrlSetFont(-1, 18, 800, 0, "MS Sans Serif")
GUISetState(@SW_HIDE)
#EndRegion ### END Koda GUI section ###

_Win_SetPosition($GUI_01, $GUI_02) ; cette fonction permet de positionner la deuxième fenetre ($gui_02) correctement avant son affichage.

While 1
 $nMsg = GUIGetMsg(1)
Select

  Case $nMsg[0] = $ButtonClose_1 And $nMsg[1] = $GUI_01
   Exit

  Case $nMsg[0] = $ButtonClose_2 And $nMsg[1] = $GUI_02
   Exit

EndSElect

WEnd

func _Win_SetPosition($My_1st_GUI, $My_2nd_GUI)

;============================= Variables ==========================
; Je détermine la taille et la position de ma première fenetre
;==================================================================

Dim $pos_1st_Gui = WinGetPos($My_1st_GUI)

;==================================================================
; Ensuite, je déplace ma seconde fenetre, de deux fois la hauteur de la première fenetre + 2 (je reste sur les mêmes coordonnées X).
;==================================================================

WinMove($My_2nd_GUI, "", $pos_1st_Gui[0], ($pos_1st_Gui[1] + $pos_1st_Gui[3] + 2))


WinSetState($My_1st_GUI, "", @SW_SHOW)

WinSetState($My_2nd_GUI, "", @SW_SHOW)

WinSetOnTop($My_1st_GUI, "", 1)

WinSetOnTop($My_2nd_GUI, "", 1)

EndFunc
Il faut que, lorsque la fenêtre $gui_01 se déplace, la fenêtre $gui_02 puisse la suivre, avec un décalage vers le bas (axe Y).

Je sais que le sujet a déjà été abordé sous d’autre formes sur ce forum, mais les exemples de code ne donnaient pas le résultat que je cherche.

Les fonction GUIRegisterMsg, GUIGetCursorInfo, et mousegetpos seront surement necessaire.

J’avoue etre encore à éplucher le très bon article wiki sur GUIRegisterMsg.

Je fais donc appel à la sympathie et la patience de ceux d’entre vous qui pourraient me fournir un exemple de code suffisamment détaillé.

Ps : j'ai du mal à voir ce que j'ai loupé sur les actions pour fermer les fenetres, ou les déplacer, car il ne fonctionnent pas.
Modifié en dernier par lerin57 le mar. 16 nov. 2021 20:07, modifié 7 fois.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [...]Coller / détacher / bouger des fenetres façon winamp ou koda

#2

Message par mikell »

Voilà, c'est du bricolage mais ça devrait te permettre de démarrer quelque chose. C'est une des manières de procéder, y en a d'autres
En passant, ton script est assez brouillon, tu devrais faire un effort de cleanitude :wink:

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#include <SendMessage.au3>

Global Const $SC_DRAGMOVE = 0xF012

Global $GUI_01 = GUICreate("GUI 01", 252, 202, -1, -1, $WS_POPUP, BitOR($WS_EX_CONTEXTHELP,$WS_EX_WINDOWEDGE))
Global $Pic1 = GUICtrlCreatePic("", 8, 8, 185, 41, -1, BitOR($WS_EX_CLIENTEDGE,$GUI_WS_EX_PARENTDRAG))
Global $Label1 = GUICtrlCreateLabel("Gui 01", 72, 88, 97, 41, BitOR($SS_CENTER,$SS_CENTERIMAGE))
GUICtrlSetFont(-1, 24, 400, 0, "MS Sans Serif")
Global $ButtonClose_1 = GUICtrlCreateButton("X", 200, 8, 43, 41)
GUICtrlSetFont(-1, 18, 800, 0, "MS Sans Serif")

Global $GUI_02 = GUICreate("GUI 01", 252, 202, 732, 576, $WS_POPUP, BitOR($WS_EX_CONTEXTHELP,$WS_EX_WINDOWEDGE, $WS_EX_MDICHILD), $GUI_01)
Global $Pic2 = GUICtrlCreatePic("", 8, 8, 185, 41, -1, BitOR($WS_EX_CLIENTEDGE,$GUI_WS_EX_PARENTDRAG))
Global $Label2 = GUICtrlCreateLabel("Gui 02", 72, 88, 97, 41, BitOR($SS_CENTER,$SS_CENTERIMAGE))
GUICtrlSetFont(-1, 24, 400, 0, "MS Sans Serif")
Global $ButtonClose_2 = GUICtrlCreateButton("X", 200, 8, 43, 41)
GUICtrlSetFont(-1, 18, 800, 0, "MS Sans Serif")

Global $GUI_03 = GUICreate("GUI 01", 252, 202, 732, 576, $WS_POPUP, BitOR($WS_EX_CONTEXTHELP,$WS_EX_WINDOWEDGE, $WS_EX_MDICHILD), $GUI_01)
Global $Pic3 = GUICtrlCreatePic("", 8, 8, 185, 41, -1, BitOR($WS_EX_CLIENTEDGE,$GUI_WS_EX_PARENTDRAG))
Global $Label3 = GUICtrlCreateLabel("Gui 03", 72, 88, 97, 41, BitOR($SS_CENTER,$SS_CENTERIMAGE))
GUICtrlSetFont(-1, 24, 400, 0, "MS Sans Serif")
Global $ButtonClose_3 = GUICtrlCreateButton("X", 200, 8, 43, 41)
GUICtrlSetFont(-1, 18, 800, 0, "MS Sans Serif")

$pos_1st_Gui = WinGetPos($GUI_01) ; je récupère les coordonnées et taille de ma premiere gui
WinMove($GUI_02, "", $pos_1st_Gui[0], ($pos_1st_Gui[1] + $pos_1st_Gui[3] + 2))
WinMove($GUI_03, "", $pos_1st_Gui[0] + $pos_1st_Gui[2] + 2, $pos_1st_Gui[1] )
WinSetOnTop($GUI_01, "", 1)
WinSetOnTop($GUI_02, "", 1)
WinSetOnTop($GUI_03, "", 1)
GUISetState(@SW_SHOW, $GUI_01)
GUISetState(@SW_SHOW, $GUI_02)
GUISetState(@SW_SHOW, $GUI_03)


While 1
    $aMsg = GUIGetMsg(1)
    Switch $aMsg[1]
        Case $GUI_01
            Switch $aMsg[0]
                Case $ButtonClose_1
                    Exit
            EndSwitch
        Case $GUI_02
            Switch $aMsg[0]
                 Case $ButtonClose_2
                    GuiDelete($GUI_02)
                Case $GUI_EVENT_PRIMARYDOWN
                    _SendMessage($GUI_02, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
            EndSwitch
        Case $GUI_03
            Switch $aMsg[0]
                 Case $ButtonClose_3
                    GuiDelete($GUI_03)
                Case $GUI_EVENT_PRIMARYDOWN
                    _SendMessage($GUI_03, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
            EndSwitch
    EndSwitch
WEnd
 
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
lerin57
Niveau 4
Niveau 4
Messages : 97
Enregistré le : mer. 30 sept. 2009 12:50
Status : Hors ligne

Re: [...]Coller / détacher / bouger des fenetres façon winamp ou koda

#3

Message par lerin57 »

Bonjour, Mikell, merci pour votre retour.

Je me suis donc efforcé de rendre mon code plus "compréhensible".

Pouvez vous m'expliquer à quoi correspond cette constante :

Code : Tout sélectionner

Global Const $SC_DRAGMOVE = 0xF012
ainsi que la façon dont fonctionne la fonction _sendMessage dans tout çà ?

Bien à vous .
Avatar du membre
walkson
Modérateur
Modérateur
Messages : 1020
Enregistré le : ven. 12 août 2011 19:49
Localisation : Hurepoix
Status : Hors ligne

Re: [...]Coller / détacher / bouger des fenetres façon winamp ou koda

#4

Message par walkson »

Bonjours,
un peu de lecture devrait répondre à vos questions
https://www.autoitscript.com/wiki/Movin ... PopUp_GUIs
Cordialement,
Walkson
"Horas non numero nisi serenas " Le canon de midi
(Je ne compte que les heures heureuses)
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [...]Coller / détacher / bouger des fenetres façon winamp ou koda

#5

Message par mikell »

SC_DRAGMOVE est une commande système qui permet de déplacer la fenêtre avec la souris
_SendMessage est la fonction qui envoie cette commande à la fenêtre spécifiée quand celle-ci reçoit le message $WM_SYSCOMMAND

En fait dans le cas particulier de ce script, ce _SendMessage est superflu puisque
- la gui 2 est définie comme fille de la gui 1 ($WS_EX_MDICHILD) donc se déplace naturellement avec elle
- il existe déjà autre un moyen de déplacer la gui 2 seule (avec $GUI_WS_EX_PARENTDRAG)
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
lerin57
Niveau 4
Niveau 4
Messages : 97
Enregistré le : mer. 30 sept. 2009 12:50
Status : Hors ligne

Re: [...]Coller / détacher / bouger des fenetres façon winamp ou koda

#6

Message par lerin57 »

Mikell, Walkson,

Suivant l'exemple de code fournie par mikell, chaque fenetre se déplace, quelque soit la zone ou l'on va cliquer; ... Le restreindre sur le contrôle " GUICtrlCreatePic" serait plus pratique (peut etre en utilisant GUIGetCursorInfo ?).

j'ai commencé à étudier les nombreux exemples proposé dans l'article que wilson a posté.

Je vais également suivre la piste de la variable $GUI_WS_EX_PARENTDRAG.

je me permet de laisser le sujet en suspend pour au moins deux semaines, je reste à l'écoute si vous, ou d'autres membres ont des pistes intéressantes.

Quoiqu'il en soit , je vous remercie tous les deux.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [...]Coller / détacher / bouger des fenetres façon winamp ou koda

#7

Message par mikell »

lerin57 a écrit : lun. 01 nov. 2021 20:23Le restreindre sur le contrôle " GUICtrlCreatePic" serait plus pratique
C'est exactement ce que je voulais dire dans mon post précédent
Si dans mon script tu supprimes les _SendMessage, tu obtiendras précisément le résultat voulu - en laissant définies les gui 2 et 3 comme filles de la gui 1, et en laissant les $GUI_WS_EX_PARENTDRAG sur les controles Pic
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2511
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: [.]Coller / détacher / bouger des fenetres façon winamp ou koda

#8

Message par jguinch »

Voilà un autre exemple, avec l'effet "Magnet" (Winamp, que de bon souvenirs...)
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $aChildNewPos[2]
Global $iMagnetPrecision = 30
Global $_bMagnet

Global $GUI_01 = GUICreate("GUI 01", 250, 150, 100, 100, $WS_POPUPWINDOW)
GUISetBkColor(0xf7db90)
GUICtrlCreateLabel("Fenêtre principale", 0, 0, 250, 15, -1, $GUI_WS_EX_PARENTDRAG)
GUICtrlSetBkColor(-1, 0xdda100)
GUICtrlCreateLabel( @CRLF & "J'emmène l'autre fenêtre avec moi quand on me déplace, seulement si elle est collée à moi", 25, 20, 200, 50)

Global $GUI_02 = GUICreate("GUI 02", 250, 150, 150, 350, $WS_POPUPWINDOW )
GUISetBkColor(0xccccff)
GUICtrlCreateLabel("", 0, 0, 250, 15, -1, $GUI_WS_EX_PARENTDRAG)
GUICtrlSetBkColor(-1, 0xffffff)

GUISetState(@SW_SHOW, $GUI_01)
GUISetState(@SW_SHOW, $GUI_02)

GUIRegisterMsg($WM_ENTERSIZEMOVE, "CaldPos")
GUIRegisterMsg($WM_MOVE, "_MoveChild")

While 1
    If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
WEnd

Func _MoveChild($hWndGUI, $MsgID, $WParam, $LParam)
   Local $aParentPos = WinGetPos($GUI_01)
   Local $aChildPos = WinGetPos($GUI_02)
   Switch $hWndGUI
      Case $GUI_01
         If Not $_bMagnet Then Return
         WinMove($GUI_02, "", $aParentPos[0] - $aChildNewPos[0], $aParentPos[1] - $aChildNewPos[1])
      Case $GUI_02
         $_bMagnet = False
         Local $res = 0
         If Abs($aChildPos[0] - $aParentPos[0]) < $iMagnetPrecision And Abs($aChildPos[1] - $aParentPos[1] - $aParentPos[3]) < $iMagnetPrecision Then $res = WinMove($GUI_02, "", $aParentPos[0], $aParentPos[1] + $aParentPos[3])
         If Abs($aChildPos[0] - $aParentPos[0] - $aParentPos[2]) < $iMagnetPrecision And Abs($aChildPos[1] - $aParentPos[1]) < $iMagnetPrecision Then $res = WinMove($GUI_02, "", $aParentPos[0] + $aParentPos[2], $aParentPos[1])
         If Abs($aChildPos[0] + $aChildPos[2] - $aParentPos[0]) < $iMagnetPrecision And Abs($aChildPos[1] - $aParentPos[1]) < $iMagnetPrecision  Then $res = WinMove($GUI_02, "", $aParentPos[0] - $aChildPos[2], $aParentPos[1])
         If Abs($aChildPos[0] - $aParentPos[0]) < $iMagnetPrecision And Abs($aChildPos[1] + $aChildPos[3] - $aParentPos[1]) < $iMagnetPrecision  Then $res = WinMove($GUI_02, "", $aParentPos[0], $aParentPos[1] - $aChildPos[3])
         If $res Then $_bMagnet = True
   EndSwitch
EndFunc

Func CaldPos($hWndGUI, $MsgID, $WParam, $LParam)
   Local $aParentPos = WinGetPos($GUI_01)
   Local $aChildPos = WinGetPos($GUI_02)
   Switch $hWndGUI
      Case $GUI_01
         $aChildNewPos[0] = $aParentPos[0] - $aChildPos[0]
         $aChildNewPos[1] = $aParentPos[1] - $aChildPos[1]
   EndSwitch
EndFunc
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
lerin57
Niveau 4
Niveau 4
Messages : 97
Enregistré le : mer. 30 sept. 2009 12:50
Status : Hors ligne

Re: [.]Coller / détacher / bouger des fenetres façon winamp ou koda

#9

Message par lerin57 »

Bonsoir à tous,

jguinch, ton exemple est exactement ce que je recherche.

Avant de marquer le sujet en résolu, je me permet une dernière question :

je comprend a peu prêt la condition qui fait que la fenêtre "child" va se magnétiser à une certaine distance du rebord de la fenêtre "parent."

Mais peux tu m'expliquer ce qu'est la variable $_bMagnet? ou sur quoi elle influt?

En te remerciant par avance.
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..]Coller / détacher / bouger des fenetres façon winamp ou koda

#10

Message par mikell »

jguinch est pas là donc je réponds
"J'emmène l'autre fenêtre avec moi quand on me déplace, seulement si elle est collée à moi"
$_bMagnet est une variable booléenne (true / false) destinée à renseigner la gui 1 sur le fait que la gui 2 y est collée ou non
Par défaut $_bMagnet = false
Dans le Case $GUI_02, si la gui 2 se colle, WinMove retourne son handle, $res <> 0 et $_bMagnet = true
Dans le Case $GUI_01, si bMagnet = true alors la gui 2 est déplacée en même temps que la gui 1
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2511
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: [..]Coller / détacher / bouger des fenetres façon winamp ou koda

#11

Message par jguinch »

J'aurais pas mieux expliqué :D
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [..]Coller / détacher / bouger des fenetres façon winamp ou koda

#12

Message par mikell »

Damned il était là finalement :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
lerin57
Niveau 4
Niveau 4
Messages : 97
Enregistré le : mer. 30 sept. 2009 12:50
Status : Hors ligne

Re: [..]Coller / détacher / bouger des fenetres façon winamp ou koda

#13

Message par lerin57 »

Bonsoir à tous et à toutes

Avec un peu de retard, merci à tous les trois pour vos exemples.

Il y a assez de base pour ce que je tente de réaliser.

Je vous remercie encore une fois pour votre aide.

Le sujet est résolu.
Répondre