[RESOLU]Bouger une fenêtre via imagegadget

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Ekim
Messages : 215
Inscription : dim. 24/juin/2018 1:20

[RESOLU]Bouger une fenêtre via imagegadget

Message par Ekim »

Bonsoir à tous,

Pouvez vous me dire comment peut on faire bouger une fenêtre sur laquelle on place une "ImageGadget" recouvrant l'ensemble de la fenêtre en question?

Note: bien entendu la fenêtre à pour attribut "WindowBorderless"

je souhaiterais également par la suite "skiner" ma fenêtre pour un habillage plus moderne, donc si vous avez des topics opérationnel :wink:

merci pour votre aide :D
Dernière modification par Ekim le mer. 28/nov./2018 23:23, modifié 1 fois.
Avatar de l’utilisateur
Ar-S
Messages : 9478
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Bouger une fenêtre via imagegadget

Message par Ar-S »

Bonjour Ekim
Je t'invite à voir ce topic : https://www.purebasic.fr/french/viewtop ... re#p194584
que j'ai trouvé en tapant "déplacer fenêtre" dans les recherches.

Voilà un code complet de Rashad.
Il y en a probablement d'autres.

Code : Tout sélectionner

;rashad
#MONITORINFOF_PRIMARY=1
#MONITOR_DEFAULTTONULL=0
#MONITOR_DEFAULTTOPRIMARY=1
#MONITOR_DEFAULTTONEAREST=2

#SC_Leftsize      = $F001
#SC_Rightsize     = $F002
#SC_Upsize        = $F003
#SC_UpLeftsize    = $F004
#SC_UpRightsize   = $F005
#SC_Dnsize        = $F006
#SC_DnLeftsize    = $F007
#SC_DnRightsize   = $F008
#SC_DragMove      = $F012

; CompilerIf #PB_Compiler_Unicode = 0
;   MessageRequester("Info","Unicode compiler option not set",#MB_ICONINFORMATION)
;   End
; CompilerEndIf

Global  hwnd,r.RECT,hmon,mi.MONITORINFO,x,y,w,h,snap
mi\cbSize=SizeOf(mi)

Procedure sizeCB()
  ResizeGadget(0,10,WindowHeight(0)-36,60,24)
EndProcedure

hwnd=OpenWindow(0,0,0,800,600,"PB_Player",#PB_Window_BorderLess | #WS_BORDER | #PB_Window_Invisible)
SetWindowColor(0,$838383)

ButtonGadget(0,10,564,60,24,"Quit")
HideWindow(0,0,#PB_Window_ScreenCentered)
BindEvent(#PB_Event_SizeWindow,@sizeCB())
SmartWindowRefresh(0,1)

snap = 50
sw = 10
sww = 2*sw
Repeat
  Select WaitWindowEvent(1)         
    Case #PB_Event_MoveWindow
        If IsWindow(0)
          GetWindowRect_(hWnd,r)
          w = r\right - r\left
          h = r\bottom - r\top
        EndIf 
        hmon = MonitorFromWindow_(hWnd,#MONITOR_DEFAULTTONEAREST)
        GetMonitorInfo_(hmon,mi)
        If mi\rcWork\left + snap > r\left : r\left = mi\rcWork\left - 2: EndIf
        If r\left + w >= (mi\rcWork\right - snap): r\left = mi\rcWork\right - w + 2: EndIf
        If mi\rcWork\top + snap > r\top : r\top = mi\rcWork\top - 2 : EndIf
        If r\top + h >= (mi\rcWork\bottom - snap): r\top = mi\rcWork\bottom - h + 2 : EndIf
        MoveWindow_(hWnd,r\left,r\top,w,h,1)
   
    Case #WM_MOUSEMOVE;,#WM_NCMOUSEMOVE
        GetWindowRect_(hWnd,r.RECT)
        mx = DesktopMouseX()
        my = DesktopMouseY()
        Flag = 0
        If mx > r\left+sww And mx < r\right-sww And my > r\top-sw And my < r\top+sw
          SetCursor_(LoadCursor_(0, #IDC_SIZENS))
          Flag = 1
        ElseIf mx > r\left+sww And mx < r\right-sww And my > r\bottom-sw And my < r\bottom+sw
          SetCursor_(LoadCursor_(0, #IDC_SIZENS))
          Flag = 2
        ElseIf mx > r\left-sw And mx < r\left+sw And my > r\top+sww And my < r\bottom-sww
          SetCursor_(LoadCursor_(0, #IDC_SIZEWE))
          Flag = 3
        ElseIf mx > r\right-sw And mx < r\right+sw And my > r\top+sww And my < r\bottom-sww
          SetCursor_(LoadCursor_(0, #IDC_SIZEWE))
          Flag = 4
        ElseIf mx > r\left-sw And mx < r\left+sw And my > r\top-sw And my < r\top+sw
          SetCursor_(LoadCursor_(0, #IDC_SIZENWSE))
          Flag = 5
        ElseIf mx > r\right-sw And mx < r\right+sw And my > r\bottom-sw And my < r\bottom+sww
          SetCursor_(LoadCursor_(0, #IDC_SIZENWSE))
          Flag = 6
        ElseIf mx > r\right-sw And mx < r\right+sw And my > r\top-sw And my < r\top+sw
          SetCursor_(LoadCursor_(0, #IDC_SIZENESW))
          Flag = 7
        ElseIf mx > r\left-sw And mx < r\left+sw And my > r\bottom-sw And my < r\bottom+sww
          SetCursor_(LoadCursor_(0, #IDC_SIZENESW))
          Flag = 8
        EndIf
       
    Case #WM_LBUTTONDOWN
        If Flag > 0
          ReleaseCapture_()
        EndIf
        If Flag = 0
SetCursor_(LoadCursor_(0, #IDC_HAND))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_DragMove,0)
        ElseIf Flag = 1
          SetCursor_(LoadCursor_(0, #IDC_SIZENS))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_Upsize,0)       
        ElseIf Flag = 2
          SetCursor_(LoadCursor_(0, #IDC_SIZENS))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_Dnsize,0) 
        ElseIf Flag = 3
          SetCursor_(LoadCursor_(0, #IDC_SIZEWE))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_Leftsize,0)
        ElseIf Flag = 4
          SetCursor_(LoadCursor_(0, #IDC_SIZEWE))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_Rightsize,0)
        ElseIf Flag = 5
          SetCursor_(LoadCursor_(0, #IDC_SIZENWSE))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_UpLeftsize,0)
        ElseIf Flag = 6
          SetCursor_(LoadCursor_(0, #IDC_SIZENWSE))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_DnRightsize,0)
        ElseIf Flag = 7
          SetCursor_(LoadCursor_(0, #IDC_SIZENESW))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_UpRightsize,0)
        ElseIf Flag = 8
          SetCursor_(LoadCursor_(0, #IDC_SIZENESW))
          SendMessage_(hWnd, #WM_SYSCOMMAND , #SC_DnLeftsize,0) 
        EndIf
     
    Case #WM_LBUTTONUP
        Flag = 0
        SendMessage_(hWnd, #WM_SYSCOMMAND, 0, 0)
       
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          Quit = 1
      EndSelect

EndSelect       
     
Until Quit = 1
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Marc56
Messages : 2148
Inscription : sam. 08/févr./2014 15:19

Re: Bouger une fenêtre via imagegadget

Message par Marc56 »

Ekim a écrit :Bonsoir à tous,
Pouvez vous me dire comment peut on faire bouger une fenêtre sur laquelle on place une "ImageGadget" recouvrant l'ensemble de la fenêtre en question?
Note: bien entendu la fenêtre à pour attribut "WindowBorderless"
Une fenêtre peut aussi servir de conteneur pour une image, donc tu n'as pas nécessairement besoin d'un ImageGadget

Petit exemple d'une fenêtre:
  • Ayant une image de fond (donc pouvant servir de prévisualisation)
  • Pas de bordure
  • Déplaçable à la souris (Nécessite PB enregistré car utilisation d'une API)
Fermeture par le bouton close ou par un double-clic sur la fenêtre.
L'exemple est plus assez court, mais la fenêtre n'est pas redimensionnable à la souris.

Code : Tout sélectionner

EnableExplicit

Enumeration
    #Win
    #Img
    #Btn_Close
EndEnumeration

OpenWindow(#Win, 0, 0, 500, 200, "", #PB_Window_BorderLess | #PB_Window_ScreenCentered)


ButtonGadget(#Btn_Close, WindowWidth(#Win) - 70, 170, 60, 20, "Close")

If LoadImage(#Img, #PB_Compiler_Home + "\Examples\Sources\Data\PureBasicLogo.bmp")
    StartDrawing(WindowOutput(#Win))
    DrawImage(ImageID(#Img), 10, 10)
    StopDrawing()
EndIf

Repeat
    Select WaitWindowEvent()
            
        Case #PB_Event_Gadget
            
            Select EventGadget()
                Case #Btn_Close
                    Break
            EndSelect
            
        Case #PB_Event_LeftDoubleClick 
            ; Double clic gauche = Quitter
            Break
            
        Case #WM_LBUTTONDOWN
            ; Déplace la fenêtre sans bordure avec le bouton gauche souris (API)
            SendMessage_(WindowID(#Win), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)       
            
    EndSelect
ForEver

End
Pour "skiner" ta fenêtre, il suffit de tracer les éléments entre StartDrawing(WindowOutput(#Win)) et StopDrawing()

:wink:
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Bouger une fenêtre via imagegadget

Message par boby »

J'suis pas fan de la boucle waitwindowevent, aussi je propose :

Code : Tout sélectionner

Procedure WindowMove(hWnd, uMsg, WParam, LParam)
  If uMsg = #WM_LBUTTONDOWN
    SendMessage_(hWnd, #WM_NCLBUTTONDOWN, #HTCAPTION, 0) 
  EndIf
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure
Procedure Exit()
  End
EndProcedure
OpenWindow(0,0,0,300,300,"",#PB_Window_ScreenCentered|#PB_Window_BorderLess)
ButtonGadget(0,10,270,50,20,"Exit")
BindGadgetEvent(0,@Exit())
SetWindowCallback(@WindowMove(),0)
StartDrawing(WindowOutput(0))
;ici dessiner ton image
Box(0,0,300,300,$FFCC11)
StopDrawing()
Repeat
  WaitWindowEvent()
ForEver
Christophe
Messages : 43
Inscription : lun. 22/oct./2018 19:34
Localisation : Haisnes (62)

Re: Bouger une fenêtre via imagegadget

Message par Christophe »

Boby, Tu as été plus rapide que moi... Seul petit changement plus de ButtonGadget pour quitter

Code : Tout sélectionner

CreateImage(0,610,410)
StartDrawing(ImageOutput(0))
For x=0 To 619 Step 20
  For y=0 To 419 Step 20
    Box(x,y,10,10, #Gray)
  Next
Next
Box(600,0,10,10, #Red)
StopDrawing()

  Procedure MoveWindow()
    
    If WindowMouseX(0)>599 And WindowMouseY(0)<11     ; Clique sur carre rouge 'Quit'
      End
    Else
        
    SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0) ; Sinon Bouge fenetre
  EndIf
  
  EndProcedure
  
OpenWindow(0,0,0,610,410,"",#PB_Window_ScreenCentered | #PB_Window_BorderLess)
ImageGadget(0,0,0,610,410,ImageID(0))

BindGadgetEvent(0, @MoveWindow())

Repeat
  E = WaitWindowEvent()
    Delay(30)
ForEver
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Bouger une fenêtre via imagegadget

Message par boby »

@Christophe, ça reste intéressant d'avoir plusieurs points de vue !
Persso, quand il s’agit de fonctionnalité habituellement géré par windob (Tel que déplacer une fenêtre) je préfère gérer ça par un bon vieux callback manuellement, ça permet d'être sur que ça sera géré en priorité par rapport au subclassement des events de Pure... S'pas forcément la meilleur solutions, c'est juste la mienne :p
Pour le reste... Le principale c'est que ça fonctionne ^^"

Code : Tout sélectionner

Repeat
  E = WaitWindowEvent()
    Delay(30)
ForEver
En revanche, il faudra que tu m'explique la pertinence de ton delay dans cette boucle :p
Marc56
Messages : 2148
Inscription : sam. 08/févr./2014 15:19

Re: Bouger une fenêtre via imagegadget

Message par Marc56 »

WaitWindowEvent() est bloquant, il est donc conseillé (et prévu) de lui mettre un timeout (même très court), mais plutôt comme cela:

Code : Tout sélectionner

WaitWindowEvent(30)
Delay() n'aurait pas le même effet (il bloque tout). Son utilité est plutôt de faire une pause complète le temps de vérifier un affichage par exemple.

PS. Perso je continue de préférer la boucle principale classique. Je ne sais plus où sur ce forum (ou celui us ?) on avait démontré que le CallBack (Bind...) n'est pas la panacée. Heureusement, on peut mixer les deux techniques dans le même code.
Utiliser un callback est par exemple intéressant pour redimensionner une fenêtre car on voit en temps réel tous les gadgets changer de taille alors qu'avec la procédure classique la fenêtre n'est redessinée qu'au relâché de la souris. Si on a beaucoup de gadgets et une machine peu puissante, la deuxième technique est plus intéressante. (les développeurs ont en général des PC bien plus puissants que les utilisateurs standards qui en plus font souvent tourner plusieurs applications, penser à eux)

:wink:
Christophe
Messages : 43
Inscription : lun. 22/oct./2018 19:34
Localisation : Haisnes (62)

Re: Bouger une fenêtre via imagegadget

Message par Christophe »

@boby

Juste un oublie de ma part... Au depart j'etais parti sur une autre approche du code avec un WindowEvent() donc j'avais mis ce 'delay'. Merci pour ton attention
Avatar de l’utilisateur
MLD
Messages : 1105
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Bouger une fenêtre via imagegadget

Message par MLD »

Bonjour a tous
@Marc 56
Il faudra me démontrer que le fait mettre un timeout dans l'évent est plus rapide. J'utilise aussi la boucle classique sans jamais mettre un timeout, et je n'est jamais eu de souci de blocage. Par contre avec un timeout dans la boucle l'on a un phénomène de saccade.
C'est mon avis
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Bouger une fenêtre via imagegadget

Message par boby »

En effet WaitWindowEvent() est bloquant, donc placer un delay(30) APRÉS ne fera QUE retarder la gestion des events de 30ms, donc farpaitement inutile.

Pour ce qui est du CallBack, BindEvent() et SetWindowCallback() restent une approche différente, BindEvent utilise le système de subclassement de pure, SetWindowCallback intervient AVANT le subclass de pure et permet donc de prendre la main sur les actions à entreprendre avant de rendre la main à pure (ProcedureReturn #PB_ProcessPureBasicEvents).

Pour ce qui est de la boucle WaitWindowEvent(), moi je trouve le bind nettement plus lisible, quand tu te retrouve avec une boucle évènementielle de 1000 lignes, je trouve que la lisibilité prime sur la perf (bien que je ne soit pas convaincu que la boucle windowevent perf plus...). J'aimerai dire libre à chacun d'adopter sa solution, mais je trouve que continuer à utiliser la boucle WindowEvent est une hérésie et je ne comprend même pas que cette boucle existe encore depuis l'arrive du bind, en effet multiplier les solutions pour obtenir le même résultat à l'intérieur même du langage est le meilleur moyen de "perdre" ses utilisateurs... Mais la, cet avis n'appartiens qu'à moi.

@MLD bloquant signifi que ton programme attendra qu'un event se produise avant de faire quoi que ce soit, si tu fait une boucle waitwindowevent() et que tu as une communication réseau à gérer par exemple, alors tans que tu n'as pas un évènement produit par l'utilisateur (souris qui bouge, clic sur bouton etc...) la récéption de tes paquets réseau ne serons pas traité... je crois que Marc56 a prouvé plusieurs fois qu'il sait de quoi il parle, tu devrais lui faire un poil plus confiance...
Avatar de l’utilisateur
MLD
Messages : 1105
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Bouger une fenêtre via imagegadget

Message par MLD »

@boby
Je comprend ton point de vue mais ne le partage pas forcément.
J'ai vu aussi l'utilisation des BindEvent() abusive.
une boucle classique ne doit pas avoir 1000 lignes
Et les threads ne sont pas fait pour rien notamment pour une communication réseau.
J'ai une parfaite confiance en Marc56,mais une discutions entre programmeurs n'est jamais inutile.
Il y a maintenant une palette d'outils assez grande pour pouvoir avoir des méthodes de programmation différentes, voir a mixer les possibilités. :wink:
Marc56
Messages : 2148
Inscription : sam. 08/févr./2014 15:19

Re: Bouger une fenêtre via imagegadget

Message par Marc56 »

@boby: Merci, mais pas du tout, j'ai beaucoup moins d'expérience que MLD et je raconte (trop) souvent un tas de "clowneries" :mrgreen:

Pour WaitWindowEvent([Timeout]), après relecture de l'aide (voir les exemples), il semble que ce timeout serve si on souhaite temporiser. C'est une alternative à #PB_Event_Timer si on veut temporiser tous les évènements de la boucle principale en une seule fois et selon le même tempo. Ça montre encore une fois les vastes possibilités de PB. (De mémoire c'était une question de relâcher du CPU, comme quoi la mémoire joue des tours)

(Read The Fine Manual :D (encore et encore) Je viens d'apprendre encore un truc aujourd'hui 8)

:wink:
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Bouger une fenêtre via imagegadget

Message par boby »

Doc de PureBasic a écrit :The timeout (in milliseconds) which causes the function to return if no events are occurring. If no timeout is specified, it will wait infinitely until an event occurs.
Non non, WaitWindowEvent() bloque bien tout ton programme tans que tu n'as aucun évènement qui se passe.

Code : Tout sélectionner

OpenWindow(0,0,0,100,30,"bla",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
Repeat
  Debug "???"
Until WaitWindowEvent() = #PB_Event_CloseWindow
;Until WaitWindowEvent(30) = #PB_Event_CloseWindow
Et c'est pas bien dur à vérifier...
mais une discutions entre programmeurs n'est jamais inutile.
Quand elle viens remettre en question une info facilement trouvable juste en lisant la doc, je trouve que si, mais... Ce n'est encore et toujours que mon point de vue.

PS : On ne serait pas en train de partir en hors sujet la par hasard ?
Marc56
Messages : 2148
Inscription : sam. 08/févr./2014 15:19

Re: Bouger une fenêtre via imagegadget

Message par Marc56 »

Avec 30 ms, tu n'as pas le temps de voir ce qui se passe réellement.
Essayes plutôt ceci: (1 seconde et affichage des secondes)

Code : Tout sélectionner

OpenWindow(0,0,0,100,30,"bla",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
Repeat
  Debug FormatDate("%ss", Date())
Until WaitWindowEvent() = #PB_Event_CloseWindow
;Until WaitWindowEvent(1000) = #PB_Event_CloseWindow
Bouge la souris et tu verras
Sans le timeout, le programme est stoppé si la fenêtre n'a plus le focus
Avec, le programme continue à faire la boucle une fois par seconde même si on passe sur une autre application.
En fait on dit la même chose d'une façon différente :mrgreen:

PS. Oui, il faudrait qu'un modo coupe ce sujet en deux, car ça n'a plus de rapport avec le sujet initial

:wink:
Ekim
Messages : 215
Inscription : dim. 24/juin/2018 1:20

Re: [RESOLU] Bouger une fenêtre via imagegadget

Message par Ekim »

Impeccable merci pour vos réponses :D

ce topic se révèle être une véritable mine d'information

@boby ta méthode est très instructive j'apprends au passage l'utilisation des "Callback"

encore merci pour vos soutiens :wink:
Répondre