Page 1 sur 1

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

Posté : dim. 31 oct. 2021 16:56
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.

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

Posté : dim. 31 oct. 2021 21:02
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
 

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

Posté : dim. 31 oct. 2021 21:42
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 .

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

Posté : lun. 01 nov. 2021 00:33
par walkson
Bonjours,
un peu de lecture devrait répondre à vos questions
https://www.autoitscript.com/wiki/Movin ... PopUp_GUIs

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

Posté : lun. 01 nov. 2021 10:31
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)

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

Posté : lun. 01 nov. 2021 20:23
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.

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

Posté : lun. 01 nov. 2021 21:07
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

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

Posté : mar. 02 nov. 2021 00:04
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

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

Posté : jeu. 04 nov. 2021 00:09
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.

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

Posté : ven. 05 nov. 2021 13:40
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

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

Posté : ven. 05 nov. 2021 18:53
par jguinch
J'aurais pas mieux expliqué :D

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

Posté : ven. 05 nov. 2021 22:11
par mikell
Damned il était là finalement :mrgreen:

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

Posté : mar. 16 nov. 2021 20:06
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.