How to bind the second event to the button?

Just starting out? Need help? Post your questions and find answers here.
AZJIO
Enthusiast
Enthusiast
Posts: 457
Joined: Sun May 14, 2017 1:48 am

How to bind the second event to the button?

Post by AZJIO »

I have a launcher with buttons to launch programs.
I want to be able to open the program's link.
Ideally, I would like to open the menu with the right mouse button, but this event does not exist for the button.
I press F2 to show the menu for the active button.

Code: Select all

hMenuURL = CreatePopupMenu(#MenuURL)
If hMenuURL
	MenuItem(mF22, "Open url")
	AddKeyboardShortcut(#Window, #PB_Shortcut_F2, mF2)
EndIf
;..........................
Case mF2
	If SelectElement(BtnLst() , btnactive) And Asc(BtnLst()\url)
		DisplayPopupMenu(#MenuURL, hGUI)
	EndIf
Case mF22
	RunProgram(BtnLst()\url)
I tried double-clicking the mouse, but PureBasic treats it as two clicks. I will have to do button events in the callback function (Callback + BN_CLICKED).

Code: Select all

Case #WM_COMMAND
	nNotifyCode = wParam >> 16  ; HiWord
	If nNotifyCode = #BN_DOUBLECLICKED
		ForEach BtnLst()
			If GadgetID(BtnLst()\id) = LParam
        		If SelectElement(BtnLst() , btnactive) And Asc(BtnLst()\url)
        			RunProgram(BtnLst()\url)
        		EndIf
			EndIf
		Next
	EndIf
How do I make it so that when I press the Ctrl button I would get a different event

Code: Select all

Select g_event
	Case 0 To d
		If GetAsyncKeyState_(#VK_F1)
			Message(g_event)
		Else
			EventBtnMenu(g_event)
		EndIf
EndSelect
It works if you press F1 beforehand
infratec
Always Here
Always Here
Posts: 5849
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: How to bind the second event to the button?

Post by infratec »

Build your own CanvasButton() with a CanvasGadget().
Then you have all event types available.

An example:
https://www.purebasic.fr/english/viewto ... on#p356366
BarryG
Addict
Addict
Posts: 2184
Joined: Thu Apr 18, 2019 8:17 am

Re: How to bind the second event to the button?

Post by BarryG »

AZJIO wrote: Sun Feb 06, 2022 11:07 pmI would like to open the menu with the right mouse button, but this event does not exist for the button.
Try #WM_RBUTTONDOWN for the event.
AZJIO
Enthusiast
Enthusiast
Posts: 457
Joined: Sun May 14, 2017 1:48 am

Re: How to bind the second event to the button?

Post by AZJIO »

BarryG wrote: Mon Feb 07, 2022 12:26 amTry #WM_RBUTTONDOWN for the event.
Returns the coordinates, but it works only on the client area of ​​the window, not over the buttons.

Code: Select all

Case #WM_RBUTTONDOWN
	Debug LParam >> 16
	Debug LParam & $FFFF
BarryG
Addict
Addict
Posts: 2184
Joined: Thu Apr 18, 2019 8:17 am

Re: How to bind the second event to the button?

Post by BarryG »

Do you want something like this?

Code: Select all

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

OpenWindow(0,100,100,130,70,"test")
ButtonGadget(0,10,10,110,50,"Right-click me")

Repeat
  ev=WaitWindowEvent()
  If ev=#WM_RBUTTONDOWN
    If MouseIsOver(GadgetID(0))
      SetGadgetText(0,"Hello")
      Sleep_(500)
      SetGadgetText(0,"Right-click me")
    EndIf
  EndIf
Until ev=#PB_Event_CloseWindow
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4224
Joined: Sun Apr 12, 2009 6:27 am

Re: How to bind the second event to the button?

Post by RASHAD »

Code: Select all

Procedure MouseHook(nCode, wParam, lParam)
  GetCursorPos_(@p.POINT) 
  gadID = WindowFromPoint_(p\x|p\y<<32)
  Select wParam
    Case #WM_LBUTTONDBLCLK
      Debug "Gadget "+Str(GetDlgCtrlID_(gadID))+" Left Mouse DblClicked"
      
    Case #WM_LBUTTONDOWN 
      Debug "Gadget "+Str(GetDlgCtrlID_(gadID))+" Left Mouse Down"
      
    Case  #WM_RBUTTONDBLCLK
      Debug "Gadget "+Str(GetDlgCtrlID_(gadID))+" Right Mouse DblClicked"
      
    Case  #WM_RBUTTONDOWN
      Debug "Gadget "+Str(GetDlgCtrlID_(gadID))+" Right Mouse Down"
      
    Case  #WM_RBUTTONUP
      Debug "Gadget "+Str(GetDlgCtrlID_(gadID))+" Right Mouse UP"
      
  EndSelect
  ProcedureReturn result
EndProcedure

OpenWindow(0,0,0,600,400,"", #PB_Window_SystemMenu| #PB_Window_ScreenCentered)
ContainerGadget(0,10,10,200,200,#PB_Container_Flat)
ButtonGadget(1,10,10,80,25,"#1")
ButtonGadget(2,10,40,80,24,"#2")
CloseGadgetList()

lpdwProcessId = GetWindowThreadProcessId_(WindowID(0), 0)
hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE, @MouseHook(), GetModuleHandle_(0), lpdwProcessId)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      UnhookWindowsHookEx_(hhkLLMouse)
      Quit = 1
  EndSelect
Until Quit = 1
Egypt my love
AZJIO
Enthusiast
Enthusiast
Posts: 457
Joined: Sun May 14, 2017 1:48 am

Re: How to bind the second event to the button?

Post by AZJIO »

BarryG
This option is not suitable because you need to check 40 buttons that the cursor is not on any of them. It is more logical to get the ID above which is located. I think it can be done.

RASHAD
The example works reliably, but embedding itself in the program performs multiple events as if I pressed a button 20 times, or 5, or 8, randomly. Doesn't conflict with WinCallback?
BarryG
Addict
Addict
Posts: 2184
Joined: Thu Apr 18, 2019 8:17 am

Re: How to bind the second event to the button?

Post by BarryG »

AZJIO wrote: Mon Feb 07, 2022 3:19 amThis option is not suitable because you need to check 40 buttons that the cursor is not on any of them
I'm only guessing what you want because I don't have any runnable code to test, or a way to see the big picture. What exactly do you want the right-click to do? My initial reply with my code was based on you saying "this event (right-click) does not exist for the button", so I provided you a way to right-click a button and get that event. But now you're saying to check that the mouse ISN'T on any button?
AZJIO
Enthusiast
Enthusiast
Posts: 457
Joined: Sun May 14, 2017 1:48 am

Re: How to bind the second event to the button?

Post by AZJIO »

Code: Select all

Procedure GetID()
	Protected gadID, n, p.POINT
	GetCursorPos_(@p.POINT) 
	gadID = WindowFromPoint_(p\x|p\y<<32)
	If gadID = WindowID(0)
		ProcedureReturn -1
	EndIf
	n = GetDlgCtrlID_(gadID)
	ProcedureReturn n
EndProcedure

OpenWindow(0,100,100,130,90,"test")
ButtonGadget(0,10,5,110,20,"Right-click me")
ButtonGadget(1,10,30,110,20,"Right-click me")
ButtonGadget(2,10,55,110,20,"Right-click me")

Define n

Repeat
	ev=WaitWindowEvent()
	If ev=#WM_RBUTTONDOWN
		n = GetID()
		If n > -1
			SetGadgetText(n,"Hello")
			Sleep_(500)
			SetGadgetText(n,"Right-click me")
		EndIf
	EndIf
Until ev=#PB_Event_CloseWindow
Thanks, I'll study the examples.

BarryG
Look at here (Launcher-URL, source included).
Last edited by AZJIO on Mon Feb 07, 2022 4:13 am, edited 1 time in total.
BarryG
Addict
Addict
Posts: 2184
Joined: Thu Apr 18, 2019 8:17 am

Re: How to bind the second event to the button?

Post by BarryG »

Is this what you're after?

Code: Select all

Procedure GadgetUnderMouse()
  GetCursorPos_(@pt.POINT)
  hWnd=WindowFromPoint_(PeekQ(@pt))
  If hWnd=WindowID(0)
    gad=-1
  Else
    gad=GetDlgCtrlID_(hWnd)
  EndIf
 ProcedureReturn gad
EndProcedure

OpenWindow(0,100,100,130,90,"test")
ButtonGadget(0,10,5,110,20,"Right-click me")
ButtonGadget(1,10,30,110,20,"Right-click me")
ButtonGadget(2,10,55,110,20,"Right-click me")

Repeat
  ev=WaitWindowEvent()
  If ev=#WM_RBUTTONUP
    gad=GadgetUnderMouse()
    If gad<>-1
      SetGadgetText(gad,"Hello")
      Sleep_(500)
      SetGadgetText(gad,"Right-click me")
    EndIf
  EndIf
Until ev=#PB_Event_CloseWindow
AZJIO
Enthusiast
Enthusiast
Posts: 457
Joined: Sun May 14, 2017 1:48 am

Re: How to bind the second event to the button?

Post by AZJIO »

In the help, in the description of the EventlParam() function, there is an example using Ctrl and Shift keys. I also asked about this in the first post to expand the functionality of the button.

Code: Select all

EnableExplicit
Declare MouseHook(nCode, wParam, lParam)

Define lpdwProcessId, hhkLLMouse, i
Global hGUI

Procedure MouseHook(nCode, wParam, lParam)
	Protected *MHS.MOUSEHOOKSTRUCT = lParam

; 	= MOUSEHOOKSTRUCT =
; 	pt.POINT
; 	hwnd.i
; 	wHitTestCode.l
; 	dwExtraInfo.i

	Static ChangingID
	
	Select wParam
		Case #WM_LBUTTONUP
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Left Mouse UP"
		Case #WM_LBUTTONDOWN 
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Left Mouse Down"
		Case #WM_LBUTTONDBLCLK
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Left Mouse DblClicked"
		Case  #WM_RBUTTONUP
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Right Mouse UP"
		Case  #WM_RBUTTONDOWN
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Right Mouse Down"
		Case  #WM_RBUTTONDBLCLK
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Right Mouse DblClicked"
		Case  #WM_MBUTTONUP
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Middle Mouse UP"
		Case  #WM_MBUTTONDOWN
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Middle Mouse Down"
		Case  #WM_MBUTTONDBLCLK
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Middle Mouse DblClicked"
			
; 		=== click in a non-client area ===
; 		Case  #WM_NCLBUTTONUP
; 		Case  #WM_NCLBUTTONDOWN
; 		Case  #WM_NCLBUTTONDBLCLK
; 		Case  #WM_NCRBUTTONUP
; 		Case  #WM_NCRBUTTONDOWN
; 		Case  #WM_NCRBUTTONDBLCLK
; 		Case  #WM_NCMBUTTONUP
; 		Case  #WM_NCMBUTTONDOWN
; 		Case  #WM_NCMBUTTONDBLCLK
; 		=== additional mouse button ===
; 		Case  #WM_XBUTTONUP
; 		Case  #WM_XBUTTONDOWN
; 		Case  #WM_XBUTTONDBLCLK
			
		Case  #WM_MOUSEWHEEL
			Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Mouse wheel"
			
		Case  #WM_MOUSEMOVE
			If *MHS\hwnd <> hGUI And ChangingID <> *MHS\hwnd
				ChangingID = *MHS\hwnd
				Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Changing"
			EndIf
			
	EndSelect
EndProcedure

hGUI = OpenWindow(0,0,0,600,400,"", #PB_Window_SystemMenu| #PB_Window_ScreenCentered)
For i = 0 To 9
	ButtonGadget(i,10,i * 30,80,25,Str(i))
Next

lpdwProcessId = GetWindowThreadProcessId_(WindowID(0), 0)
hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE, @MouseHook(), GetModuleHandle_(0), lpdwProcessId)

Repeat
	Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
			UnhookWindowsHookEx_(hhkLLMouse)
			Break
	EndSelect
ForEver
BarryG
Addict
Addict
Posts: 2184
Joined: Thu Apr 18, 2019 8:17 am

Re: How to bind the second event to the button?

Post by BarryG »

You didn't answer my question. I think my code just above is what you want to do, right?
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4224
Joined: Sun Apr 12, 2009 6:27 am

Re: How to bind the second event to the button?

Post by RASHAD »

Code: Select all

Procedure MouseHook(nCode, wParam, lParam)
	Protected *MHS.MOUSEHOOKSTRUCT = lParam
        bcontrol = GetAsyncKeyState_(#VK_CONTROL)
        balt = GetAsyncKeyState_(#VK_MENU)
        bshift = GetAsyncKeyState_(#VK_SHIFT)

	Static ChangingID
	
	Select wParam
		Case #WM_LBUTTONUP
		  If bcontrol
			  Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Control + Left Mouse UP"
			Else
			  Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Left Mouse UP"
			EndIf
		Case #WM_LBUTTONDOWN
		  If bshift 
			  Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Shift + Left Mouse Down"
			Else
			  Debug "Gadget "+Str(GetDlgCtrlID_(*MHS\hwnd))+" Left Mouse Down"
			EndIf
Egypt my love
Post Reply