Right-click on a ComboBoxGadget
-
- User
- Posts: 86
- Joined: Thu May 02, 2019 3:57 am
- Location: USA
- Contact:
Right-click on a ComboBoxGadget
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
Any ideas?
Thanks,
Rob
Re: Right-click on a ComboBoxGadget
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
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
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
Re: Right-click on a ComboBoxGadget
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()
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
-
- User
- Posts: 86
- Joined: Thu May 02, 2019 3:57 am
- Location: USA
- Contact:
Re: Right-click on a ComboBoxGadget
Hello Axolotl,
Thank you very much. This is exactly what I needed.
Rob
Thank you very much. This is exactly what I needed.
Rob
Re: Right-click on a ComboBoxGadget
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
Works well, with one limitation: If the mouse is outside the list box when clicked, it is not recognized.
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
Re: Right-click on a ComboBoxGadget
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?
-
- User
- Posts: 86
- Joined: Thu May 02, 2019 3:57 am
- Location: USA
- Contact:
Re: Right-click on a ComboBoxGadget
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
Rob
Re: Right-click on a ComboBoxGadget
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
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
-
- User
- Posts: 86
- Joined: Thu May 02, 2019 3:57 am
- Location: USA
- Contact:
Re: Right-click on a ComboBoxGadget
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
Rob
Re: Right-click on a ComboBoxGadget
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
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.
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()
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
-
- User
- Posts: 86
- Joined: Thu May 02, 2019 3:57 am
- Location: USA
- Contact:
Re: Right-click on a ComboBoxGadget
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
To all else: Thank you for your efforts. But I now have what I needed.
Rob
-
- Addict
- Posts: 1078
- Joined: Sun Jul 25, 2004 4:21 pm
- Location: USoA
Re: Right-click on a ComboBoxGadget
That is a really great code sample there Axolotl. Thanks for sharing!!!Axolotl wrote: Mon Sep 15, 2025 2:32 pm Here is an example of right-click on the dropdown-listbox ..... (Windows Only)
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
Randy
I *never* claimed to be a programmer.