Right-click on a ComboBoxGadget
- 
				RobertRioja
 - 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).
- 
				RobertRioja
 - 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?
			
			
									
									
						- 
				RobertRioja
 - 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
- 
				RobertRioja
 - 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).
- 
				RobertRioja
 - 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
- 
				Randy Walker
 - Addict

 - Posts: 1129
 - 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.
