Page 1 of 1
ListIconGadget event for scrollbar change?
Posted: Mon Sep 13, 2021 1:28 am
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
Re: ListIconGadget event for scrollbar change?
Posted: Mon Sep 13, 2021 3:12 am
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
Re: ListIconGadget event for scrollbar change?
Posted: Mon Sep 13, 2021 3:39 am
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?
Re: ListIconGadget event for scrollbar change?
Posted: Mon Sep 13, 2021 3:47 am
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
Re: ListIconGadget event for scrollbar change?
Posted: Mon Sep 13, 2021 4:33 am
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
Re: ListIconGadget event for scrollbar change?
Posted: Mon Sep 13, 2021 7:38 am
by BarryG
The visible lines in your new example above are correct for me now.
Re: ListIconGadget event for scrollbar change?
Posted: Mon Sep 13, 2021 7:45 pm
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.
Re: ListIconGadget event for scrollbar change?
Posted: Mon Sep 13, 2021 9:01 pm
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
Re: ListIconGadget event for scrollbar change?
Posted: Mon Sep 13, 2021 9:48 pm
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.