ListIconGadget event for scrollbar change?

Just starting out? Need help? Post your questions and find answers here.
novablue
Enthusiast
Enthusiast
Posts: 165
Joined: Sun Nov 27, 2016 6:38 am

ListIconGadget event for scrollbar change?

Post by novablue »

Hi, Now i am looking for a way to get an event whenever the scrollbar of an Listicon changes position. Right now i am doing it with Timers but i would like it to be triggered by an event only when an actual change occurs.

Here is how i am doing it for now:

Code: Select all

EnableExplicit

Define MainWindow.i = OpenWindow(#PB_Any, 0, 0, 500, 485, "MainWindow", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
Define Listicon.i   = ListIconGadget(#PB_Any, 0, 0, 500, 485, "Test", 460)
Define I.i, WindowEvent.i, FirstVisibleLine.i, VisibleLinesCount.i, FirstVisibleLineBefore.i = -1

For I = 0 To 1000 
	AddGadgetItem(Listicon, -1, "Test " + I)
Next

AddWindowTimer(MainWindow, 123, 100)

Repeat 
	WindowEvent = WaitWindowEvent()
	
	Select (WindowEvent) 
		Case #PB_Event_CloseWindow 
			End
		Case #PB_Event_Timer 
			Select EventTimer() 
				Case 123 
					FirstVisibleLine  = SendMessage_(GadgetID(Listicon), #LVM_GETTOPINDEX, 0, 0)
					VisibleLinesCount = SendMessage_(GadgetID(Listicon), #LVM_GETCOUNTPERPAGE, 0, 0) - 1
					
					If (FirstVisibleLine <> FirstVisibleLineBefore) 
					    FirstVisibleLineBefore = FirstVisibleLine
					    Debug "Visible Lines: " + Str(FirstVisibleLine) + " To " + Str(FirstVisibleLine + VisibleLinesCount)
					EndIf
			EndSelect
	EndSelect
ForEver
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: ListIconGadget event for scrollbar change?

Post by BarryG »

For Windows only, you can do it like below (thanks to Netmaestro for the original code at viewtopic.php?p=573040#p573040).

But the visible lines in the Debug Output are off; you'll have to work that bit out yourself. Sorry!

Code: Select all

Define MainWindow.i = OpenWindow(#PB_Any, 0, 0, 500, 485, "MainWindow", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
Define Listicon.i = ListIconGadget(#PB_Any, 0, 0, 500, 485, "Test", 460)
Global Listicon_hWnd = GadgetID(Listicon) ; Needed in ListiconProc().

Define I.i, WindowEvent.i, FirstVisibleLine.i, VisibleLinesCount.i, FirstVisibleLineBefore.i = -1

Procedure ListiconProc(hWnd, Msg, wParam, lParam)
  oldproc = GetProp_(hWnd, "oldproc")
  Select Msg
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, "oldproc")
    Case #WM_VSCROLL
      FirstVisibleLine  = SendMessage_(Listicon_hWnd, #LVM_GETTOPINDEX, 0, 0)
      VisibleLinesCount = SendMessage_(Listicon_hWnd, #LVM_GETCOUNTPERPAGE, 0, 0) - 1
      If (FirstVisibleLine <> FirstVisibleLineBefore) 
        FirstVisibleLineBefore = FirstVisibleLine
        Debug "Visible Lines: " + Str(FirstVisibleLine) + " To " + Str(FirstVisibleLine + VisibleLinesCount)
      EndIf
  EndSelect
  ProcedureReturn CallWindowProc_(oldproc, hWnd, Msg, wParam, lParam)
EndProcedure

For I = 0 To 1000 
  AddGadgetItem(Listicon, -1, "Test " + I)
Next

SetProp_(Listicon_hWnd, "oldproc", SetWindowLongPtr_(Listicon_hWnd, #GWL_WNDPROC, @ListiconProc()))

Repeat 
  WindowEvent = WaitWindowEvent()
  Select (WindowEvent) 
    Case #PB_Event_CloseWindow 
      End
  EndSelect
ForEver
novablue
Enthusiast
Enthusiast
Posts: 165
Joined: Sun Nov 27, 2016 6:38 am

Re: ListIconGadget event for scrollbar change?

Post by novablue »

BarryG wrote: Mon Sep 13, 2021 3:12 am For Windows only, you can do it like below (thanks to Netmaestro for the original code at viewtopic.php?p=573040#p573040).

But the visible lines in the Debug Output are off; you'll have to work that bit out yourself. Sorry!

Code: Select all

Define MainWindow.i = OpenWindow(#PB_Any, 0, 0, 500, 485, "MainWindow", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
Define Listicon.i = ListIconGadget(#PB_Any, 0, 0, 500, 485, "Test", 460)
Global Listicon_hWnd = GadgetID(Listicon) ; Needed in ListiconProc().

Define I.i, WindowEvent.i, FirstVisibleLine.i, VisibleLinesCount.i, FirstVisibleLineBefore.i = -1

Procedure ListiconProc(hWnd, Msg, wParam, lParam)
  oldproc = GetProp_(hWnd, "oldproc")
  Select Msg
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, "oldproc")
    Case #WM_VSCROLL
      FirstVisibleLine  = SendMessage_(Listicon_hWnd, #LVM_GETTOPINDEX, 0, 0)
      VisibleLinesCount = SendMessage_(Listicon_hWnd, #LVM_GETCOUNTPERPAGE, 0, 0) - 1
      If (FirstVisibleLine <> FirstVisibleLineBefore) 
        FirstVisibleLineBefore = FirstVisibleLine
        Debug "Visible Lines: " + Str(FirstVisibleLine) + " To " + Str(FirstVisibleLine + VisibleLinesCount)
      EndIf
  EndSelect
  ProcedureReturn CallWindowProc_(oldproc, hWnd, Msg, wParam, lParam)
EndProcedure

For I = 0 To 1000 
  AddGadgetItem(Listicon, -1, "Test " + I)
Next

SetProp_(Listicon_hWnd, "oldproc", SetWindowLongPtr_(Listicon_hWnd, #GWL_WNDPROC, @ListiconProc()))

Repeat 
  WindowEvent = WaitWindowEvent()
  Select (WindowEvent) 
    Case #PB_Event_CloseWindow 
      End
  EndSelect
ForEver
Thanks, the lines are not off for me. This won't react to any keyboard input or mouse wheel though. I know i can read those separately but it seem odd that there is no event that just simply catches any change?
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: ListIconGadget event for scrollbar change?

Post by BarryG »

novablue wrote: Mon Sep 13, 2021 3:39 amthe lines are not off for me
Very strange! They're definitely off for me. I'm using 32-bit PureBasic on 64-bit Windows, so maybe that's why.
novablue wrote: Mon Sep 13, 2021 3:39 amThis won't react to any keyboard input or mouse wheel
Easily fixed - just change the "Case #WM_VSCROLL" line to this:

Code: Select all

Case #WM_VSCROLL, #WM_MOUSEWHEEL, #WM_KEYDOWN
novablue wrote: Mon Sep 13, 2021 3:39 amit seem odd that there is no event that just simply catches any change?
I know, it's weird. Something for you to post in the "Requests" section?

Also, another version is here -> viewtopic.php?f=5&t=66753
novablue
Enthusiast
Enthusiast
Posts: 165
Joined: Sun Nov 27, 2016 6:38 am

Re: ListIconGadget event for scrollbar change?

Post by novablue »

Thanks, here is my solution for now, there must be a better way to avoid spamming of events when holding and dragging the scrollbar but it works. The visible lines output being wrong could be dpi setting related, at least that's my guess.

Code: Select all

EnableExplicit

Define MainWindow.i = OpenWindow(#PB_Any, 0, 0, 500, 485, "MainWindow", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
Define Listicon.i = ListIconGadget(#PB_Any, 0, 0, 500, 485, "Test", 460)
Define I.i, WindowEvent.i, FirstVisibleLine.i, VisibleLinesCount.i

#MSG_VSCROLL = #PB_Event_FirstCustomValue

Procedure.i ListiconProc(hWnd.i, Msg.i, wParam.i, lParam.i) 
    Define OldProc.i = GetProp_(hWnd, "oldproc")
    Define FirstVisibleLine.i
    
    Select (Msg) 
        Case #WM_NCDESTROY 
            RemoveProp_(hWnd, "oldproc")
        Case #WM_VSCROLL, #WM_MOUSEWHEEL, #WM_KEYUP 
            If (Not GetAsyncKeyState_(1) & $8000) 
                FirstVisibleLine = SendMessage_(hWnd, #LVM_GETTOPINDEX, 0, 0)
                If (FirstVisibleLine <> GetWindowLongPtr_(hWnd, #GWLP_USERDATA)) 
                    SetWindowLongPtr_(hWnd, #GWLP_USERDATA, FirstVisibleLine)
                    PostEvent(#MSG_VSCROLL, hWnd, hWnd, 0, wParam)
				EndIf
            EndIf
    EndSelect
    ProcedureReturn CallWindowProc_(OldProc, hWnd, Msg, wParam, lParam)
EndProcedure

For I = 0 To 1000 
    AddGadgetItem(Listicon, -1, "Test " + I)
Next

SetProp_(GadgetID(Listicon), "oldproc", SetWindowLongPtr_(GadgetID(Listicon), #GWL_WNDPROC, @ListiconProc()))

Repeat 
    WindowEvent = WaitWindowEvent()
    Select (WindowEvent)  
        Case #PB_Event_CloseWindow  
            End
        Case #MSG_VSCROLL 
            FirstVisibleLine  = SendMessage_(EventGadget(), #LVM_GETTOPINDEX, 0, 0)
            VisibleLinesCount = SendMessage_(EventGadget(), #LVM_GETCOUNTPERPAGE, 0, 0) - 1
            Debug "Visible Lines: " + Str(FirstVisibleLine) + " To " + Str(FirstVisibleLine + VisibleLinesCount)
    EndSelect
ForEver
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: ListIconGadget event for scrollbar change?

Post by BarryG »

The visible lines in your new example above are correct for me now.
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1243
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Re: ListIconGadget event for scrollbar change?

Post by Paul »

BarryG wrote: Mon Sep 13, 2021 7:38 am The visible lines in your new example above are correct for me now.
Maybe you had "DPI Aware" enabled when you compiled? If I have this flag set then the lines are off like you mentioned.
Image Image
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ListIconGadget event for scrollbar change?

Post by netmaestro »

Code: Select all

EnableExplicit

Define I.i, WindowEvent.i, Listicon.i

Procedure Report(hWnd)
  Protected I.i, FirstVisibleLine.i, VisibleLinesCount.i, FirstVisibleLineBefore.i = -1
  FirstVisibleLine  = SendMessage_(hWnd, #LVM_GETTOPINDEX, 0, 0)
  VisibleLinesCount = SendMessage_(hWnd, #LVM_GETCOUNTPERPAGE, 0, 0) - 1
  
  If (FirstVisibleLine <> FirstVisibleLineBefore) 
    FirstVisibleLineBefore = FirstVisibleLine
    Debug "Visible Lines: " + Str(FirstVisibleLine) + " To " + Str(FirstVisibleLine + VisibleLinesCount)
  EndIf
EndProcedure

Procedure ListProc(hWnd, Msg, wParam, lParam)
  Protected oldproc.i
  oldproc = GetProp_(hWnd, "oldproc")
  Select Msg
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, "oldproc")
      
    Case #WM_VSCROLL
      CallWindowProc_(oldproc, hWnd, Msg, wParam, lParam)
      Report(hWnd)
      ProcedureReturn 0
      
    Case #WM_KEYDOWN
      If wParam = #VK_DOWN Or wParam = #VK_UP
        CallWindowProc_(oldproc, hWnd, Msg, wParam, lParam)
        Report(hWnd)
      EndIf
      ProcedureReturn 0
      
  EndSelect
  
  ProcedureReturn CallWindowProc_(oldproc, hWnd, Msg, wParam, lParam)
EndProcedure


Define MainWindow.i = OpenWindow(#PB_Any, 0, 0, 500, 485, "MainWindow", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
Listicon.i   = ListIconGadget(#PB_Any, 0, 0, 500, 485, "Test", 460)
SetProp_(GadgetID(listicon), "oldproc", SetWindowLongPtr_(GadgetID(listicon),#GWLP_WNDPROC,@ListProc()))

For I = 0 To 1000 
  AddGadgetItem(Listicon, -1, "Test " + I)
Next

Repeat 
  WindowEvent = WaitWindowEvent()
  
  Select (WindowEvent) 
    Case #PB_Event_CloseWindow 
      End
  EndSelect
ForEver
BERESHEIT
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: ListIconGadget event for scrollbar change?

Post by BarryG »

Paul wrote: Mon Sep 13, 2021 7:45 pmMaybe you had "DPI Aware" enabled when you compiled?
No. I just copy and paste the code in this forum into a blank default PureBasic IDE, and DPI is never enabled. Besides, the visible line count was only out when I use the callback procedure, which has nothing to do with DPI. I'm talking about the Debug Output results, not the app itself.
Post Reply