Page 1 sur 2

Déplacer à la souris une petite fenêtre sans bordure

Publié : dim. 23/mars/2014 11:03
par Marc56
Je fais un minuscule programme (une petit horloge), composée d'une fenêtre unique, sans bord, ni barre de menu.
Mon souhait est de pouvoir la déplacer à la souris (clic gauche enfoncé puis déplacement de la souris)
Voila le code (expurgé pour isoler la partie déplacement)
Le problème est que ça se déplace très bien, mais que la procédure ne lâche plus la fenêtre :-/
(en clair, une fois le mouvement enclenché, elle ne détecte pas que le bouton gauche est relâché)

(attention: ce code fait planter: il faut quitter par l'IDE)

Code : Tout sélectionner

Global x = 100, y = 100, w = 300, h = 100

OpenWindow(0, x, y, w, h, "", #PB_Window_BorderLess | #PB_Window_BorderLess)

Repeat
  event = WaitWindowEvent()
  Select event
      
        ; Clic DROIT sur la fenêtre = Quitter
        Case #PB_Event_RightClick
          End
          
        ; Clic GAUCHE = Déplacer la fenêtre sur la position de la souris  
        Case #PB_Event_LeftClick
            While #PB_EventType_LeftButtonDown
              ResizeWindow(0, DesktopMouseX(), DesktopMouseY(), w, h)
              ; Ici la fenêtre se déplace bien, mais ne détecte pas que le bouton gauche est relaché :-/
              ; Comment forcer la relecture d'event ?
            Wend  
    
  EndSelect
Until Event = #PB_Event_CloseWindow
J'ai une demi-solution en mettant un 'break' dans ma boucle while/wend, mais ce n'est pas satisfaisant.
J'ai aussi essayé avec un delay(200), mais marche pas.
Puis-je injecter un event dans la file (au niveau de la while/wend) ?

J'ai trouvé quelques exemples ça et là, mais je souhaite si possible rester en pur basic (en deux mots), c'est à dire ne pas faire appel direct aux API système ni aux pointeurs, ni bidouille :-)

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : dim. 23/mars/2014 13:44
par Backup
comme ça ;)


Code : Tout sélectionner

; German forum:
; Author: Danilo
; Date: 18. April 2003
#Fenetre=0
#stop=88 ; on creer un evenement pour quitter !!!
hwnd = OpenWindow(#Fenetre, 200, 200, 300, 300,  "...",#PB_Window_BorderLess)
AddKeyboardShortcut(#Fenetre,#PB_Shortcut_Escape, #stop) ; ici on relie le numero d'evenement (88) a la touche escape !!
Repeat
	Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
		End
		Case #WM_LBUTTONDOWN ; on recupere l'evenement d'un click souris gauche
		SendMessage_(hwnd, #WM_NCLBUTTONDOWN, #HTCAPTION, 0) ; ceci fait suivre la fenetre avec la souris
		Case #WM_LBUTTONUP ; on a relaché le bouton souris
		Debug "clic"
		Case #WM_RBUTTONDOWN ; on recupere l'evenement d'un click souris gauche
		End
		Case #PB_Event_Menu ; on a cree un numero d'evenement clavier (menu), on pourra quitter le prg grace a esc !!
		Select  EventMenu()
			Case #stop 
			End 
		EndSelect 
	EndSelect
ForEver 
; Epb


Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : dim. 23/mars/2014 14:42
par Marc56
OK, Merci Dobro :D

Donc voici mon exemple minimal modifié avec ces infos.
(J'ai juste mis un id sur la fenêtre et utilisé SendMessage_)

Code : Tout sélectionner

Global x = 100, y = 100, w = 300, h = 100

Fenetre = OpenWindow(0, x, y, w, h, "", #PB_Window_BorderLess | #PB_Window_BorderLess)

Repeat
  event = WaitWindowEvent()
  Select event
      
        ; Clic DROIT sur la fenêtre = Quitter
        Case #PB_Event_RightClick
          End
          
        ; Clic GAUCHE = Déplacer la fenêtre sur la position de la souris
        Case #WM_LBUTTONDOWN
          SendMessage_(Fenetre, #WM_NCLBUTTONDOWN, #HTCAPTION, 0)  
    
  EndSelect
Until Event = #PB_Event_CloseWindow
Parfait, ça marche. :D
Cependant, j'ai un peu de scrupule à utiliser SendMessage_ qui fait partie de l'API Windows.
J'aurais bien aimé trouver une solution compatible toutes plateformes (juste pour le principe de compatibilité) :)

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : dim. 23/mars/2014 16:05
par Backup
Marc56 a écrit : Cependant, j'ai un peu de scrupule à utiliser SendMessage_ qui fait partie de l'API Windows. :)
pour info : #WM_LBUTTONDOWN aussi fait parti de l'API window ....

tant que l'equipe de développement , n'aura pas fait une veritable librairie pour la souris
(Directx mais surtout Application ) ben on sera contraint d'utiliser l'api Windows ...

a moins de connaitre les constantes (les apis ) spécifique a tous les OS ....

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : dim. 23/mars/2014 16:12
par nico
J'utilise rarement les constantes de PureBasic, je n'ai pas vu les constantes down et up de la souris, il suffirait juste de traiter les trois événements, le down du clic gauche, le up du clic gauche et le move de la souris pour réaliser un déplacement.

Cela qui oblige de passer par un Canva qui gère ces événements et ça marche très bien sauf qu'il faut cliquer sur une zone déterminée pour le déplacement mais c'est plus élégant et est plus censé d'un point de vue utiisateur.

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : dim. 23/mars/2014 16:36
par nico
Voilà un exemple pour le concept, faudrait finaler en mettant un icone de redimensionnement dans le Canva:

Code : Tout sélectionner

Global x = 100, y = 100, w = 300, h = 100
Global Test.l, Quit.l

Enumeration
  #Main
EndEnumeration

Enumeration
  #Canvas
  #Button
EndEnumeration

Fenetre = OpenWindow(#Main, x, y, w, h, "", #PB_Window_BorderLess | #PB_Window_BorderLess)
Resultat = CanvasGadget(#Canvas, w - 30, h - 30, 20, 20)
ButtonGadget(#Button, w-50, 10, 40, 20, "Quit")

Repeat
  event = WaitWindowEvent()
  Select event
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Canvas
          Select  EventType()
            Case #PB_EventType_LeftButtonDown
              Debug "#PB_EventType_LeftButtonDown"
              Test = 1
                MouseX1 = WindowX(#Main)
                MouseY1 = WindowY(#Main)
                MouseX2 = DesktopMouseX()
                MouseY2 = DesktopMouseY() 
                
                DecalageX = MouseX2  - MouseX1
                DecalageY = MouseY2  - MouseY1          
                
            Case #PB_EventType_MouseMove
              Debug "#PB_EventType_MouseMove"
              If Test = 1
                MouseX = DesktopMouseX()
                MouseY = DesktopMouseY()  
                
                x = MouseX - DecalageX
                y = MouseY - DecalageY
                
                ResizeWindow(#Main, x, y, #PB_Ignore, #PB_Ignore)
              EndIf
          
              
            Case #PB_EventType_LeftButtonUp
              Debug "#PB_EventType_LeftButtonUp"
              Test = 0
              
          EndSelect
          
        Case #Button
          Quit = 1
          
      EndSelect

  EndSelect
Until Quit = 1

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : dim. 23/mars/2014 18:41
par Marc56
Effectivement, très intéressante, élégante et logique pour l'utilisateur cette méthode avec le Canvas.
Méthode PureBasic pur jus, donc compatible tous OS :D
Et comme je souhaite que mon horloge ait la forme d'une barre, je peux mettre le canvas comme une zone de grip à droite ou à gauche.

En plus, comme je la force à rester au dessus de toutes les autres fenêtre Windows (avec StickyWindow(#Main, #True)) je vais même transformer ma petite pendule en lanceur d'application.
Plein d'idées tout d'un coup! :idea:

Merci à vous deux.
:P

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : lun. 24/mars/2014 10:19
par Marc56
Question subsidiaire: Peut-on faire en sorte de rien afficher dans la barre de tâche ET que la fenêtre n'ait pas de bord ?

En effet, #PB_Window_Tool semble la seule option qui n'affiche rien dans la barre de tâche, mais elle annule l'effet de #PB_Window_BorderLess

(Je m'aperçois que dans mon code d'ouverture de fenêtre principale, j'ai mis deux fois #PB_Window_BorderLess)

J'ai pensé qu'en mettant une trayicon, la barre de tâche serait libérée, mais non :? (mais c'est logique, on peut avoir besoin des deux)

J'ai bien la ressource d'utiliser le très ancien utilitaire TrayIt, mais je perd l'intérêt du tout-en-un.

:wink:

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : lun. 24/mars/2014 10:50
par falsam
Marc56 a écrit :Question subsidiaire: Peut-on faire en sorte de rien afficher dans la barre de tâche ET que la fenêtre n'ait pas de bord ?
C'est possible mais moyennant une API. (J'ai bien compris que tu ne le souhaitais pas)

Code : Tout sélectionner

hWnd = OpenWindow(0, 0, 0, 300, 100," Hello", #PB_Window_BorderLess|#PB_Window_Invisible)

If hWnd
  SetWindowLong_(hWnd,#GWL_EXSTYLE, #WS_EX_TOOLWINDOW) ;Astuces pour empecher la fenetre d'apparaitre dans la barre des taches
  HideWindow(0, #False) ; Rendre de nouveau la fenetre visible
EndIf

Repeat
  Event  = WaitWindowEvent(10)
  Select Event
        
    Case #PB_Event_CloseWindow
      End
  EndSelect
ForEver
Je n'ai pas insérer le code de déplacement de la fenetre.

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : lun. 24/mars/2014 11:23
par Backup
heu ...

ça ne marche pas ça : ??

Code : Tout sélectionner


hWnd = OpenWindow(0, 0, 0, 300, 100," Hello", #PB_Window_BorderLess|#PB_Window_Tool )


Repeat
	Event  = WaitWindowEvent(10)
	Select Event
		
		Case #PB_Event_CloseWindow
		End
	EndSelect
ForEver
; Epb


Sans bordures, et n'apparait pas en barre des taches .... :wink:

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : lun. 24/mars/2014 11:28
par Marc56
Dobro a écrit :hWnd = OpenWindow(0, 0, 0, 300, 100," Hello", #PB_Window_BorderLess|#PB_Window_Tool )


Repeat
Event = WaitWindowEvent(10)
Select Event

Case #PB_Event_CloseWindow
End
EndSelect
ForEver
; Epb
Hélas non, j'ai une bordure (fine) et une barre titre.
Mais c'est peut-être dû à Windows 8.1 ?

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : lun. 24/mars/2014 11:31
par Backup
haaa .. oui la barre de titre :oops:

[Reedit]
effectivement , sans APi point de salut :)

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : lun. 24/mars/2014 11:31
par Marc56
falsam a écrit :C'est possible mais moyennant une API. (J'ai bien compris que tu ne le souhaitais pas)
Tant pis, je m'y ferais.
De toutes façons si j’utilise aussi la trayicon, je perd le bénéfice de la compatibilité avec d'autres os (mais ce n'était pas le but initial, juste un souhait)
Du coup je peux rester aussi dans la solution tout API avec #WM_

Merci à vous tous.
Maintenant, tout fonctionne :P

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : lun. 24/mars/2014 11:38
par Backup
quoiqu'il en soit , si tu avait fait une recherche sur le forum avec le mot "Horloge"

tu aurai pu entre pleins d'autres.....
tomber sur mon horloge polygone
http://www.purebasic.fr/french/viewtopi ... it=horloge

qui contient tout ce que tu as cherché a faire (pas de bordures , pas de trace dans la barres des taches , et déplaçable ) :)


faire une horloge , fait parti des premiers trucs qu'on cherche a faire , donc tu en trouvera pas mal :lol:

Re: Déplacer à la souris une petite fenêtre sans bordure

Publié : lun. 24/mars/2014 11:47
par Marc56
Comme quoi le choix des mots est important :mrgreen:
j'ai cherché "fenêtre sans bordure" "fenêtre flottante" et autres termes compliqués
et pas pensé à faire simplement horloge :roll:

Beau boulot, il y a de quoi faire :D