Page 1 of 1
Disabling & hiding Listbox/Listview vertical scrollbar
Posted: Mon Mar 05, 2007 5:52 pm
by Fluid Byte
As I can't be arsed to write a complete custom list control myself I decided to only make the scrollbars ownerdraw and let Windows handle the item management. AFAIK there's no easy, standard way to acomplish ownerdraw scrollbars anyway (e.g. like #SBS_OWNERDRAW) so I can live with that.
Well, in order for that to work I need to disable and hide the scrollbars. A listbox doesn't seem to have proper style for this and using #LVS_NOSCROLL for a listview completely disables scrolling. So sending #LVM_SCROLL or #WM_VSCROLL explicitly won't work.
Now what to do? Maybe clip the control using a custom region?
Posted: Mon Mar 05, 2007 7:22 pm
by r_hyde
This seems to work
Code: Select all
Procedure HideScrollBars(gadget.l, which.b=#SB_BOTH)
Protected ierect.RECT, cxvs.l, cyvs.l, iehrgn.l
GetClientRect_(GadgetID(gadget), ierect)
cxvs = GetSystemMetrics_(#SM_CXVSCROLL)
cyvs = GetSystemMetrics_(#SM_CYVSCROLL)
If which = #SB_HORZ : cxvs = 0 : EndIf
If which = #SB_VERT : cyvs = 0 : EndIf
SetWindowPos_(GadgetID(gadget), #Null, ierect\left-2, ierect\top-2, ierect\right+cxvs+6, ierect\bottom+cyvs, SWP_NOMOVE | SWP_NOZORDER)
If which = #SB_BOTH Or which = #SB_HORZ : ierect\bottom - ierect\top : EndIf
If which = #SB_BOTH Or which = #SB_VERT : ierect\right - ierect\left : EndIf
ierect\top = 0
ierect\left = 0
Select which
Case #SB_BOTH : iehrgn = CreateRectRgn_(ierect\left, ierect\top, ierect\right-2, ierect\bottom-2)
Case #SB_HORZ : iehrgn = CreateRectRgn_(ierect\left, ierect\top, ierect\right, ierect\bottom-2)
Case #SB_VERT : iehrgn = CreateRectRgn_(ierect\left, ierect\top, ierect\right-2, ierect\bottom)
EndSelect
SetWindowRgn_(GadgetID(gadget), iehrgn, #True)
EndProcedure
win = OpenWindow(#PB_Any, 100, 100, 200, 300, "")
CreateGadgetList(WindowID(win))
lv = ListViewGadget(#PB_Any, 0, 0, 200, 300)
HideScrollBars(lv)
For i = 1 To 100
item$ = "List Item " + RSet(Str(i), 3, "0")
AddGadgetItem(lv, -1, item$)
Next
Repeat
ev = WindowEvent()
Until ev = #PB_Event_CloseWindow
Note that some of the constant values I'm adding and subtracting in the hide function are probably dependent on certain system metrics, so it may not look quite the same on every system. It's probably possible to probe the right metrics, but I didn't dig that far into it.
Posted: Mon Mar 05, 2007 9:03 pm
by Fluid Byte
r_hyde wrote:Note that some of the constant values I'm adding and subtracting in the hide function are probably dependent on certain system metrics, so it may not look quite the same on every system. It's probably possible to probe the right metrics, but I didn't dig that far into it.
I guess you mean the 2 pixel border around the listbox control. This is because of the #WS_EX_CLIENTEDGE style wich can be removed with SetWindowLong_(). Apart from that I don't see anything wich should cause different visual results on other machines.
So you just need to retrieve the width of the horz/vert scrollbar and subtract that from the region wich is initially the size of the window.
Hmm, yeah. That should do it. Thanks!

Posted: Mon Mar 05, 2007 9:47 pm
by netmaestro
This issue has come up a few times in the past and iirc the shortest/best solution was generally agreed to be placing the listicon inside a container gadget that is sized too small for it widthwise to hide the vertical scroll, heightwise to hide the horizontal. Requires one extra line of code to implement and virtually no effort.
Posted: Mon Mar 05, 2007 10:04 pm
by Fluid Byte
Heh, using an extra window for clipping. Why I didn't think of that?
Well. thanks for the tip maestro.
Now while we at it, do you know how to set a fixed image in a listicon gadget?
Just getting desprate cause I tried almost everything but I have severe display problems. I tried sublcassing the listicon gadget and drawing the background in respond to #WM_ERASEBAKGND and #WM_VSCROLL. I have set the image using the #LVM_SETBKIMAGE but the background scrolls with the content up and down. I also had no success with drawing it while processing #WM_DRAWITEM as the clipping gets screwed.
Any ideas?
Posted: Mon Mar 05, 2007 10:14 pm
by netmaestro
This one should be perfect for your needs as described:
http://www.purebasic.fr/english/viewtop ... 49&start=2
Posted: Tue Mar 06, 2007 11:56 am
by Fluid Byte
I was disapointed at first because of a little bug in the code. I accidently pressed the left mousebutton in the listbox and moving it down. After I scrolled I saw all of sudden that like 10 items had this focus rect drawn around them. Well, it's normal since I later saw the #PB_ListView_Multiselect flag. The listbox just doesn't refresh propely when you select multiple items with mousedragging but I'm gonna fix that myself.
Although this is exactly what I was looking for, the code needs some heavy cleanup.
Thanks again netmaestro!

Posted: Tue Mar 06, 2007 12:16 pm
by netmaestro
Good stuff, Fluid! If you make improvements to the code, please post your version to the linked thread, that way the next guy passing through doesn't have to do it all over again.
Posted: Tue Mar 06, 2007 12:34 pm
by Fluid Byte
Sure thing!
By the way, if you resize the gadget in realtime the background gets completely screwed up so I'm gonna try to fix that to.
Laters!