Page 1 sur 1

Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : jeu. 04/mai/2017 20:32
par Bahamut
Salutations! J'ai ce problème: je dois ouvrir un menu contextuel lorsque vous placez le curseur sur le bord du bureau, puis cliquez sur le bouton droit de la souris, l'argent de la fenêtre devait être vu. Il existe une version du code, mais il ne fonctionne pas correctement.

Ici, le menu est créé, mais le programme ne fonctionne pas toujours: soit le menu ne disparaît pas si vous cliquez sur un endroit de l'écran, ou un programme se bloque pendant un certain temps de pièce.

Code : Tout sélectionner

EnableExplicit

Global hhkLLMouse, handle, thread1, thread2

Enumeration
    #WIN_MAIN
    #MENU_POPUP
EndEnumeration

Structure MSLLHOOKSTRUCT
    pt.POINT
    mouseData.l
    flags.l
    time.l
    dwExtraInfo.l
EndStructure

Procedure.l MouseHookProcLL(nCode.l, wParam.l, lParam.l)
    
    ;{The menu is created, but it works unstably.
    ;On the desktop, the menu does Not disappear,
    ;when the window is expanded, it disappears 10-15 times And hangs.
    
        Protected *position.POINT, *MOUSESTRUCT.MOUSEHOOKSTRUCT
        
        If nCode = #HC_ACTION
            If lParam <> 0
                *MOUSESTRUCT.MOUSEHOOKSTRUCT = lParam
                *position.POINT=*MOUSESTRUCT\pt
                If wParam = #WM_RBUTTONDOWN
                    If *position\x>=DesktopWidth(0)-1
                        ResizeWindow(#WIN_MAIN, *position\x, *position\y, #PB_Ignore, #PB_Ignore)
                        HideWindow(#WIN_MAIN, 0)
                        handle=FindWindow_(0,#WIN_MAIN)
                        Debug handle
                        thread1=GetWindowThreadProcessId_(GetForegroundWindow_(),0)
                        Debug thread1
                        thread2=GetWindowThreadProcessId_(handle,0)
                        Debug thread2
                        If thread1<>thread2 
                            AttachThreadInput_(thread1,thread2,#True) 
                        EndIf
                        SetForegroundWindow_(handle) 
                        Delay(125) 
                        DisplayPopupMenu(#MENU_POPUP, WindowID(#WIN_MAIN))
                        ;                    HideWindow(#WIN_MAIN, 1)
                        
                    EndIf
                EndIf
            EndIf
        EndIf
    ;}
    ProcedureReturn CallNextHookEx_(hhkLLMouse, nCode, wParam, lParam)
EndProcedure 

ExamineDesktops()

If OpenWindow(#WIN_MAIN, 0, 0, 10, 10, "", #PB_Window_BorderLess | #PB_Window_NoGadgets | #PB_Window_Invisible)
    
    SetWindowLong_(WindowID(#WIN_MAIN), #GWL_EXSTYLE, GetWindowLong_(WindowID(#WIN_MAIN), #GWL_EXSTYLE) | #WS_EX_TOOLWINDOW)
    
    If CreatePopupImageMenu(#MENU_POPUP, #PB_Menu_ModernLook)      
        MenuItem(1, "Open")   
        MenuItem(2, "Save")   
        MenuItem(3, "Save as")
        MenuItem(4, "Quit")
        MenuBar()
        OpenSubMenu("Recent files")
        MenuItem(5, "PureBasic")
        MenuItem(6, "Test")
        CloseSubMenu()
    EndIf
    
    hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE_LL,@MouseHookProcLL(),GetModuleHandle_(0),0)
    
    Repeat
        Select WaitWindowEvent() 
            Case #WM_RBUTTONDOWN
            Case #WM_RBUTTONUP 
            Case #PB_Event_CloseWindow
                Break
            Case #PB_Event_Menu
                Select EventMenu()
                    Case 1 : Debug "Menu: Open"
                    Case 2 : Debug "Menu: Save"
                    Case 3 : Debug "Menu: Save as"
                    Case 4 : Break
                    Case 5 : Debug "Menu: PureBasic"
                    Case 6 : Debug "Menu: Text"
                EndSelect
        EndSelect 
    ForEver
    
    UnhookWindowsHookEx_(hhkLLMouse)
    
    CloseWindow(#WIN_MAIN)
    
EndIf

End



Aide si vous pouvez corriger le code. Merci à l'avance.

Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : ven. 05/mai/2017 10:59
par Mesa
On peut aussi créer une fenêtre tranparente qui recouvre le bureau, comme ça:

Code : Tout sélectionner

; EnableExplicit
; 


Enumeration win
  #WIN_MAIN
EndEnumeration

Enumeration menu
  #MENU_POPUP
EndEnumeration


; PB 5.2 - set windows transparency (Mac,Linux,Windows)
CompilerIf #PB_Compiler_OS=#PB_OS_Linux
  ImportC "-gtk"
    gtk_window_set_opacity(*Window.i, Opacity.d);
    gtk_widget_is_composited(*Widget)
  EndImport
  
  Procedure.i SetWindowTransparency(Window, Transparency=255)
    Protected *windowID=WindowID(Window), alpha.d=Transparency/255.0
    If Transparency>=0 And Transparency<=255
      If gtk_widget_is_composited(*windowID)
        gtk_window_set_opacity(*windowID, alpha.d)
        ProcedureReturn #True
      EndIf
    EndIf
  EndProcedure
CompilerElseIf #PB_Compiler_OS=#PB_OS_MacOS
  Procedure.i SetWindowTransparency(Window, Transparency=255)
    Protected *windowID=WindowID(Window), alpha.CGFloat=Transparency/255.0
    If Transparency>=0 And Transparency<=255
      CocoaMessage(0, *windowID, "setOpaque:", #NO)
      If CocoaMessage(0, *windowID, "isOpaque")=#NO
        CocoaMessage(0, *windowID, "setAlphaValue:@", @alpha)
        ProcedureReturn #True
      EndIf
    EndIf
  EndProcedure
CompilerElseIf #PB_Compiler_OS=#PB_OS_Windows
  Procedure.i SetWindowTransparency(Window, Transparency=255)
    Protected *windowID=WindowID(Window), exStyle=GetWindowLongPtr_(*windowID, #GWL_EXSTYLE)
    If Transparency>=0 And Transparency<=255
      SetWindowLongPtr_(*windowID, #GWL_EXSTYLE, exStyle | #WS_EX_LAYERED)
      SetLayeredWindowAttributes_(*windowID, 0, Transparency, #LWA_ALPHA)
      
      ProcedureReturn #True
    EndIf
  EndProcedure
CompilerEndIf


If OpenWindow(#WIN_MAIN, 0, 0, 0, 0, "", #PB_Window_Maximize|#PB_Window_BorderLess )
  
  SetWindowTransparency(0, 1)
  
  If CreatePopupImageMenu(#MENU_POPUP, #PB_Menu_ModernLook)      
    MenuItem(1, "Open")   
    MenuItem(2, "Save")   
    MenuItem(3, "Save as")
    MenuItem(4, "Quit")
    MenuBar()
    OpenSubMenu("Recent files")
    MenuItem(5, "PureBasic")
    MenuItem(6, "Test")
    CloseSubMenu()
  EndIf
  
  
  Repeat
    Event = WaitWindowEvent()
    Select Event                        ; Examine quel type d'évènement est survenu sur la fenêtre
      Case #PB_Event_RightClick         ; Le bouton droit de la souris a été clické =>
        ExamineDesktops()
        SetWindowTitle(#WIN_MAIN,Str(DesktopMouseX())+"/"+Str(DesktopMouseY()))
        If Bool(DesktopMouseX() <10 Or DesktopMouseX()>DesktopWidth(0)-10 Or
                DesktopMouseY() <10 Or DesktopMouseY()>DesktopHeight(0)-10) = #True
          
          DisplayPopupMenu(#MENU_POPUP,WindowID(#WIN_MAIN)) ; On affiche le menu contextuel
        EndIf
        
        
      Case #PB_Event_Menu      ; Un élément du menu a été sélectionné
        Select EventMenu()     ; On recupère le numéro de cet élement...
          Case 1 : Debug "Menu : Ouvrir"
          Case 2 : Debug "Menu : Enregistrer"
          Case 3 : Debug "Menu : Enregistrer sous"
          Case 4 : End
          Case 5 : Debug "Menu : PureBasic.exe"
          Case 6 : Debug "Menu : Text.txt"
        EndSelect
        
    EndSelect
  Until Event = #PB_Event_CloseWindow
  
  
EndIf
End

M.

Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : ven. 05/mai/2017 11:56
par Zorro
comme ceci

ça marche si , tu choisis en premier un menu

ensuite, meme si tu cliques pour faire réaparaitre
tu peux cliquer en dehors de la fenetre pour la cacher

mais il faut au moins 1 fois , avoir choisi un menu au debut !!

(et je ne sais pas pourquoi il faut lancer au moins une fois le processus pour que le clic en dehors de la fenetre soit pris en compte )
It works if you choose a menu first

Then, even if you click to display the menu
You can click outside the window to hide it

But it takes at least 1 time, having chosen a menu at the beginning !!
(And I do not know why it is necessary to launch at least once the process so that the click outside the window is taken into account)

Ps: j'ai retiré mon code pour pas faire doublon avec celui qui est donné ci dessous

Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : sam. 06/mai/2017 18:58
par Bahamut
Zorro, merci pour la correction.
Mesa Merci pour le code, il pensait faire la même chose.
Voici ce qui est arrivé. Le code fonctionne presque comme un besoin. :)
Quelqu'un peut-il optimiser ou d'offrir une meilleure solution :?:

Code : Tout sélectionner

EnableExplicit

Global Event, hhkLLMouse

Enumeration win
    #WIN_MAIN
EndEnumeration

Enumeration menu
    #MENU_POPUP
EndEnumeration

ExamineDesktops()

Procedure.i SetWindowTransparency(Window, Transparency=255)
    Protected *windowID=WindowID(Window), exStyle=GetWindowLongPtr_(*windowID, #GWL_EXSTYLE)
    If Transparency>=0 And Transparency<=255
        SetWindowLongPtr_(*windowID, #GWL_EXSTYLE, exStyle | #WS_EX_LAYERED)
        SetLayeredWindowAttributes_(*windowID, 0, Transparency, #LWA_ALPHA)
        
        ProcedureReturn #True
    EndIf
EndProcedure


Procedure.l MouseHookProcLL(nCode.l, wParam.l, lParam.l)
    Protected *position.POINT, *MOUSESTRUCT.MOUSEHOOKSTRUCT, handle, thread1, thread2
    If nCode = #HC_ACTION
        If lParam <> 0
            *MOUSESTRUCT.MOUSEHOOKSTRUCT = lParam
            *position.POINT=*MOUSESTRUCT\pt
            If wParam = #WM_RBUTTONDOWN
                If *position\x>=DesktopWidth(0)-2
                    Debug Str(DesktopMouseX())+"/"+Str(DesktopMouseY())
                    
                    HideWindow(#WIN_MAIN, #False) 
                                                  
                    handle=FindWindow_(0,#WIN_MAIN)
                    ;                              Debug handle
                    thread1=GetWindowThreadProcessId_(GetForegroundWindow_(),0)
                    ;                              Debug thread1
                    thread2=GetWindowThreadProcessId_(handle,0)
                    ;                              Debug thread2
                    If thread1<>thread2
                        AttachThreadInput_(thread1,thread2,#True)
                    EndIf
                    SetForegroundWindow_(handle)
                EndIf
            EndIf
            
        EndIf
    EndIf
    
    ProcedureReturn CallNextHookEx_(hhkLLMouse, nCode, wParam, lParam)
EndProcedure

If OpenWindow(#WIN_MAIN, 0, 0, 1, 1, "", #PB_Window_BorderLess | #PB_Window_Maximize)
    
    SetWindowTransparency(#WIN_MAIN, 1)
    
    HideWindow(#WIN_MAIN, #True)
    
    hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE_LL,@MouseHookProcLL(),GetModuleHandle_(0),0)
    
    If CreatePopupImageMenu(#MENU_POPUP, #PB_Menu_ModernLook)      
        MenuItem(1, "Open")   
        MenuItem(2, "Save")   
        MenuItem(3, "Save as")
        MenuItem(4, "Quit")
        MenuBar()
        OpenSubMenu("Recent files")
        MenuItem(5, "PureBasic")
        MenuItem(6, "Test")
        CloseSubMenu()
    EndIf
    
    
    Repeat
        
        Event = WaitWindowEvent()
        Select Event                        
                
            Case #WM_RBUTTONUP
                DisplayPopupMenu(#MENU_POPUP,WindowID(#WIN_MAIN))
                HideWindow(#WIN_MAIN,#True)
            Case #WM_LBUTTONUP
                HideWindow(#WIN_MAIN,#True)
                
                
            Case #PB_Event_Menu      
                Select EventMenu()   
                    Case 1 : Debug "Menu : Open"
                    Case 2 : Debug "Menu : Save"
                    Case 3 : Debug "Menu : Save as"
                    Case 4 : End
                    Case 5 : Debug "Menu : PureBasic"
                    Case 6 : Debug "Menu : Test"
                EndSelect
                
        EndSelect
    Until Event = #PB_Event_CloseWindow
    
    UnhookWindowsHookEx_(hhkLLMouse)
    
EndIf
End


Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : sam. 06/mai/2017 23:29
par Ollivier
Bahamut a écrit : Quelqu'un peut-il optimiser ou d'offrir une meilleure solution ?
Peut-être zapper tout ce truc compliqué et utiliser la SysTray.

Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : dim. 07/mai/2017 7:33
par Zorro
Fonctionne parfaitement chez moi ; Windows 10 :)

ps: ça peut servir d'outils "sous la main" ou de lanceur d'applications ....
personnellement, j'avais fait un lanceur d'applications "Starter" en utilisant le Hook Clavier (avec touches définissable)

mais pourquoi pas utiliser le bords droit de l'ecran c'est une bonne idée ...

Merci pour le code, et pour l'idée :)

Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : dim. 07/mai/2017 11:30
par Ar-S
Je rejoints l'avis d'Ollivier. J'ai déjà fait un soft du genre qui s'affiche lorsqu'on va en bordure d'écran.. Au final j'ai trouvé ça pénible et j'ai tout refait en systray. Plus discret, plus pratique.
http://www.purebasic.fr/french/viewtopi ... =8&t=12337

Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : dim. 07/mai/2017 11:41
par Zorro
Ar-S a écrit :Je rejoints l'avis d'Ollivier. J'ai déjà fait un soft du genre qui s'affiche lorsqu'on va en bordure d'écran.. Au final j'ai trouvé ça pénible et j'ai tout refait en systray. Plus discret, plus pratique.
oui mais là la fenetre popup ne s'affiche que si tu click droit sur le bord droit de l'ecran ...
donc ne s'affiche pas de maniere intempestive ;)
elle ne s'affiche qu'a la demande :) ... plus discret, tu meurs

Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : dim. 07/mai/2017 12:04
par Ar-S
Sauf que par defaut sous windows 8 par exemple, si l'on pointe ta souris dans un bord d'ecran ça fait déjà apparaître une barre latérale windows ;)

Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : dim. 07/mai/2017 12:11
par venom
Ar-S a écrit :Sauf que par defaut sous windows 8 par exemple, si l'on pointe ta souris dans un bord d'ecran ça fait déjà apparaître une barre latérale windows ;)
Exactement :wink: Le SysTray est en native sous pb autant l'utilisé. C'est une utilisation assez "standard"






@++

Re: Vsplyvayushee bureau de menu latéral sans fenêtres

Publié : dim. 07/mai/2017 19:53
par Zorro
oui bah Windows 8 est obsolete ! on est a windows 10 ! :mrgreen: :mrgreen: :lol: