Page 1 of 2

Drop-down menu on hover (?)

Posted: Sat Jul 19, 2025 7:46 am
by AZJIO
What am I doing wrong?

Code: Select all

EnableExplicit

#Window = 0
Enumeration
	#Menu1
	#Menu2
EndEnumeration

Enumeration
	#btn1
	#btn2
EndEnumeration

Structure Point64
	StructureUnion
		p.POINT
		q.q
	EndStructureUnion
EndStructure

Global hGUI

Procedure ChangeButton()
	Protected id_menu, hwndWFP, cursor.POINT64
	Protected BtnRest.RECT
	Static hwndWFP_Old
	GetCursorPos_(cursor.POINT64)
	hwndWFP = WindowFromPoint_(cursor\q)
	If hGUI <> hwndWFP And hwndWFP_Old <> hwndWFP
		hwndWFP_Old = hwndWFP
		id_menu = GetWindowLongPtr_(hwndWFP, #GWL_USERDATA)
; 		id_menu = GetWindowLong_(hwndWFP,#GWL_USERDATA)
; 		Debug hwndWFP
		Debug id_menu
		If id_menu
			Debug 2
; 			GetClientRect_(hwndWFP, @BtnRest)
; 			ClientToScreen_(hwndWFP, @BtnRest)
			GetWindowRect_(hwndWFP, @BtnRest)
			With BtnRest
				DisplayPopupMenu(id_menu, WindowID(#Window), \left, \bottom)
			EndWith
		EndIf
	EndIf
EndProcedure

hGUI = OpenWindow(#Window, 0, 0, 220, 100, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If hGUI
	ButtonGadget(#btn1, 10, 10, 30, 30, "1")
	ButtonGadget(#btn2, 40, 10, 30, 30, "2")
	If CreatePopupMenu(#Menu1)
		MenuItem(1, "Item11")
		MenuItem(2, "Item12")
	EndIf
	If CreatePopupMenu(#Menu2)
		MenuItem(1, "Item21")
		MenuItem(2, "Item22")
	EndIf

	SetGadgetData(#btn1, #Menu1)
	SetGadgetData(#btn2, #Menu2)

	Repeat
		Select WaitWindowEvent()
			Case #WM_MOUSEMOVE
				ChangeButton()
			Case #PB_Event_CloseWindow
				CloseWindow(#Window)
				End
		EndSelect
	ForEver
EndIf

Re: Drop-down menu on hover (?)

Posted: Sat Jul 19, 2025 10:16 am
by drgolf
Hello,

With this i have a popup... maybe this help...

Code: Select all

EnableExplicit

#Window = 0
Enumeration
	#Menu1
	#Menu2
EndEnumeration

Enumeration
	#btn1
	#btn2
EndEnumeration

Structure Point64
	StructureUnion
		p.POINT
		q.q
	EndStructureUnion
EndStructure

Global hGUI

Procedure ChangeButton()
	Protected id_menu, hwndWFP, cursor.POINT
	Protected BtnRest.RECT
	Static hwndWFP_Old
	GetCursorPos_(@cursor)
	hwndWFP = WindowFromPoint_(cursor\y<<32+cursor\x)
	If hGUI <> hwndWFP And hwndWFP_Old <> hwndWFP
		hwndWFP_Old = hwndWFP
		id_menu=GetGadgetData(GetDlgCtrlID_(hwndWFP))
		;id_menu = GetWindowLongPtr_(hwndWFP, #GWL_USERDATA)
; 		id_menu = GetWindowLong_(hwndWFP,#GWL_USERDATA)
; 		Debug hwndWFP
		Debug id_menu
		If id_menu
			Debug 2
; 			GetClientRect_(hwndWFP, @BtnRest)
; 			ClientToScreen_(hwndWFP, @BtnRest)
			GetWindowRect_(hwndWFP, @BtnRest)
			With BtnRest
				DisplayPopupMenu(id_menu, WindowID(#Window), \left, \bottom)
			EndWith
		EndIf
	EndIf
EndProcedure

hGUI = OpenWindow(#Window, 0, 0, 220, 100, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If hGUI
	ButtonGadget(#btn1, 10, 10, 30, 30, "1")
	ButtonGadget(#btn2, 40, 10, 30, 30, "2")
	If CreatePopupMenu(#Menu1)
		MenuItem(1, "Item11")
		MenuItem(2, "Item12")
	EndIf
	If CreatePopupMenu(#Menu2)
		MenuItem(1, "Item21")
		MenuItem(2, "Item22")
	EndIf

	SetGadgetData(#btn1, #Menu1)
	SetGadgetData(#btn2, #Menu2)

	Repeat
		Select WaitWindowEvent()
			Case #WM_MOUSEMOVE
				ChangeButton()
			Case #PB_Event_CloseWindow
				CloseWindow(#Window)
				End
		EndSelect
	ForEver
EndIf



Re: Drop-down menu on hover (?)

Posted: Sat Jul 19, 2025 1:24 pm
by Piero
AZJIO wrote: Sat Jul 19, 2025 7:46 am What am I doing wrong?
I hate having to be repetitive, but YOU DON'T HAVE A MAC! :x (doesn't compile here)

Re: Drop-down menu on hover (?)

Posted: Sat Jul 19, 2025 7:12 pm
by HeX0R
the only useful MAC is this here:
Image

Re: Drop-down menu on hover (?)

Posted: Sat Jul 19, 2025 7:37 pm
by Piero
Image

Re: Drop-down menu on hover (?)

Posted: Sat Jul 19, 2025 10:26 pm
by jacdelad
Piero wrote: Sat Jul 19, 2025 1:24 pm
AZJIO wrote: Sat Jul 19, 2025 7:46 am What am I doing wrong?
I hate having to be repetitive, but YOU DON'T HAVE A MAC! :x (doesn't compile here)
It contains obvious windows API calls. How about not trying to be funny in every reply?

Re: Drop-down menu on hover (?)

Posted: Sun Jul 20, 2025 3:39 am
by BarryG
Piero wrote: Sat Jul 19, 2025 1:24 pmI hate having to be repetitive, but YOU DON'T HAVE A MAC! :x (doesn't compile here)
What's a Mac got to do with it? He didn't post in the Mac section of the forum.

Re: Drop-down menu on hover (?)

Posted: Sun Jul 20, 2025 11:08 am
by Mindphazer
Hi Barry, AZJIO's code was posted in the Coding Questions section (witch is not OS specific), but it contains Windows API... That's all :)

Re: Drop-down menu on hover (?)

Posted: Sun Jul 20, 2025 12:39 pm
by mk-soft
jacdelad wrote: Sat Jul 19, 2025 10:26 pm
Piero wrote: Sat Jul 19, 2025 1:24 pm
AZJIO wrote: Sat Jul 19, 2025 7:46 am What am I doing wrong?
I hate having to be repetitive, but YOU DON'T HAVE A MAC! :x (doesn't compile here)
It contains obvious windows API calls. How about not trying to be funny in every reply?
Should recognise after the time here that it is not for macOS and uses Windows API (or Linux API) ...

Re: Drop-down menu on hover (?)

Posted: Sun Jul 20, 2025 4:11 pm
by Axolotl
AFAIK this (as far as I understand it) can be done without API calls in the procedures.

Code: Select all

Procedure DisplayPopupMenuWithGadget(Gadget, Menu) ; VOID 
  Protected x, y 

  x = GadgetX(Gadget, #PB_Gadget_ScreenCoordinate) 
  y = GadgetY(Gadget, #PB_Gadget_ScreenCoordinate) + GadgetHeight(Gadget) 

  DisplayPopupMenu(Menu, WindowID(#Window), x, y)  ; no return value 
EndProcedure 

Procedure ChangeButton() ; adapted to my understanding ??? 
  Protected x, y 
  
  x = WindowMouseX(#Window) 
  y = WindowMouseY(#Window) 

  If x >= GadgetX(#btn1) And x <= GadgetX(#btn1) + GadgetWidth(#btn1) 
    If y >= GadgetY(#btn1) And y <= GadgetY(#btn1) + GadgetHeight(#btn1) 
      DisplayPopupMenuWithGadget(#btn1, #menu1) 
      ProcedureReturn ; no return value 
    EndIf 
  EndIf 

  If x >= GadgetX(#btn2) And x <= GadgetX(#btn2) + GadgetWidth(#btn2) 
    If y >= GadgetY(#btn2) And y <= GadgetY(#btn2) + GadgetHeight(#btn2) 
      DisplayPopupMenuWithGadget(#btn2, #menu2) 
      ProcedureReturn ; no return value 
    EndIf 
  EndIf 
EndProcedure 

Re: Drop-down menu on hover (?)

Posted: Sun Jul 20, 2025 6:23 pm
by AZJIO
Piero wrote: Sat Jul 19, 2025 1:24 pm I hate having to be repetitive, but YOU DON'T HAVE A MAC! :x (doesn't compile here)
I'm writing a DBar utility, and I need the code for it. I don't think it's possible to write a cross-platform version, as there's a window that pops up when you hover over the top of the screen.
I bought a new computer and installed Win11. Now several programs are not working as expected and I can't create a drop-down menu in the taskbar. I have to use DBar and SaveFolders.

I realized that I can't use the menu because it takes focus and becomes the foreground. I already had an example with a pop-up window, but it requires creating windows that mimic menus.

There was also a topic about creating your own menu, but I haven't found it yet (I've already found it). The color of the menu and buttons changed, and a non-standard technique was used in the code. By RASHAD

Re: Drop-down menu on hover (?)

Posted: Sun Jul 20, 2025 10:01 pm
by BarryG
Mindphazer wrote: Sun Jul 20, 2025 11:08 am Hi Barry, AZJIO's code was posted in the Coding Questions section (witch is not OS specific), but it contains Windows API... That's all :)
I know that, which was my entire point. Piero shouldn't be complaining just because someone doesn't have a Mac and posted Win code here.

Re: Drop-down menu on hover (?)

Posted: Mon Jul 21, 2025 12:42 am
by RASHAD
Hi
Quick hack for Windows ONLY :D
Adapt it for your needs
DPI aware

Code: Select all

Global dpix.d,dpiy.d
dpix = DesktopResolutionX()
dpiy = DesktopResolutionY()

#Window = 0
Enumeration
  #Menu1
  #Menu2
EndEnumeration

Enumeration
  #btn1
  #btn2
EndEnumeration

Procedure IsMouseOver(hWnd) 
  GetWindowRect_(hWnd,r.RECT) 
  GetCursorPos_(p.POINT) 
  Result = PtInRect_(r,p\y << 32 + p\x) 
  ProcedureReturn Result 
EndProcedure 

Procedure WindowCallback(hWnd,uMsg,wParam,lParam)
  Select uMsg
    Case #WM_ENTERIDLE
      GetCursorPos_(cpt.POINT)   
      If WindowFromPoint_(cpt\y<<32 + cpt\x) = hwnd
        SendMessage_(hwnd, #WM_CANCELMODE,0,0)
      EndIf
  EndSelect
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

hGUI = OpenWindow(#Window, 0, 0, 220, 100, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If hGUI
  ButtonGadget(#btn1, 10, 10, 30, 30, "1")
  ButtonGadget(#btn2, 45, 10, 30, 30, "2")
  If CreatePopupMenu(#Menu1)
    MenuItem(1, "Item11")
    MenuItem(2, "Item12")
  EndIf
  If CreatePopupMenu(#Menu2)
    MenuItem(3, "Item21")
    MenuItem(4, "Item22")
  EndIf
EndIf

SetWindowCallback(@WindowCallback())

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case EventMenu()
          Debug EventMenu()
      EndSelect
      
    Case #WM_MOUSEMOVE
      If IsMouseOver(GadgetID(#btn1))
        DisplayPopupMenu(#Menu1, WindowID(#Window), GadgetX(#btn1,#PB_Gadget_ScreenCoordinate )*dpix,GadgetY(#btn1,#PB_Gadget_ScreenCoordinate )*dpiy+40)
      ElseIf IsMouseOver(GadgetID(#btn2))
        DisplayPopupMenu(#Menu2, WindowID(#Window), GadgetX(#btn2,#PB_Gadget_ScreenCoordinate )*dpix,GadgetY(#btn2,#PB_Gadget_ScreenCoordinate )*dpiy+40)
      EndIf
  EndSelect 
Until Quit = 1


Re: Drop-down menu on hover (?)

Posted: Mon Jul 21, 2025 6:07 am
by Piero
Strange: this works on Mac and Linux, but win11 does not trigger #PB_EventType_MouseMove
 

Code: Select all

EnableExplicit

#Window = 0
Enumeration
   #Menu1
   #Menu2
EndEnumeration

Enumeration
   #btn1
   #btn2
   #CAN1
   #CAN2
EndEnumeration

Global hGUI, Event

Procedure DisplayPopupMenuWithGadget(Gadget, Menu) ; VOID 
   Protected x, y 
   x = GadgetX(Gadget, #PB_Gadget_ScreenCoordinate) 
   y = GadgetY(Gadget, #PB_Gadget_ScreenCoordinate) + GadgetHeight(Gadget) + 6
   DisplayPopupMenu(Menu, WindowID(#Window), x, y)  ; no return value 
EndProcedure 

hGUI = OpenWindow(#Window, 0, 0, 220, 120, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If hGUI
   CanvasGadget(#CAN1, 10, 10, 30, 30,#PB_Canvas_Container)
   ButtonGadget(#btn1, 0, 0, 30, 30,"1")
   CloseGadgetList()
   CanvasGadget(#CAN2, 50, 10, 30, 30,#PB_Canvas_Container)
   ButtonGadget(#btn2, 0, 0, 30, 30,"2")
   CloseGadgetList()
   If StartDrawing(CanvasOutput(#CAN1))
      Box(0, 0, 999, 999, #Black) ; good for dark mode on mac
      StopDrawing()
   EndIf
   If StartDrawing(CanvasOutput(#CAN2))
      Box(0, 0, 999, 999, #Black) ; good for dark mode on mac
      StopDrawing()
   EndIf
   If CreatePopupMenu(#Menu1)
      MenuItem(1, "Item 11")
      MenuItem(2, "Item 12")
   EndIf
   If CreatePopupMenu(#Menu2)
      MenuItem(3, "Item 21")
      MenuItem(4, "Item 22")
   EndIf
   Repeat
      Event = WaitWindowEvent()
      Select Event
         Case  #PB_Event_Gadget
            Select EventGadget() 
               Case #CAN1
                  Select EventType()
                     Case #PB_EventType_MouseMove ; alt must be pressed
                        If GetGadgetAttribute(#CAN1,#PB_Canvas_Modifiers)&#PB_Canvas_Alt
                           Debug "#PB_EventType_MouseMove 1"
                           DisplayPopupMenuWithGadget(#CAN1, #menu1)
                        EndIf
                  EndSelect
               Case #CAN2
                  Select EventType()
                     Case #PB_EventType_MouseMove ; alt must be pressed
                        If GetGadgetAttribute(#CAN2,#PB_Canvas_Modifiers)&#PB_Canvas_Alt
                           Debug "#PB_EventType_MouseMove 2"
                           DisplayPopupMenuWithGadget(#CAN2, #Menu2)
                        EndIf
                  EndSelect
               Case #btn1 : Debug "Button 1 clicked!"
               Case #btn2 : Debug "Button 2 clicked!"
            EndSelect
         Case #PB_Event_Menu
            Select EventMenu()
               Case 1 : Debug "Menu item 11 clicked!"
               Case 2 : Debug "Menu item 12 clicked!"
               Case 3 : Debug "Menu item 21 clicked!"
               Case 4 : Debug "Menu item 22 clicked!"
            EndSelect
         Case #PB_Event_CloseWindow
            End
      EndSelect
   ForEver
EndIf
Edit: used #PB_EventType_MouseMove instead of mouse enter, because it seems to work better (doesn't "get triggered" while menu is open)
Note: #PB_Canvas_Modifiers #PB_Canvas_Alt seems to work well only on Mac

Re: Drop-down menu on hover (?)

Posted: Mon Jul 21, 2025 6:45 am
by jacdelad
Can't test right now, but I believe the button is receiving the entering message (and PB is not processing it for buttons). Don't know whether it's a but or desired behaviour by Windows.