Disableing scrollbar in wxListCtrl

894 views
Skip to first unread message

Kovács Tamás

unread,
Apr 3, 2005, 2:04:10 PM4/3/05
to wxWidgets-User
Hi all!

Is there any way to disable the horizontal scrollbar in a wxListCtrl? I
didn't found any appropriate function or style in wxListCtrl nor
wxWindow. Maybe it wolud be enough to get a pointer to the scrollbar so
I could hide or delete it (but how to get this pointer?).


--
Kovacs Tamas, Hungary

Vadim Zeitlin

unread,
Apr 3, 2005, 2:04:55 PM4/3/05
to wxWidgets-User
On Sun, 03 Apr 2005 20:04:10 +0200 Kovács Tamás <kov...@blackpanther.hu> wrote:

KT> Is there any way to disable the horizontal scrollbar in a wxListCtrl?

Simply make it columns wide enough.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/


Gunnar Roth

unread,
Apr 3, 2005, 2:21:34 PM4/3/05
to wx-u...@lists.wxwidgets.org
Vadim Zeitlin schrieb:

>On Sun, 03 Apr 2005 20:04:10 +0200 Kovács Tamás <kov...@blackpanther.hu> wrote:
>
>KT> Is there any way to disable the horizontal scrollbar in a wxListCtrl?
>
> Simply make it columns wide enough.
>
> Regards,
>VZ
>
>

I adjust the cilumns in the EVT_SIZE Handler to the client width of the
listctrl window, so no scorll bar is shown.
But this only will partially work. On wxMAC and wxGTK it works But on
MSW whuile resizing the horizontal scroll bar appears flickering,
which looks terrible.
I solved it for MSW this way:

.h

#ifdef __WXMSW__
bool m_bHideHorzScrollbar;
bool m_bHideVertScrollbar;
protected:
long MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
#endif

.cpp

CMusikListCtrl::CMusikListCtrl( wxWindow *parent, const wxWindowID id,
const wxPoint& pos, const wxSize& size, long style)
: wxListCtrl ( parent, id, pos, size, wxLC_REPORT |
wxLC_VIRTUAL | wxCLIP_CHILDREN | style)
#ifdef __WXMSW__
,m_freezeCount(0)
,m_bHideHorzScrollbar(false)
,m_bHideVertScrollbar(false)
#endif
{
#ifdef __WXMSW__
#ifdef LVS_EX_LABELTIP
HWND hwnd = (HWND)GetHandle();

ListView_SetExtendedListViewStyleEx(hwnd,LVS_EX_LABELTIP,LVS_EX_LABELTIP);
#endif
#endif
}


#ifdef __WXMSW__
BOOL ModifyStyle(HWND hWnd,
DWORD dwRemove, DWORD dwAdd, UINT nFlags)
{
int nStyleOffset = GWL_STYLE;
DWORD dwStyle = ::GetWindowLong(hWnd, nStyleOffset);
DWORD dwNewStyle = (dwStyle & ~dwRemove) | dwAdd;
if (dwStyle == dwNewStyle)
return FALSE;

::SetWindowLong(hWnd, nStyleOffset, dwNewStyle);
return TRUE;

}

long CMusikListCtrl::MSWWindowProc(WXUINT message, WXWPARAM wParam,
WXLPARAM lParam)
{
if(message == WM_NCCALCSIZE)
{
if(m_bHideHorzScrollbar)
ModifyStyle(((HWND)GetHWND()),WS_HSCROLL ,0,0);
if(m_bHideVertScrollbar)
ModifyStyle(((HWND)GetHWND()),WS_VSCROLL,0,0);
}
return wxListCtrl::MSWWindowProc(message,wParam,lParam);
}
#endif

regards,
gunnar

Kovács Tamás

unread,
Apr 3, 2005, 2:24:43 PM4/3/05
to wx-u...@lists.wxwidgets.org
Vadim Zeitlin írta:

> KT> Is there any way to disable the horizontal scrollbar in a wxListCtrl?
>
> Simply make it columns wide enough.

Nice idea, but in my case it don't work:( I set the width of the
columns to fit the whole width of the control when an EVT_SIZE event
occurs. I calculate the width of the columns as follows:

int i, width, colWidth, colNum = 0;

GetClientSize (&width, NULL);
colNum = GetColumnCount();
if (colNum < 1) return; // don't want to divide by 0
colWidth = width / colNum;
for (i = 0; i < colNum; i++) SetColumnWidth (i, colWidth);

According to the description of GetClientSize(), it should return the
width _excluding_ the scrollbar, but it doesn't work the way excepted.
Another solution would be to get the width of the vertical scrollbar so
I could descent the width variable with it. But I still can't get any
pointer to the scrollbars or to their properties..

--
Kovacs Tamas, Hungary

Gunnar Roth

unread,
Apr 3, 2005, 2:33:25 PM4/3/05
to wx-u...@lists.wxwidgets.org
Kovács Tamás schrieb:

I assume you are using the generic listcrl used by wxGTK and wxMAC.
There GetClientSize() return the size INCLUDING the scrollbar.

I have therefore this code in wxMusik.

void CActivityListBox::RescaleColumns( )
{
int nWidth, nHeight;
GetClientSize ( &nWidth, &nHeight );
const int main_col = 0;
if ( GetColumnWidth( main_col ) != nWidth )
{
#ifdef __WXMSW__
SetColumnWidth ( main_col, nWidth );
#else
SetColumnWidth( main_col, nWidth -
wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y) - 1 );
#endif
}
}

NOTE: This is for only one column.
regards,
gunnar

Kovács Tamás

unread,
Apr 3, 2005, 2:44:20 PM4/3/05
to wx-u...@lists.wxwidgets.org
Gunnar Roth írta:

> SetColumnWidth( main_col, nWidth - wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y) - 1 );

Thanks, this works fine! Now I have only one question according to this
topic: how can I make the vertical scrollbar always visible? Passing the
wxVSCROLL flag to the constructor doesn't seem beeing enough..

--
Kovacs Tamas, Hungary

Vadim Zeitlin

unread,
Apr 3, 2005, 5:39:16 PM4/3/05
to wx-u...@lists.wxwidgets.org
On Sun, 03 Apr 2005 20:21:34 +0200 Gunnar Roth <gunna...@gmx.de> wrote:

GR> ListView_SetExtendedListViewStyleEx(hwnd,LVS_EX_LABELTIP,LVS_EX_LABELTIP);

We probably should do this in wxListCtrl itself by default -- I don't see
any reason to not do it.

GR> long CMusikListCtrl::MSWWindowProc(WXUINT message, WXWPARAM wParam,
GR> WXLPARAM lParam)
GR> {
GR> if(message == WM_NCCALCSIZE)
GR> {
GR> if(m_bHideHorzScrollbar)
GR> ModifyStyle(((HWND)GetHWND()),WS_HSCROLL ,0,0);
GR> if(m_bHideVertScrollbar)
GR> ModifyStyle(((HWND)GetHWND()),WS_VSCROLL,0,0);
GR> }
GR> return wxListCtrl::MSWWindowProc(message,wParam,lParam);
GR> }

Interesting. I wonder how does the list control behave if you forcefully
remove the scrollbars from under it. Anyhow, I don't think this is the best
way to achieve what we want here, I'd prefer to fix the flicker due to
hiding/showing/hiding scrollbar. Do you have any idea where is it coming
from?

Thanks,

Gunnar Roth

unread,
Apr 3, 2005, 6:58:24 PM4/3/05
to wx-u...@lists.wxwidgets.org

Am 03.04.2005 um 23:39 schrieb Vadim Zeitlin:

> On Sun, 03 Apr 2005 20:21:34 +0200 Gunnar Roth <gunna...@gmx.de>
> wrote:
>
> GR>
> ListView_SetExtendedListViewStyleEx(hwnd,LVS_EX_LABELTIP,LVS_EX_LABELTI
> P);
>
> We probably should do this in wxListCtrl itself by default -- I don't
> see
> any reason to not do it.
>

Yes this style is always useful IMHO. I dont know why windows doenst
use it as a default.
But wxWidgets can of course set it always. But maybe there should be a
style to switch it off,
because there always people who complain ;-)


> GR> long CMusikListCtrl::MSWWindowProc(WXUINT message, WXWPARAM wParam,
> GR> WXLPARAM lParam)
> GR> {
> GR> if(message == WM_NCCALCSIZE)
> GR> {
> GR> if(m_bHideHorzScrollbar)
> GR> ModifyStyle(((HWND)GetHWND()),WS_HSCROLL ,0,0);
> GR> if(m_bHideVertScrollbar)
> GR> ModifyStyle(((HWND)GetHWND()),WS_VSCROLL,0,0);
> GR> }
> GR> return wxListCtrl::MSWWindowProc(message,wParam,lParam);
> GR> }
>
> Interesting. I wonder how does the list control behave if you
> forcefully
> remove the scrollbars from under it.

Well the idea is from code i found on www.codeproject.com
The listctrl does add the WS_HSCROLL if the columns do not fit,
the code removes them again, before the ctrl handles WM_NCCALCSIZE,
so it does the calculation without the WS_HSCROLL.

> Anyhow, I don't think this is the best
> way to achieve what we want here,

Well i added this code just a few days ago, but i have not experienced
any problems yet.

> I'd prefer to fix the flicker due to
> hiding/showing/hiding scrollbar. Do you have any idea where is it
> coming
> from?

The window is getting smaller, a scrollbar is needed, sb is shown, in
EVT_SIZE handler column is made smaller, scrollbar is hidden again.

regards,
gunnar


Vadim Zeitlin

unread,
Apr 5, 2005, 8:31:28 PM4/5/05
to wx-u...@lists.wxwidgets.org
On Mon, 4 Apr 2005 00:58:24 +0200 Gunnar Roth <gunna...@gmx.de> wrote:

GR> > ListView_SetExtendedListViewStyleEx(hwnd,LVS_EX_LABELTIP,LVS_EX_LABELTI
GR> > P);
GR> >
GR> > We probably should do this in wxListCtrl itself by default -- I don't
GR> > see any reason to not do it.
GR> >
GR> Yes this style is always useful IMHO. I dont know why windows doenst
GR> use it as a default.

wxWindows now does.

GR> > I'd prefer to fix the flicker due to hiding/showing/hiding scrollbar.
GR> > Do you have any idea where is it coming from?
GR>
GR> The window is getting smaller, a scrollbar is needed, sb is shown, in
GR> EVT_SIZE handler column is made smaller, scrollbar is hidden again.

Somehow we should adjust the column widths before... I guess we should do
it when handling WM_SIZING (as opposed to WM_SIZE) but currently there is
no special wx event for this message.

Still, it would be nice to be able to do this portably and not using Win32
code you showed, even if it's surely useful as a solution of last resort.

Regards,

Gunnar Roth

unread,
Apr 6, 2005, 6:58:05 AM4/6/05
to wx-u...@lists.wxwidgets.org
Vadim Zeitlin sagte:

> On Mon, 4 Apr 2005 00:58:24 +0200 Gunnar Roth <gunna...@gmx.de> wrote:
>
> GR> >
> ListView_SetExtendedListViewStyleEx(hwnd,LVS_EX_LABELTIP,LVS_EX_LABELTI
> GR> > P);
> GR> >
> GR> > We probably should do this in wxListCtrl itself by default -- I
> don't
> GR> > see any reason to not do it.
> GR> >
> GR> Yes this style is always useful IMHO. I dont know why windows doenst
> GR> use it as a default.
>
> wxWindows now does.
>
> GR> > I'd prefer to fix the flicker due to hiding/showing/hiding
> scrollbar.
> GR> > Do you have any idea where is it coming from?
> GR>
> GR> The window is getting smaller, a scrollbar is needed, sb is shown, in
> GR> EVT_SIZE handler column is made smaller, scrollbar is hidden again.
>
> Somehow we should adjust the column widths before... I guess we should do
> it when handling WM_SIZING (as opposed to WM_SIZE) but currently there is
> no special wx event for this message.
There is EVT_SIZING, i have tried that but that event does never get fired
it seems.

>
> Still, it would be nice to be able to do this portably and not using
> Win32
> code you showed, even if it's surely useful as a solution of last resort.

Well as far as i can remember( i am not at home now) on wxMAC and wxGTK i
dont have the problem with flickering scrollbars.


Before a few weeks i did the cloumn resizing in DoSetSize().
But after change of wxWidgets concerning use of DeferWindowPos
this didnt work anymore, so i used a EVT_SIZE handler.
But now a evil bug has raised its head...
I have 2 or more selection boxes (containing a listctrl with one column
each) the content of the boxes depend on the selection of the active box.
If i scroll the content vertically of a dependant box somewhat and then
slect another entry in the first box, the content of the 2nd box is
changed
. this is done by filling an internal array and calling SetItemCount() of
the virtaul listctrl. But NOW the content of this listctrl is shown by an
offset, depneding on how far scrolled the control was before the change.

If i comment out the SetColumnWidth() call, this does not happen.

I have made a small patch to the listctrl sample, which exhibits the bug.
I have no cvs acces here so the patch is against 2.5.3,
i hope it can be applied without problem.
to see the bug do this:
1. start listctrl sample.
2. scroll a few lines down.
3. select a line in the listctrl to give it the focus.
4. press insert key.

regards,
gunnar


--- wxWidgets-2.5.3/samples/listctrl/listtest.h 2004-10-01
12:27:18.000000000 +0200
+++ wxcvs/wxWidgets/samples/listctrl/listtest.h 2005-04-06
01:30:50.421875000 +0200
@@ -61,4 +61,13 @@

void OnChar(wxKeyEvent& event);
+ void OnSize(wxSizeEvent& event)
+ {
+ int nWidth, nHeight;
+ GetClientSize ( &nWidth, &nHeight );
+ SetColumnWidth(0,nWidth/3);
+ SetColumnWidth(1,nWidth/3);
+ SetColumnWidth(2,nWidth - 2*(nWidth/3));
+ event.Skip();
+ }

private:

--- wxWidgets-2.5.3/samples/listctrl/listtest.cpp 2004-10-01
12:27:18.000000000 +0200
+++ wxcvs/wxWidgets/samples/listctrl/listtest.cpp 2005-04-06
01:27:44.250000000 +0200
@@ -109,4 +109,5 @@

EVT_CHAR(MyListCtrl::OnChar)
+ EVT_SIZE(MyListCtrl::OnSize)
END_EVENT_TABLE()

@@ -241,5 +242,5 @@
m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_logWindow));

- RecreateList(wxLC_REPORT | wxLC_SINGLE_SEL);
+ RecreateList(wxLC_REPORT | wxLC_VIRTUAL);

#if wxUSE_STATUSBAR
@@ -474,7 +475,7 @@
m_listCtrl->SetBackgroundColour(*wxLIGHT_GREY);

- m_listCtrl->SetColumnWidth( 0, wxLIST_AUTOSIZE );
- m_listCtrl->SetColumnWidth( 1, wxLIST_AUTOSIZE );
- m_listCtrl->SetColumnWidth( 2, wxLIST_AUTOSIZE );
+ m_listCtrl->SetColumnWidth( 0, 30 );
+ m_listCtrl->SetColumnWidth( 1, 30 );
+ m_listCtrl->SetColumnWidth( 2, 30 );
}

@@ -910,5 +913,5 @@
if ( GetWindowStyle() & wxLC_VIRTUAL )
{
- SetItemCount(GetItemCount() + 1);
+ SetItemCount(GetItemCount() > 10 ? 4 : 100);
}
else // !virtual


Gunnar Roth

unread,
Apr 8, 2005, 8:33:48 AM4/8/05
to wx-u...@lists.wxwidgets.org
Hello,
this problem i do describe here is very important to me and my app.
Would be nice if some kind soul would give me some feedback.
regards,
gunnar


Gunnar Roth wrote:

>Vadim Zeitlin sagte:

>---------------------------------------------------------------------
>To unsubscribe, e-mail: wx-users-u...@lists.wxwidgets.org
>For additional commands, e-mail: wx-use...@lists.wxwidgets.org
>
>
>
>
>


Vadim Zeitlin

unread,
Apr 8, 2005, 8:36:21 AM4/8/05
to wx-u...@lists.wxwidgets.org
On Fri, 08 Apr 2005 14:33:48 +0200 Gunnar Roth <gunna...@gmx.de> wrote:

GR> this problem i do describe here is very important to me and my app.
GR> Would be nice if some kind soul would give me some feedback.

I won't have time to look at this, sorry.

Reply all
Reply to author
Forward
0 new messages