Page 1 of 1

ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 6:22 am
by Blue
OS : Windows 11 X64
PB : 6.21 beta 7
----------------------------------------

I'm using a ListView Gadget to display data.
And I just can't figure out how to determine the line number on which the user RIGHT-clicks.
Getting this information after a left-click is simple enough.
Any idea, anyone ?


Code: Select all

  ; Blue April 2025 - code snippet courtesy of PB Help file, modified
  EnableExplicit
  If 0 = OpenWindow(0, 0, 0, 270, 140, "ListViewGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    End
  EndIf
  
  ; PROBLEM : determining the line number on which the user RIGHT-clicks in a ListView gadget

  #dataList = 11
  ListViewGadget(#dataList, 10, 10, 250, 120)
  Define i, p = Len("0: value captured ")
  For i = 1 To 12
    AddGadgetItem (#dataList, -1, Str(i-1) + ": value captured " + Random(1200,1)); listview content
  Next
  SetGadgetState(#dataList, 0)   ; start with first entry

  Define event
  Repeat
    event = WaitWindowEvent()
    Select event
      Case #PB_Event_CloseWindow : Break
      Case #PB_Event_Gadget
        Select EventType()
          Case #PB_EventType_LeftClick
            i = GetGadgetState(#dataList)
            Debug "click on " + i + ": ["+ Mid(GetGadgetItemText(#dataList, i),p+1)+"]"
          Case #PB_EventType_RightClick
            SetGadgetState(#dataList, -1)  ; unselect the currently selected entry
            ; How do I assign to the variable the line number that was right-clicked ?
            i = GetGadgetState(#dataList)  ; this correctly tells me nothing is selected    <<<   HELP needed here
            Debug "Right-click on " + i + ": ["+ Mid(GetGadgetItemText(#dataList, i),p+1)+"]"
        EndSelect
    EndSelect
  ForEver
Thank you for taking the time...

Re: ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 8:37 am
by Marc56us
Hi,
And I just can't figure out how to determine the line number on which the user RIGHT-clicks.
You can't do that with Listview (as far as I know)
Use ListIconGadget() instead.

Code: Select all

; Blue April 2025 - code snippet courtesy of PB Help file, modified
EnableExplicit
If 0 = OpenWindow(0, 0, 0, 270, 140, "ListViewGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    End
EndIf

; PROBLEM : determining the line number on which the user RIGHT-clicks in a ListView gadget

#dataList = 11
; ListViewGadget(#dataList, 10, 10, 250, 120, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect))
ListIconGadget(#dataList, 10, 10, 250, 120, "", 225)
Define i, p = Len("0: value captured ")

For i = 1 To 12
    AddGadgetItem (#dataList, -1, Str(i-1) + ": value captured " + Random(1200,1)); listview content
Next
SetGadgetState(#dataList, 0)   ; start with first entry


Repeat
    Select WaitWindowEvent()      
        Case #PB_Event_CloseWindow : Break
            
        Case #PB_Event_Gadget
            Select EventGadget()  
                Case #dataList        
                    Select EventType()
                            
                        Case #PB_EventType_LeftClick
                            Debug "Left     " + GetGadgetItemText(#dataList, GetGadgetState(#dataList))
                            
                        Case #PB_EventType_RightClick    
                            Debug "Right    " + GetGadgetItemText(#dataList, GetGadgetState(#dataList))
  
                    EndSelect        
            EndSelect
    EndSelect
ForEver
Add #PB_EventType_Change if you need to use arrow up/down to select too.
:wink:

Re: ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 8:46 am
by RASHAD
Very simple for Windows

Code: Select all

  ; Blue April 2025 - code snippet courtesy of PB Help file, modified
  EnableExplicit
  If 0 = OpenWindow(0, 0, 0, 270, 140, "ListViewGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    End
  EndIf
  
  ; PROBLEM : determining the line number on which the user RIGHT-clicks in a ListView gadget

  #dataList = 11
  ListViewGadget(#dataList, 10, 10, 250, 120)
  Define i, p = Len("0: value captured ")
  For i = 1 To 12
    AddGadgetItem (#dataList, -1, Str(i-1) + ": value captured " + Random(1200,1)); listview content
  Next
  SetGadgetState(#dataList, 0)   ; start with first entry

  Define event
  Repeat
    event = WaitWindowEvent()
    Select event
      Case #PB_Event_CloseWindow : Break
      Case #PB_Event_Gadget
        Select EventType()
          Case #PB_EventType_LeftClick
            i = GetGadgetState(#dataList)
            Debug "click on " + i + ": ["+ Mid(GetGadgetItemText(#dataList, i),p+1)+"]"
          Case #PB_EventType_RightClick
            mouse_event_(#MOUSEEVENTF_LEFTDOWN,0,0,0,0)
            mouse_event_(#MOUSEEVENTF_LEFTUP,0,0,0,0)
        EndSelect
    EndSelect
  ForEver


Re: ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 9:27 am
by Marc56us

Code: Select all

mouse_event_(#MOUSEEVENTF_...
Thank you!
I'm putting this in my notes, it will come in handy for other projects.
:wink:

Re: ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 11:33 am
by mk-soft
MSDN Win32 ListBox -> LBItemFromPt
Link: https://learn.microsoft.com/en-us/windo ... list-boxes

Code: Select all

  ; Blue April 2025 - code snippet courtesy of PB Help file, modified
  EnableExplicit
  If 0 = OpenWindow(0, 0, 0, 270, 140, "ListViewGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    End
  EndIf
  
  ; PROBLEM : determining the line number on which the user RIGHT-clicks in a ListView gadget

  #dataList = 11
  ListViewGadget(#dataList, 10, 10, 250, 120)
  Define i, p = Len("0: value captured ")
  For i = 1 To 12
    AddGadgetItem (#dataList, -1, Str(i-1) + ": value captured " + Random(1200,1)); listview content
  Next
  SetGadgetState(#dataList, 0)   ; start with first entry

  Define event, point.q, item
  Repeat
    event = WaitWindowEvent()
    Select event
      Case #PB_Event_CloseWindow : Break
      Case #PB_Event_Gadget
        Select EventType()
          Case #PB_EventType_LeftClick
            i = GetGadgetState(#dataList)
            Debug "click on " + i + ": ["+ Mid(GetGadgetItemText(#dataList, i),p+1)+"]"
          Case #PB_EventType_RightClick
            GetCursorPos_(@point)
            i = LBItemFromPt_(GadgetID(#dataList), point, #False)
            If i >= 0
              SetGadgetState(#dataList, -1)  ; unselect the currently selected entry
              ; How do I assign to the variable the line number that was right-clicked ?
              Debug "Right-click on " + i + ": ["+ Mid(GetGadgetItemText(#dataList, i),p+1)+"]"
            EndIf
            
        EndSelect
    EndSelect
  ForEver

Even if I still don't do much with Windows ...
There is still the API Reference from MSDN. So you can also look up the available functions there.
You just need to know which gadget is which control

ListViewGadget -> ListBox
ListIconGadget -> ListView

Re: ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 4:19 pm
by skywalk
I prefer mk-soft's api code since the mouse events create a rat race for selection query.
Even better, use the ListIconGadget() if you require more native PB event coverage.

Re: ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 5:27 pm
by Blue
Marc56us wrote: Fri May 02, 2025 8:37 am […]
Add #PB_EventType_Change if you need to use arrow up/down to select too.
:wink:
Thank you Marc56us for the simplest and (now, to me) most obvious solution.
That’s the one I’ll retain … and try to remember. :thumbsup:

Many thanks as well to all who took the time to help out.
You keep me learning steadily. Much appreciated.

Note to mk-soft : reasonable suggestion (consulting the MSDN API listings)…
Your use of API code here is very clean and follows a logical line that makes it easy to understand.
But most of the time, I just can’t get my head around the code suggested at MSDN. :cry:
and I therefore find myself unable to translate it into PB's clean near-English speak.
Knowing which PB gadget is which MS control is a solid starting point. Thanks for that.

Note to Rashad : Brilliant solution. :shock: And surprisingly simple.
I'm diving into MSDN to figure out how you pulled that magic API trick.

Re: ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 6:12 pm
by RASHAD
Hi Blue
Subclassing ListViewGadget() is the pro solution
BTW : If you want to use Marc56us as a native solution you can code the ListIcon inside a ContainerGadget() with negative ListIcon y to eliminate the header :)

Code: Select all

#LB_ITEMFROMPOINT = $1A9
Global ListCB

Procedure ListCB(hWnd, uMsg, wParam, lParam)
  Select uMsg        
    Case #WM_RBUTTONDOWN    
        GetCursorPos_(p.POINT)
        ScreenToClient_ (hWnd, @p)
        item = SendMessage_(hWnd,#LB_ITEMFROMPOINT,0,p\y<<16+p\x)        
        Debug item+1
        SetGadgetState(1,item) 
  EndSelect
  
  ProcedureReturn CallWindowProc_(ListCB, hWnd, uMsg, wParam, lParam)
EndProcedure

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListViewGadget(1, 0, 0, WindowWidth(0), WindowHeight(0), 0)
 
  For a=1 To 50
    AddGadgetItem(1, -1, "Item " + Str(a), 0, 0)
  Next
  
  ListCB = SetWindowLongPtr_(GadgetID(1), #GWL_WNDPROC, @ListCB())
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf

Re: ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 8:48 pm
by Blue
RASHAD wrote: Fri May 02, 2025 6:12 pm Hi Blue
Subclassing ListViewGadget() is the pro solution
BTW : If you want to use Marc56us as a native solution you can code the ListIcon inside a ContainerGadget() with negative ListIcon y to eliminate the header :)
[...]
Greetings RASHAD !
You had me at "subclassling", but after trying out and studying closely your proposed solution, I finally understood.
Beautiful code, and rather simple once you overcome the hurdle of the nebulous API concepts. As you say, real pro.
But I ain't anywhere close to honestly appending that word to my work.

Thanks for a priceless learning experience.
As for your suggestion on how to get rid of the header, it's spot on :thumbsup: : that's exactly what had me scratching my head in vain.
Besides being a code magician, you can also read minds ? Amazing... :shock:

Re: ListView : how to identify line that is RIGHT-clicked ?

Posted: Fri May 02, 2025 9:08 pm
by Blue
mk-soft wrote: Fri May 02, 2025 11:33 am [...]
You just need to know which gadget is which control

ListViewGadget -> ListBox
ListIconGadget -> ListView
too bad PB didn't simply follow this naming scheme for its related gadgets.