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