Page 1 of 1

How to bind the second event to the button?

Posted: Sun Feb 06, 2022 11:07 pm
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

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

Posted: Mon Feb 07, 2022 12:02 am
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

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

Posted: Mon Feb 07, 2022 12:26 am
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.

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

Posted: Mon Feb 07, 2022 12:56 am
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

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

Posted: Mon Feb 07, 2022 1:43 am
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

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

Posted: Mon Feb 07, 2022 1:55 am
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

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

Posted: Mon Feb 07, 2022 3:19 am
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?

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

Posted: Mon Feb 07, 2022 3:24 am
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?

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

Posted: Mon Feb 07, 2022 3:31 am
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).

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

Posted: Mon Feb 07, 2022 4:13 am
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

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

Posted: Mon Feb 07, 2022 11:59 pm
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

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

Posted: Tue Feb 08, 2022 9:38 am
by BarryG
You didn't answer my question. I think my code just above is what you want to do, right?

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

Posted: Tue Feb 08, 2022 1:12 pm
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