Page 1 of 1
Right-click on a ComboBoxGadget
Posted: Sun Sep 14, 2025 10:27 pm
by RobertRioja
I hope someone can answer this. If I click on a ComboBoxGadget, its list will drop down so I can click on any item. That will trigger the #PB_EventType_Change event. However, I need to right-click on an item and I don't see a way of capturing that event.
Any ideas?
Thanks,
Rob
Re: Right-click on a ComboBoxGadget
Posted: Mon Sep 15, 2025 1:45 pm
by Axolotl
Which OS?
On windows maybe by doing the following:
1. Get the ListBox handle (GetComboBoxInfo),
2. subclass it (SetWindowSubclass)
3. look at WM_RBUTTONDOWN and LB_ITEMFROMPOINT
Re: Right-click on a ComboBoxGadget
Posted: Mon Sep 15, 2025 2:32 pm
by Axolotl
Here is an example of right-click on the dropdown-listbox ..... (Windows Only)
Code: Select all
EnableExplicit
Import "Comctl32.lib" ;{ <<< from (latest) Comctl32.dll >>>
; use the PureBasic Syntax (Windows API procedures using trailing underscore)
;
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData) As "SetWindowSubclass"
GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "GetWindowSubclass"
RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass) As "RemoveWindowSubclass"
DefSubclassProc_(hWnd, uMsg, wParam, lParam) As "DefSubclassProc"
CompilerElse
SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData) As "_SetWindowSubclass@16"
GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "_GetWindowSubclass@16"
RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass) As "_RemoveWindowSubclass@12"
DefSubclassProc_(hWnd, uMsg, wParam, lParam) As "_DefSubclassProc@16"
CompilerEndIf
EndImport
; for simplicity's sake, constants (enums are even better)
#WND_Main = 1
#GDT_cbbTest = 2
Structure COMBOBOXINFO
cbSize.l ; DWORD
rcItem.RECT ; RECT
rcButton.RECT ; RECT
stateButton.l ; DWORD
hwndCombo.i ; HWND
hwndItem.i ; HWND
hwndList.i ; HWND
EndStructure
#LB_ITEMFROMPOINT = 425
Procedure SubclassComboboxList(hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData)
Protected index, pt.POINT
Select uMsg
Case #WM_NCDESTROY : Debug "WM_NCDESTROY"
RemoveWindowSubclass_(hWnd, @SubclassComboboxList(), uIdSubclass)
Case #WM_LBUTTONDOWN : Debug "WM_LBUTTONDOWN"
Case #WM_RBUTTONDOWN : Debug "WM_RBUTTONDOWN"
GetCursorPos_(@pt)
ScreenToClient_(hWnd, @pt)
index = ((pt\y & $FFFF) << 16) + (pt\x + $FFFF)
index = SendMessage_(hWnd, #LB_ITEMFROMPOINT, 0, index)
If (index >> 16) & $FFFF ; inside the listbox
index & $FFFF : Debug " index == " + index + " outside "
Else
index & $FFFF : Debug " index == " + index + " inside "
EndIf
EndSelect
ProcedureReturn DefSubclassProc_(hWnd, uMsg, wParam, lParam)
EndProcedure
Procedure Main()
Protected ii, hList, cbi.COMBOBOXINFO
If OpenWindow(#WND_Main, 0, 0, 256, 200, "Something with Combobox ... ", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
StickyWindow(#WND_Main, 1) ; always on top :)
ComboBoxGadget(#GDT_cbbTest, 8, 8, 240, 24)
For ii = 1 To 9
AddGadgetItem(#GDT_cbbTest, -1, "Test Text Item "+ii)
Next
SetGadgetState(#GDT_cbbTest, 1)
cbi\cbSize = SizeOf(COMBOBOXINFO)
If GetComboBoxInfo_(GadgetID(#GDT_cbbTest), @cbi)
hList = cbi\hwndList : Debug "Combobox List hwnd == " + hList
SetWindowSubclass_(hList, @SubclassComboboxList(), #GDT_cbbTest, 0) ;
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break ; say good bye.
EndSelect
ForEver
EndIf
EndProcedure
End Main()
Re: Right-click on a ComboBoxGadget
Posted: Mon Sep 15, 2025 11:42 pm
by RobertRioja
Hello Axolotl,
Thank you very much. This is exactly what I needed.
Rob
Re: Right-click on a ComboBoxGadget
Posted: Tue Sep 16, 2025 3:05 am
by BarryG
Code: Select all
If OpenWindow(0, 0, 0, 270, 80, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBoxGadget(0, 10, 10, 250, 21)
For a = 1 To 5
AddGadgetItem(0, -1,"ComboBox item " + Str(a))
Next
Repeat
ev=WaitWindowEvent()
If ev=#WM_RBUTTONDOWN
Debug "Right-clicked on "+Str(GetGadgetState(0))
EndIf
Until ev = #PB_Event_CloseWindow
EndIf
Re: Right-click on a ComboBoxGadget
Posted: Tue Sep 16, 2025 2:00 pm
by Axolotl
Works well, with one limitation: If the mouse is outside the list box when clicked, it is not recognized.
Re: Right-click on a ComboBoxGadget
Posted: Wed Sep 17, 2025 8:31 am
by BarryG
How is that a limitation? The request is for when the gadget is right-clicked, so if the gadget is not in focus, then no big deal?
Re: Right-click on a ComboBoxGadget
Posted: Wed Sep 17, 2025 8:05 pm
by RobertRioja
The real problem is that right-clicking anywhere will trigger the event. I need it to trigger ONLY when an item in the ComboBoxGadget is right-clicked.
Rob
Re: Right-click on a ComboBoxGadget
Posted: Thu Sep 18, 2025 12:57 am
by mk-soft
Code: Select all
;-TOP by mk-soft
Procedure IsCursorOnGadget(Gadget)
Protected r1, hWnd, cursor.q, rect.RECT
hWnd = GadgetID(Gadget)
GetCursorPos_(@cursor)
GetClientRect_(hWnd, @rect)
ClientToScreen_(hWnd, @rect)
rect\right + rect\left
rect\bottom + rect\top
r1 = PtInRect_(@rect, cursor)
ProcedureReturn r1
EndProcedure
If OpenWindow(0, 0, 0, 270, 80, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBoxGadget(0, 10, 10, 250, 21)
For a = 1 To 5
AddGadgetItem(0, -1,"ComboBox item " + Str(a))
Next
Repeat
ev=WaitWindowEvent()
If ev=#WM_RBUTTONDOWN
If IsCursorOnGadget(0)
Debug "Right-clicked on "+Str(GetGadgetState(0))
EndIf
EndIf
Until ev = #PB_Event_CloseWindow
EndIf
Re: Right-click on a ComboBoxGadget
Posted: Thu Sep 18, 2025 2:03 am
by RobertRioja
The problem with the last reply, is that it only works if you right-click on the gadget itself. I need to be able to right-click on an ITEM that is pulled down from the ComboBoxGadget. The IsCursorOnGadget function only looks at the boundaries of the gadget, not the pull down list.
Rob
Re: Right-click on a ComboBoxGadget
Posted: Thu Sep 18, 2025 2:34 am
by BarryG
My code does let you right-click on an item from the drop-down list? It even shows which item number was right-clicked.
Re: Right-click on a ComboBoxGadget
Posted: Thu Sep 18, 2025 3:27 pm
by Axolotl
okay, new try based on my code from above.
Now, after open the Dropdownlist with LeftClick you can use either Left or Right Mouse Click to do the selection.
Easier to show than to describe.
Anyway the result is in the main loop. (I borrowed the #PB_Eventtype_RightClick for that)
Please bear in mind it's a concept only.
Code: Select all
EnableExplicit
Import "Comctl32.lib" ;{ <<< from (latest) Comctl32.dll >>>
; use the PureBasic Syntax (Windows API procedures using trailing underscore)
;
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData) As "SetWindowSubclass"
GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "GetWindowSubclass"
RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass) As "RemoveWindowSubclass"
DefSubclassProc_(hWnd, uMsg, wParam, lParam) As "DefSubclassProc"
CompilerElse
SetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, dwRefData) As "_SetWindowSubclass@16"
GetWindowSubclass_(hWnd, *fnSubclass, uIdSubclass, *dwRefData) As "_GetWindowSubclass@16"
RemoveWindowSubclass_(hWnd, *fnSubclass, uIdSubclass) As "_RemoveWindowSubclass@12"
DefSubclassProc_(hWnd, uMsg, wParam, lParam) As "_DefSubclassProc@16"
CompilerEndIf
EndImport
; for simplicity's sake, constants (enums are even better)
#WND_Main = 1
#GDT_cbbTest = 2
Structure COMBOBOXINFO
cbSize.l ; DWORD
rcItem.RECT ; RECT
rcButton.RECT ; RECT
stateButton.l ; DWORD
hwndCombo.i ; HWND
hwndItem.i ; HWND
hwndList.i ; HWND
EndStructure
#LB_ITEMFROMPOINT = 425
Procedure SubclassComboboxList(hWnd, uMsg, wParam, lParam, uIdSubclass, dwRefData)
Protected index, pt.POINT
Select uMsg
Case #WM_NCDESTROY : Debug "WM_NCDESTROY"
RemoveWindowSubclass_(hWnd, @SubclassComboboxList(), uIdSubclass)
; Case #WM_LBUTTONDOWN : Debug "WM_LBUTTONDOWN"
Case #WM_RBUTTONDOWN ;: Debug "WM_RBUTTONDOWN"
GetCursorPos_(@pt)
ScreenToClient_(hWnd, @pt)
index = ((pt\y & $FFFF) << 16) + (pt\x + $FFFF)
index = SendMessage_(hWnd, #LB_ITEMFROMPOINT, 0, index)
If (index >> 16) & $FFFF ; inside the listbox or out
; index & $FFFF : Debug " index == " + index + " outside "
ProcedureReturn 0
Else
index & $FFFF : Debug "WM_RBUTTONDOWN -> index == " + index + " inside "
SetGadgetText(uIdSubclass, GetGadgetItemText(uIdSubclass, index)) ; <= set selected text
SendMessage_(GadgetID(uIdSubclass), #CB_SHOWDROPDOWN, #False, 0) ; <= close the drop down
PostEvent(#PB_Event_Gadget, #WND_Main, uIdSubclass, #PB_EventType_RightClick, index) ; <= send a PB_ Style Event, Index as Data not needed.
EndIf
EndSelect
ProcedureReturn DefSubclassProc_(hWnd, uMsg, wParam, lParam)
EndProcedure
Procedure Main()
Protected ii, d, state, hList, cbi.COMBOBOXINFO
If OpenWindow(#WND_Main, 0, 0, 456, 200, "Something with Combobox ... ", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
StickyWindow(#WND_Main, 1) ; always on top :)
ComboBoxGadget(#GDT_cbbTest, 8, 8, 240, 24)
For ii = 0 To 9
AddGadgetItem(#GDT_cbbTest, -1, "Test Text Item "+ii)
Next
SetGadgetState(#GDT_cbbTest, 1)
cbi\cbSize = SizeOf(COMBOBOXINFO)
If GetComboBoxInfo_(GadgetID(#GDT_cbbTest), @cbi)
hList = cbi\hwndList : Debug "MAIN: Combobox List hwnd == " + hList
SetWindowSubclass_(hList, @SubclassComboboxList(), #GDT_cbbTest, 0) ;
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break ; say good bye.
Case #PB_Event_Gadget
Select EventGadget()
Case #GDT_cbbTest
Select EventType()
Case #PB_EventType_Change
state = GetGadgetState(#GDT_cbbTest)
Debug "MAIN: EventType_Change " + state
Case #PB_EventType_RightClick ; NEW .. NOT supported by PB as default
state = GetGadgetState(#GDT_cbbTest)
d = EventData() ; <= not really needed, because the state is correct already.
Debug "MAIN: EventType_RightClick " + state + ", Data = " + d
EndSelect
EndSelect
EndSelect
ForEver
EndIf
EndProcedure
End Main()
Re: Right-click on a ComboBoxGadget
Posted: Sat Sep 20, 2025 12:06 am
by RobertRioja
To Axolotl: Your first code does exactly what I need. Your second code is "better" but more than what I need. Thank you.
To all else: Thank you for your efforts. But I now have what I needed.
Rob
Re: Right-click on a ComboBoxGadget
Posted: Sat Sep 20, 2025 4:01 am
by Randy Walker
Axolotl wrote: Mon Sep 15, 2025 2:32 pm
Here is an example of right-click on the dropdown-listbox ..... (Windows Only)
That is a really great code sample there Axolotl. Thanks for sharing!!!