Discussion:
TListView autosize columns + drawing problem.
(too old to reply)
Jason Cipriani
2008-01-20 12:56:09 UTC
Permalink
With the TListView control in C++ Builder 2007:

1) How do I autosize columns in report mode after adding items? I have each
column's AutoSize property set to true, and I am adding items and setting
subitems via ListView->Items->Add(). I tried setting AutoSize for each
column back to false then back to true again after adding the items but that
didn't work either. Columns stay there default size.

2) How do I make this not happen when I press the down arrow on the scroll
bar:

Loading Image...

Thanks,
Jason
Asger Joergensen
2008-01-20 15:22:20 UTC
Permalink
Hi Jason Cipriani
Post by Jason Cipriani
1) How do I autosize columns in report mode after adding items? I have each
column's AutoSize property set to true, and I am adding items and setting
subitems via ListView->Items->Add(). I tried setting AutoSize for each
column back to false then back to true again after adding the items but that
didn't work either. Columns stay there default size.
Try this work-arround:
ListView->Width = ListView->Width + 1;
ListView->Width = ListView->Width - 1;

if the listview is aligned on the width You only
need one line.

p.s.
In my expirience it is best not to have all columns set to autosize.
Post by Jason Cipriani
2) How do I make this not happen when I press the down arrow on the scroll
http://img250.imageshack.us/img250/2626/listviewed3.gif
That does not look nice...
Are You ownerdrawing ?
Are You using large font on Your system ?
I have seen this a lot in other apps and I use large font 144 DPI
Obviously I have no solution, but maybe:
Have You tried DoubleBuffered = true; ?
En imagelist with no images assigned to smallimages and the imagesize
set to match the hight You want on each item.

Kind regards
Asger
Jason Cipriani
2008-01-20 16:06:15 UTC
Permalink
Thanks for your reply.
Post by Asger Joergensen
ListView->Width = ListView->Width + 1;
ListView->Width = ListView->Width - 1;
This did not work. As a sanity check I also tried just adding 1 to Width
each time without restoring it (so the list kept getting wider). When
AutoSize is true the columns just all stay the same width as eachother,
proportional to the list width (so if there's 4 columns they're always sized
to be 1/4th the list width), no matter what text is in them.

However, it appears that TListView is (as expected) based off the standard
shell list view control. So the following code works for autosizing the
columns. Set AutoSize properties to FALSE in the designer (don't use built
in auto size), then do:

#include <commctrl.h>

{
for (int j = 0; j < ListView1->Columns->Count; ++ j)
ListView_SetColumnWidth(ListView1->Handle, j,
LVSCW_AUTOSIZE_USEHEADER);
}

ListView_SetColumnWidth docs can be found in the MSDN. I really don't like
this solution for two reasons: 1) It does not change the fact that the
AutoSize property doesn't do what the documentation says it does (resize
columns to text width), and 2) it bypasses the VCL class interface and makes
the assumption that the underlying implementation is indeed a shell list
view control. A better solution would be nice.
Post by Asger Joergensen
Are You ownerdrawing ?
No.
Post by Asger Joergensen
Are You using large font on Your system ?
No.
Post by Asger Joergensen
Have You tried DoubleBuffered = true; ?
Hm, that doesn't fix it.
Post by Asger Joergensen
En imagelist with no images assigned to smallimages and the imagesize
set to match the hight You want on each item.
That does not help either, unfortunately. :(

I had wanted to try importing the list view ActiveX control (Microsoft
Windows Common Controls SP6) and seeing if that worked. Unfortunately I
could not, entirely because of issues with class name conflicts and the fact
that the Refactor tool mysteriously decided not to work (giving me the
informative message "Failed to setup refactoring"). But that is a different
story.

This is really frustrating, and is yet another addition to the growing list
of frustrations that I have with C++ Builder. I'm keeping an open mind since
I've only been using it for less than a week now but the list has grown
large for such a short amount of time.
Asger Joergensen
2008-01-21 00:37:22 UTC
Permalink
Hi Jason Cipriani
Post by Jason Cipriani
Thanks for your reply.
Post by Asger Joergensen
ListView->Width = ListView->Width + 1;
ListView->Width = ListView->Width - 1;
This did not work. As a sanity check I also tried just adding 1 to Width
each time without restoring it (so the list kept getting wider). When
AutoSize is true the columns just all stay the same width as eachother,
proportional to the list width (so if there's 4 columns they're always sized
to be 1/4th the list width), no matter what text is in them.
Yes thats how it is set up in the vcl code, thats why I mentioned
that You shouldn't set all columns to autosize
Post by Jason Cipriani
However, it appears that TListView is (as expected) based off the standard
shell list view control. So the following code works for autosizing the
columns. Set AutoSize properties to FALSE in the designer (don't use built
#include <commctrl.h>
{
for (int j = 0; j < ListView1->Columns->Count; ++ j)
ListView_SetColumnWidth(ListView1->Handle, j,
LVSCW_AUTOSIZE_USEHEADER);
}
ListView_SetColumnWidth docs can be found in the MSDN. I really don't like
this solution for two reasons: 1) It does not change the fact that the
AutoSize property doesn't do what the documentation says it does (resize
columns to text width), and 2) it bypasses the VCL class interface and makes
the assumption that the underlying implementation is indeed a shell list
view control. A better solution would be nice.
You are right about the documentation, but I think You should see it
as an extra feature, using the VCL way get rid of the horizontal scrollbar
and autosize all in view.
Whereas the API way autosize to the content and might give You
invisible columns.
I consider it a feture that I can use both.
Post by Jason Cipriani
That does not help either, unfortunately. :(
It is strange, because I cant reproduce it on my PC, but then again
I still use BCB5 and WinXP..;-)
Post by Jason Cipriani
I had wanted to try importing the list view ActiveX control (Microsoft
Windows Common Controls SP6) and seeing if that worked. Unfortunately I
could not, entirely because of issues with class name conflicts and the fact
that the Refactor tool mysteriously decided not to work (giving me the
informative message "Failed to setup refactoring"). But that is a different
story.
Never tried ActiveX, never had the need.
Post by Jason Cipriani
This is really frustrating, and is yet another addition to the growing list
of frustrations that I have with C++ Builder. I'm keeping an open mind since
I've only been using it for less than a week now but the list has grown
large for such a short amount of time.
You might have an open mind, but it is a little as if You are comparing
good working close with lastes fashion, the VCL does not implement every
feature of the windows controls and it does not have all the latest, but
it make it very easy to do windows programming and it does not lock You
in any way.
If You look at Your own code snippet You used the VCL implementation of
the columns and the ListView->Handle to make Your calls to the API listview
function. It is made easy for You..

I do admit that the listview You precented looks very strange and I hope
someone will be able to help You find the error.
But personally I find the Windoows listview very bad, it is slow, You cant
change the height of the items, It positions the icons wrong etc.
But the nice thing is that there are other reportviews or listviews out
there and they are so easy to install and use in BCB.

Kind regards
Asger
Jason Cipriani
2008-01-21 02:44:21 UTC
Permalink
Thanks for your reply. While the TListView has its pluses and minuses, the
fact remains that the documentation for TListView's AutoSize property
explicitly states, and I quote:

"Use AutoSize to get or set whether the list column automatically sizes
itself to the width of its text."

It does not say "Use AutoSize to get or set whether the list column is sized
to a fraction of the total list view width". The width of the text in the
column has no effect on the column width at all, despite what the
Post by Asger Joergensen
You are right about the documentation, but I think You should see it
as an extra feature, using the VCL way get rid of the horizontal scrollbar
and autosize all in view.
This is not quite accurate: Setting AutoSize to true does not actually get
rid of the horizontal scroll bar. When a vertical scroll bar is present,
AutoSize still sets the total width of all columns to the actual width of
the ListView control, thus -always- creating a horizontal scroll bar (when a
vertical one is present).

No matter how you look at it, something is wrong. Whether it's the
documentation or the implementation of AutoSize itself, I wouldn't be able
to say.
Post by Asger Joergensen
It is strange, because I cant reproduce it on my PC, but then again
I still use BCB5 and WinXP..;-)
I'm sure there is a difference between BCB5 and 2007 -- I am also using
Windows XP (SP2).
Post by Asger Joergensen
You might have an open mind, but it is a little as if You are comparing
good working close with lastes fashion, the VCL does not implement every
feature of the windows controls and it does not have all the latest, but
it make it very easy to do windows programming and it does not lock You
in any way.
You are right. I really like C++ Builder and that was a little snippy of me
to say. However, AutoSize does not work as expected. And while it was easy
for me, I only knew about that ListView macro (and though to try sending
standard shell list view messages to Borland's ListView control) because I
have some experience with Windows development outside of C++ Builder. This
would not always be the case, and had C++ Builder been my introduction to
Windows programming, I would never have found a solution considering what
the 2007 documentation says about the property.
Post by Asger Joergensen
If You look at Your own code snippet You used the VCL implementation of
the columns and the ListView->Handle to make Your calls to the API listview
function. It is made easy for You..
It's true, it is easy. What worries me about this solution is I feel that it
is a hack: Nowhere does it say that TListView is based on the shell list
view control, and therefore I can not in good conscience bring myself to
rely on the fact that TListViews will accept Windows shell list view
messages (the macro I used is a shortcut for SendMessage(...,
LVM_SETCOLUMNWIDTH, ..., ...)). When I said it "bypasses the VCL
interfaces", I meant that I had to go around the normal properties and
methods of the TListView class itself, and instead use it's Window handle to
call Win32 API functions directly -- functions that are not necessarily
guaranteed to work on TListViews in the first place, if that makes sense.
Post by Asger Joergensen
I do admit that the listview You precented looks very strange and I hope
someone will be able to help You find the error.
If I find the drawing error, I will post it here for sure. I have not found
a solution yet, and thanks again for your suggestions. I appreciate it. I'll
keep looking. As far as the AutoSize thing goes, although I don't like it,
the above ListView_SetColumnWidth macros can be used as a workaround for
now.

Jason
Jason Cipriani
2008-01-31 21:21:49 UTC
Permalink
Post by Jason Cipriani
2) How do I make this not happen when I press the down arrow on the scroll
I submitted this as QC #57234, and it is currently open, however...
Post by Jason Cipriani
1) How do I autosize columns in report mode after adding items? I have each
column's AutoSize property set to true, and I am adding items and setting
subitems via ListView->Items->Add(). I tried setting AutoSize for each
column back to false then back to true again after adding the items but that
didn't work either. Columns stay there default size.
I submitted this as QC #57233, but that report was withdrawn:

http://qc.codegear.com/wc/qcmain.aspx?d=57233

I still have not found a VCL-only solution. Sending window messages directly
to the listview control is the only thing that I got working. Am I missing
something obvious? If not, why was this report withdrawn?

Thanks,
Jason

Loading...