Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CListCtrl size at runtime

833 views
Skip to first unread message

Gary

unread,
Nov 17, 2008, 6:18:09 PM11/17/08
to
Hi,

I would like to know how many items can I insert into a CListCtrl.... ?
I am not using virtual list control.....
I am just using CListCtrl in a form view..........

I just want to keep on adding possibly millions of items at runtime and save
them to a text file is user wants to...........

I don't want to load those many items..........

InsertItem() takes "int" as parameter index......so CListCtrl should atleast
support
(–2,147,483,648 to 2,147,483,647) items..........

I just want to make sure I can add as many items as I want at run time...

Any pointers would be apprciated.

Thanks,
Gary

Joseph M. Newcomer

unread,
Nov 17, 2008, 10:15:05 PM11/17/08
to
In theory, as many as you want; in practice, as many as will fit.

Note that if you are putting 2G items into a list control, you are going to have a massive
amount of overhead. And there probably aren't enough bytes of storage to hold all these
strings (after all, a string takes 4+n bytes where n is the number of bytes in the string,
as a minimum, and it is probably something like 20+n bytes, and you have, at least in
Win32, only 2GB of storage, so it is unlikely you will be able to fit more than about
60,000,000 strings in any real control. But also you have to ask how long it takes to
load such a control. Hours, probably.

It is unlikely you will be able to support a negative number of items in a list control.
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Giovanni Dicanio

unread,
Nov 18, 2008, 4:32:09 AM11/18/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:FCACADAD-7521-4333...@microsoft.com...

> I would like to know how many items can I insert into a CListCtrl.... ?
> I am not using virtual list control.....
> I am just using CListCtrl in a form view..........
>
> I just want to keep on adding possibly millions of items at runtime and
> save
> them to a text file is user wants to...........

For such a big number of items, I think that you should use owner-data
listview controls.

When owner-data attribute is used (LVS_OWNERDATA), the listview does not
store any information about the content of its items: whenever the listview
needs something, it will asks you. So simple.
You just need to call CListCtrl::SetItemCount to tell the listview that
there are so many items (e.g. 1,000,000).
Then you can handle the LVN_GETDISPINFO notification, and return the
required text for particular listview items.

Note that even if you have a listview of 1,000,000 items, you can not
display 1,000,000 rows on the screen, so only some items (a small subset of
all items) will be displayed at any given point in time.

I think that in your case of such big number of items, you could load them
from some external source, and so you may use the power of LVN_ODCACHEINT
notification. Basically, when the listview needs some block of items in a
given range, it will send you that notification, telling you "I [the
listview] am going to ask you some information about the items in this
range.". So you can prepare that information, caching it, and making it
ready to pass to next LVN_GETDISPINFO requests.

Giovanni


Giovanni Dicanio

unread,
Nov 18, 2008, 5:05:33 AM11/18/08
to

"Joseph M. Newcomer" <newc...@flounder.com> ha scritto nel messaggio
news:vhc4i49md2s48k988...@4ax.com...

> Note that if you are putting 2G items into a list control, you are going
> to have a massive
> amount of overhead. And there probably aren't enough bytes of storage to
> hold all these
> strings (after all, a string takes 4+n bytes where n is the number of
> bytes in the string,
> as a minimum, and it is probably something like 20+n bytes, and you have,
> at least in
> Win32, only 2GB of storage, so it is unlikely you will be able to fit more
> than about
> 60,000,000 strings in any real control. But also you have to ask how long
> it takes to
> load such a control. Hours, probably.

Joe: I think that you made very good points, and moreover I think that the
key here is to use owner-data listviews.

At any given point in time, the listview will display only a very small
range of the total huge number of items, and it makes sense to just give the
listview information about only these items in that subset.

Proper use of owner-draw listview notification messages like LVN_GETDISPINFO
(to give the listview information about only the required items) and
LVN_ODCACHEHINT (to properly cache a subset of all items, e.g. loading from
a database or some other external source) could help the OP here.

Giovanni


Serge Wautier

unread,
Nov 18, 2008, 6:35:14 AM11/18/08
to
> I am not using virtual list control.....
> I just want to keep on adding possibly millions of items at runtime

Then you're out of luck. My own experience is that virtual list mode is
necessary to keep the list responsive at load AND destroy time as soon as
you have more than a couple thousands items.

See Giovanni's answers for more details. FWIW, "owner-data" = "virtual list"

HTH,

Serge.
http://www.apptranslator.com - Localization tool for your MFC applications


"Gary" <Ga...@discussions.microsoft.com> wrote in message
news:FCACADAD-7521-4333...@microsoft.com...

AliR (VC++ MVP)

unread,
Nov 18, 2008, 11:17:16 AM11/18/08
to
Even a couple of hundred items with 2 or 3 sub items will take long enough
that you will have to switch to virtual list mode. If you ask me virtual
list mode should be standard on list control, they should do away with the
normal mode.

AliR.


"Serge Wautier" <se...@wautier.nospam.net> wrote in message
news:uez$7GXSJH...@TK2MSFTNGP02.phx.gbl...


>> I am not using virtual list control.....
>> I just want to keep on adding possibly millions of items at runtime
>
> Then you're out of luck. My own experience is that virtual list mode is
> necessary to keep the list responsive at load AND destroy time as soon as
> you have more than a couple thousands items.
>
> See Giovanni's answers for more details. FWIW, "owner-data" = "virtual
> list"
>
> HTH,
>
> Serge.
> http://www.apptranslator.com - Localization tool for your MFC applications
>
>
> "Gary" <Ga...@discussions.microsoft.com> wrote in message
> news:FCACADAD-7521-4333...@microsoft.com...
>> Hi,
>>
>> I would like to know how many items can I insert into a CListCtrl.... ?
>> I am not using virtual list control.....
>> I am just using CListCtrl in a form view..........
>>
>> I just want to keep on adding possibly millions of items at runtime and
>> save
>> them to a text file is user wants to...........
>>
>> I don't want to load those many items..........
>>
>> InsertItem() takes "int" as parameter index......so CListCtrl should
>> atleast
>> support

>> (-2,147,483,648 to 2,147,483,647) items..........

Giovanni Dicanio

unread,
Nov 18, 2008, 1:14:36 PM11/18/08
to

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> ha scritto nel
messaggio news:uCEEWDWS...@TK2MSFTNGP04.phx.gbl...

> For such a big number of items, I think that you should use owner-data
> listview controls.

I did a simple MFC test, filling a listview with 100,000 records (each
record containing three strings).

On this computer (Intel Core 2 Duo @ 2.3 GHz, with 3 GB RAM), with normal
listview, the user must wait *more than 5 seconds* to see the listview on
screen, that is bad for user experience.

Instead, with owner-data listview, the same 100,000 records listview appears
immediately to the user.

The VS2008 source code for this simple test can be downloaded from here:

http://www.geocities.com/giovanni.dicanio/vc/ListViewTests_src.zip

And the release-mode .exe's can be downloaded from here:

http://www.geocities.com/giovanni.dicanio/vc/ListViewTests_exe.zip

Giovanni


Tom Serface

unread,
Nov 18, 2008, 4:35:11 PM11/18/08
to
I fully agree. It is so easy to set up and use it almost seems like it
should be the default. It is certainly not any more trouble than setting up
the normal way. And with the ability to set the number of items "virtually"
as well you can even have the thumb in the scroll bar work as though the
list was actually populated.

Tom

"AliR (VC++ MVP)" <Al...@online.nospam> wrote in message
news:UUBUk.11884$Ws1...@nlpi064.nbdc.sbc.com...

Tom Serface

unread,
Nov 18, 2008, 4:33:48 PM11/18/08
to
I agree with some of the others that after a few hundred items you will want
to consider a virtual list control. They are very easy to set up, the data
can come from just about anywhere, and they are way quicker for displaying.
You can even have some of the data cached in a file or database or whatever
so long as it can be accessed when needed. That said, I don't think you'll
reach the limit. Before that happened no one would be willing to use your
application.

Tom

"Gary" <Ga...@discussions.microsoft.com> wrote in message
news:FCACADAD-7521-4333...@microsoft.com...

Gary

unread,
Nov 18, 2008, 11:07:01 PM11/18/08
to
Thanks Joe.

In my case when I startup my CListCtrl will always be empty. So I don't have
to worry about loading items into the control.

I keep on receiving data at runtime and add it to the CListCtrl and when the
user closes the control I don't have to retain any data.

I just need to save the data to a text file if the user prompts me to do so.

Thanks,
Gary

Gary

unread,
Nov 18, 2008, 11:11:00 PM11/18/08
to
Thanks.

In my case when I startup my CListCtrl will always be empty. So I don't have
to worry about loading items into the control.

I keep on receiving data at runtime and add it to the CListCtrl and when the
user closes the control I don't have to retain any data.

I just need to save the data to a text file if the user prompts me to do so.

So only in this scenario I need to go through each item in the CListCtrl and
save it to a text file.

How difficult it is to convert a normal CListCtrl to use Virtual list
control ?
Can I use the virtual control in a form view ?

Thanks,
Gary

Gary

unread,
Nov 18, 2008, 11:18:03 PM11/18/08
to
Thanks a lot for the code, appreciated.

I have replied to your previous comments about the way I am using the
CListCtrl.
In my case the list keeps on updating and I use EnsureVisible() to
automatically scroll to the last item that will be visible to the user.

The only scenario I need to access the list control data is when the user
asks me to save it to a text file. In that case I need to go through each
item and save it to a text file.

My list control will be empty when I startup and build up at runtime.

So still in this case do you recommend me using a virtual list control ?

I tried adding 350, 000 items, they are added successfully but the list
control flcikers a lot after that.

Thanks,
Gary

Gary

unread,
Nov 18, 2008, 11:21:01 PM11/18/08
to
Thanks Serge.

My list control will be empty at start up and I don't need to worry about
saving data on destroy.

Only if the user asks me to save the data at runtime, I need to save each
item to a text file.

Thanks,
Gary

Gary

unread,
Nov 18, 2008, 11:23:00 PM11/18/08
to
Thanks AliR.

How difficult and time consuming it is to convert code from using CListCtrl
to using virtual list control ?

Also can I use the virtual list control in a form view ?

Thanks,
Gary

Gary

unread,
Nov 18, 2008, 11:25:01 PM11/18/08
to
Thanks Tom.

Do you have an example of converting a CListStrl to a virtual list control ?
Do I just need to use the flag LVS_OWNERDATA in my call to
setExtendedStyle() method of CListCtrl ?
Does setting the flag take care of making it a virtual list control ?

Thanks,
Gary

Gary

unread,
Nov 18, 2008, 11:30:00 PM11/18/08
to
Thanks a lot Tom.

So a few hundred items (< 500, 000) ok for a normal CListCtrl ?

I did ask you a few question in my reply to your previous comment regarding
usage of virtual list control.

In my application I need to keep on appending items to the control as they
are received forever. I automatically scroll to the last item using
EnsureVisible().

My only concern will be when I want to save the items from the list control
to a text file when the user prompts me to do so.

I don't need to load any items at startup, my list control will be empty.

Thanks,
Gary

Gary

unread,
Nov 18, 2008, 11:58:01 PM11/18/08
to
Thanks Giovanni.

I have Visual Studio 2005, so not able to open your solution file version
2008.
Is it possible for you to convert it to a 2005 version source code ?

Thanks,
Gary

Tom Serface

unread,
Nov 19, 2008, 12:20:24 AM11/19/08
to
Here's some info. Basically, you just change it to be owner drawn and add a
GetDispInfo() handler. Then you have to supply the data for each item when
it is requested in the callback. If you want a specific example drop me an
email with your address and I'll send you a sample project I just worked up
for an article I'm doing about using bitmap files as the icons in a list
control (virtual).

http://msdn.microsoft.com/en-us/library/ye4z8x58(VS.80).aspx

Tom

"Gary" <Ga...@discussions.microsoft.com> wrote in message

news:8490D69D-40A3-4815...@microsoft.com...

Tom Serface

unread,
Nov 19, 2008, 12:24:03 AM11/19/08
to
I wouldn't load more than a few hundred items into a list control directly.
They start to run really slowly after a while and it takes a lot of time.

You can use the EnsureVisible() call with a virtual list and you would just
add your data to your object array (that you would use to supply the
information to the control as it requests it). That data could even be in
an external file like an .MDB file if you need to sort it different ways.

You still have all the data (I typically use an object array of some sort)
so you can write it to the file easily from the array.

I'm sure everyone here would be happy to help if you have any specific
questions along the way, but check out the link I posted in the previous
message... well, here is again since it's still on my clipboard:

http://msdn.microsoft.com/en-us/library/ye4z8x58(VS.80).aspx

Tom

"Gary" <Ga...@discussions.microsoft.com> wrote in message

news:19217028-DD8C-4D9A...@microsoft.com...

Gary

unread,
Nov 19, 2008, 1:31:01 AM11/19/08
to
Thanks a lot Tom.

Can you please send me your sample project at girish...@hotmail.com ?
Also if it possible for you to convert it to VS 2005 ?

I have VS 2005 and it won't load the test example you sent me earlier.

Gary

unread,
Nov 19, 2008, 1:54:03 AM11/19/08
to
I tried sending you email but it bounced.

My email is girish...@hotmail.com


Also if it possible for you to convert it to VS 2005 ?

Thanks,
Gary

Giovanni Dicanio

unread,
Nov 19, 2008, 3:56:10 AM11/19/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:544C3910-C519-4C29...@microsoft.com...

> I have Visual Studio 2005, so not able to open your solution file version
> 2008.
> Is it possible for you to convert it to a 2005 version source code ?

Hi Gary,

I'm sorry but I only have VS2008 and VC6 installed here.

So the best I could do is to rewrite the sample for VC6, and you should
import it in VS2008...(but I think that you may experience compiler errors
during the conversion process.)

However, there is an article on CodeProject about virtual list controls,
that you can find here:

Using virtual lists
http://www.codeproject.com/KB/list/virtuallist.aspx

Moreover, there is an interesting series on OldNewThing blog about using
listview controls, from the simple version arriving to owner-data (it is
pure Win32 code, but you can adapt that to MFC with ease):

Displaying the dictionary, part 1: Naive version
http://blogs.msdn.com/oldnewthing/archive/2005/06/13/428534.aspx

Displaying the dictionary, part 2: Using text callbacks
http://blogs.msdn.com/oldnewthing/archive/2005/06/14/428892.aspx

Displaying the dictionary, part 3: Using an owner-data listview
http://blogs.msdn.com/oldnewthing/archive/2005/06/15/429338.aspx

Giovanni


Giovanni Dicanio

unread,
Nov 19, 2008, 3:58:00 AM11/19/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:8158E03F-2CA7-4E47...@microsoft.com...

> Thanks a lot for the code, appreciated.

You're welcome.

> I tried adding 350, 000 items, they are added successfully but the list
> control flcikers a lot after that.

I suggest you to try the virtual listviews.

Giovanni


Leo Violette

unread,
Nov 19, 2008, 6:47:32 AM11/19/08
to
To further this point, I find it quite likely that about 2 days of real use
and your users will be
wanting the ability to "reset" the list view back to zero items because
there are just too many to make it
worth scrolling through.

I recommend, like everyone else, to use a virtual list control.
* Add a button to reset the list data.
* When your application receives data you want to add to the list control,
add it to a collection object
(database, vector, list, etc) instead. Virtual List control should go
to this collection to get it's data.
* Increase the rowcount of your list control by 1 row.
* Append this item also to a text file (this is optional, but doing it line
by line makes it a bit quicker if the
user asks to generate a log of a million items because it's already
generated).
* If user clicks on button to create text file, you already have it, just
copy it somewhere they can access it.
* If user closes app, delete the text file (it's a temporary file anyway)
and if you used a database, delete
all of those rows, unless you want the data to persist across application
startups.
* If user clicks on the "Reset List" button, clear the list by setting it's
rowcount to 0 and delete all the rows
you added to the database and / or collection.

"Tom Serface" <tom.n...@camaswood.com> wrote in message
news:OZ62XcgS...@TK2MSFTNGP04.phx.gbl...

>>> > (-2,147,483,648 to 2,147,483,647) items..........

AliR (VC++ MVP)

unread,
Nov 19, 2008, 10:14:33 AM11/19/08
to
Not difficult or time consuming at all. Maybe 15 minutes worth of work at
the end.
Basically you have to set the LVS_OWERDATA (not be confused with
LVS_OWNERDRAW....).
Then you tell the list control how many items you have by calling
SetItemCount.
Then you hande the LVN_GETDISPINFO message and return a string int the
LV_DISPINFO struct passed to your handler method.
You would normally store the strings in a container class (array, map, maybe
even a database). When LVN_GETDISPINFO will tell you which item it wants
the text for.

Here are some working examples:
http://www.codeproject.com/KB/list/virtuallist.aspx
http://www.codeguru.com/cpp/controls/listview/advanced/article.php/c4151/

AliR.


"Gary" <Ga...@discussions.microsoft.com> wrote in message

news:9631EA8E-CF5D-4314...@microsoft.com...

Giovanni Dicanio

unread,
Nov 19, 2008, 3:29:33 PM11/19/08
to

"AliR (VC++ MVP)" <Al...@online.nospam> ha scritto nel messaggio
news:UUBUk.11884$Ws1...@nlpi064.nbdc.sbc.com...

> Even a couple of hundred items with 2 or 3 sub items will take long enough
> that you will have to switch to virtual list mode. If you ask me virtual
> list mode should be standard on list control, they should do away with the
> normal mode.

As a side not, I did a test with WinForms, and I think that they use some
form of "virtual list", because adding something like 20,000 items to a
listview in report mode with C# and WinForms is *fast*.

...this default smart behaviour could be an improvement for MFC next :)

Giovanni

Tom Serface

unread,
Nov 19, 2008, 3:57:33 PM11/19/08
to
If the older lines in the list are no longer needed they could periodically
be written to an external log file and deleted from the "top" of the list as
well. A reset or clear button is a good idea as well.

Tom

"Leo Violette" <le...@primenet.com> wrote in message
news:upWocyjS...@TK2MSFTNGP03.phx.gbl...

Tom Serface

unread,
Nov 19, 2008, 4:01:17 PM11/19/08
to
Sent to your email ... hope it helps. Feel free to ask questions here if
you have them.

Tom

"Gary" <Ga...@discussions.microsoft.com> wrote in message

news:3E49EC80-1886-4C68...@microsoft.com...

Tom Serface

unread,
Nov 19, 2008, 4:02:23 PM11/19/08
to
It can easily be done with MFC now :o)

Tom

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message
news:%23f7ehXo...@TK2MSFTNGP05.phx.gbl...

Gary

unread,
Nov 19, 2008, 4:20:14 PM11/19/08
to
I just checked my email and did not see any emails from you.
girish...@hotmail.com

Gary

Giovanni Dicanio

unread,
Nov 19, 2008, 5:10:13 PM11/19/08
to

"Tom Serface" <tom.n...@camaswood.com> ha scritto nel messaggio
news:02461D6B-4548-4346...@microsoft.com...

> It can easily be done with MFC now :o)

I think not.

Now with MFC the default behaviour with CListCtrl::InsertItem is a
"non-virtual" listview control, which takes lots of time to be filled with
non-trivial amount of data.

You have to use owner-data and answer the LVN_GETDISPINFO, etc. to have
decent performance.
Not very complex, sure, but not as easy and intuitive as doing some calls to
InsertItem in a loop.

Instead, I just verified that the default behaviour with .NET WinForms
listview is that a simple loop like this:

foreach ( some data to read )
{
// Read record data from source
...

// Add to listview
listview.Items.Add( newItem );
}

works fine also for 80,000+ items.

Giovanni


Tom Serface

unread,
Nov 19, 2008, 5:30:25 PM11/19/08
to
Hopefully you have it now. I still had some bugs with my bitmap code in my
other sample so I just whipped up a smaller program with everything you
needed to get started virtually :o)

Tom

"Gary" <Ga...@discussions.microsoft.com> wrote in message

news:B1B90527-D44A-4391...@microsoft.com...

Tom Serface

unread,
Nov 19, 2008, 5:32:28 PM11/19/08
to
Yes, I guess it's like anything else. When you know how to do it ... it
seems easy, but when you don't it seems more difficult. I'm not sure how
they are doing a virtual list by adding each item like that unless they are
just using a callback, but not really making it virtual. Seems like just as
much trouble if you have to add all the "rows" in a loop like that rather
than just using external data.

Tom

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message

news:eX7XVPpS...@TK2MSFTNGP03.phx.gbl...

Leo Violette

unread,
Nov 19, 2008, 6:03:39 PM11/19/08
to
Imagine InsertItem doing nothing but adding the data to a collection class
(no GUI updates).

That, in essence could be what C# is doing. It's simply adding to a
collection every time they add a row but no GUI stuff is happening.

The GUI stuff happens the same as it does for a virtual list control. You
could do something similar for MFC.

"Tom Serface" <tom.n...@camaswood.com> wrote in message

news:913FCD4C-57D1-4AB8...@microsoft.com...

Giovanni Dicanio

unread,
Nov 19, 2008, 6:12:06 PM11/19/08
to

"Leo Violette" <le...@primenet.com> ha scritto nel messaggio
news:%23KxmPsp...@TK2MSFTNGP02.phx.gbl...

> Imagine InsertItem doing nothing but adding the data to a collection class
> (no GUI updates).
>
> That, in essence could be what C# is doing. It's simply adding to a
> collection every time they add a row but no GUI stuff is happening.
>
> The GUI stuff happens the same as it does for a virtual list control.

Exactly. I think that they do something like that.

> You could do something similar for MFC.

Sure, and if MFC had something like that ready "out-of-the-box" it would be
good especially for beginners learning the framework.

It is like the problem of setting background colour of some edit-box.
With C# you can do that at design time with some mouse clicks, or just
setting a color property in code; instead with MFC you have to create the
solid background brush, handle WM_CTLCOLOR, etc. Not bad if you know how to
do it, or if you have a 3rd party CEdit-derived class to use for that
purpose, but I fail to understand why MFC could not just offer a simple and
quality ready-out-of-the-box experience like C# and WinForms do.

Maybe in Microsoft they should invest more in those kinds of improvements to
MFC.

Giovanni

Gary

unread,
Nov 19, 2008, 6:13:01 PM11/19/08
to
Yep. Thank you.

Gary

Tom Serface

unread,
Nov 19, 2008, 7:19:45 PM11/19/08
to
OK, so it's essentially doing the same thing I'm doing with an object array
in MFC (adding my data), only I don't have to add it to the list control as
well.

It would be nice to have a way to set this up in MFC easier.

Tom

"Leo Violette" <le...@primenet.com> wrote in message

news:%23KxmPsp...@TK2MSFTNGP02.phx.gbl...

Joseph M. Newcomer

unread,
Nov 19, 2008, 11:28:00 PM11/19/08
to
See below...
On Tue, 18 Nov 2008 20:07:01 -0800, Gary <Ga...@discussions.microsoft.com> wrote:

>Thanks Joe.
>
>In my case when I startup my CListCtrl will always be empty. So I don't have
>to worry about loading items into the control.
>
>I keep on receiving data at runtime and add it to the CListCtrl and when the
>user closes the control I don't have to retain any data.
>
>I just need to save the data to a text file if the user prompts me to do so.
****
That's trivial. However, as you add more and more items, you may find that the time to
add an item does not remain constant (I haven't tried this for a list control). We did
create a limited-length listbox, where adding the (n+1) element deleted the 0th element.
The reason for this was that "old history" didn't matter. I generalized this in my
Logging ListBox, by setting a "mark", so the "startup" logging sequence was retained (and
was never lost), but data elements that followed were limited.

However, your particular need screams "virtual list control" and I would suggest that is
the best approach. Tom Serface is our virtual control expert in this group, and can
probably point you at the best code for the job.
joe
****
>
>Thanks,
>Gary
>
>"Joseph M. Newcomer" wrote:
>
>> In theory, as many as you want; in practice, as many as will fit.
>>
>> Note that if you are putting 2G items into a list control, you are going to have a massive
>> amount of overhead. And there probably aren't enough bytes of storage to hold all these
>> strings (after all, a string takes 4+n bytes where n is the number of bytes in the string,
>> as a minimum, and it is probably something like 20+n bytes, and you have, at least in
>> Win32, only 2GB of storage, so it is unlikely you will be able to fit more than about
>> 60,000,000 strings in any real control. But also you have to ask how long it takes to
>> load such a control. Hours, probably.
>>
>> It is unlikely you will be able to support a negative number of items in a list control.
>> joe


>>
>> On Mon, 17 Nov 2008 15:18:09 -0800, Gary <Ga...@discussions.microsoft.com> wrote:
>>
>> >Hi,
>> >
>> >I would like to know how many items can I insert into a CListCtrl.... ?
>> >I am not using virtual list control.....
>> >I am just using CListCtrl in a form view..........
>> >
>> >I just want to keep on adding possibly millions of items at runtime and save
>> >them to a text file is user wants to...........
>> >
>> >I don't want to load those many items..........
>> >
>> >InsertItem() takes "int" as parameter index......so CListCtrl should atleast
>> >support

>> >(–2,147,483,648 to 2,147,483,647) items..........


>> >
>> >I just want to make sure I can add as many items as I want at run time...
>> >
>> >Any pointers would be apprciated.
>> >
>> >Thanks,
>> >Gary

>> Joseph M. Newcomer [MVP]
>> email: newc...@flounder.com
>> Web: http://www.flounder.com
>> MVP Tips: http://www.flounder.com/mvp_tips.htm
>>
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Tom Serface

unread,
Nov 20, 2008, 1:58:20 AM11/20/08
to
I think, with a listbox, you can do something a simple as:

// Set the horizontal scroll width
int oldwidth = m_ListBox.GetHorizontalExtent();
CDC* pDC = m_ListBox.GetWindowDC();
if (pDC) {
int newwidth = pDC->GetTextExtent(msg, _tcslen(msg)).cx;
m_ListBox.ReleaseDC(pDC);
if (newwidth > oldwidth)
m_ListBox.SetHorizontalExtent(newwidth);
}
// Delete old entries
if (m_ListBox.GetCount() >= 300)
m_ListBox.DeleteString(0);
// Add the new string at the end
m_ListBox.AddString(msg);
}

You could do the same thing with a list control using:

if(m_ListCtrl.GetItemCount() == MAX_ITEMS)
m_ListCtrl.DeleteItem(0);
m_ListCtrl.AddItem(...);

Of course if it's a virtual list control you would simply delete the content
from your external source and leave the number of items in the list constant
(I.E., remove one and add one to external content so list ctrl stays the
same size). So with something like a CObArray you could do:

if(m_MyArray.GetCount() == MAX_ITEMS)
delete m_MyArray.GetAt(0); // Delete data that was stored in the array
m_MyArray.RemoveAt(0); // Remove 1st item
m_MyArray.Add(pNewInfo); // Add the new one at the end
m_ListCtrl.UpdateWindow();
}
else {
m_MyArray.Add(pNewInfo); // Add the new item
m_ListCtrl.SetItemCountEx(m_MyArray.GetCount()); // Let it grow until
we get to MAX_ITEMS
}

The list control would never know any difference. Who said MFC is
difficult. It's easy breezy... flexible and fast :o)

Tom

"Joseph M. Newcomer" <newc...@flounder.com> wrote in message
news:tjp9i4hf00jg8km3d...@4ax.com...

Leo Violette

unread,
Nov 20, 2008, 7:46:34 AM11/20/08
to
Both you and Giovanni make good points. It's reasonable to conjecture that
perhaps when MFC was originally developed, they
didn't have time or need to build in this sort of flexibility, at least
initially. So, perhaps that flexibility was put on the back burner.
But, then as the years went on and Borland Delphi with it's RAD environment
faded away and newer languages began to steal
MS's attention, I guess MFC was no longer high on MS list to "update" to
make it easier to do some of the stuff that is
effortless with other tools.

"Tom Serface" <tom.n...@camaswood.com> wrote in message

news:FD240F87-AA22-4C1B...@microsoft.com...

Giovanni Dicanio

unread,
Nov 20, 2008, 9:29:31 AM11/20/08
to

"Leo Violette" <le...@primenet.com> ha scritto nel messaggio
news:%23yQyF4w...@TK2MSFTNGP06.phx.gbl...

> Both you and Giovanni make good points. It's reasonable to conjecture
> that perhaps when MFC was originally developed, they
> didn't have time or need to build in this sort of flexibility, at least
> initially. So, perhaps that flexibility was put on the back burner.

I agree. And I think it is not bad; I mean: no one expects a library to be
top-quality from version 1.0.

> But, then as the years went on and Borland Delphi with it's RAD
> environment faded away and newer languages began to steal
> MS's attention, I guess MFC was no longer high on MS list to "update" to
> make it easier to do some of the stuff that is
> effortless with other tools.

Exactly, these are my sentiments, too.

I have the impression that now Microsoft is heavily investing on WPF and C#
as the tools of choice to build GUIs.
I think that the fact that VS2010 IDE is going to have a WPF editor points
in that direction (in 1998 - I think this is the year of VC6 - the IDE was
written in MFC, I recall that VC6 had a startup tool-tip that told "We used
it before you do: VC6 is written using MFC", or something similar.)

Giovanni


David Connet

unread,
Nov 20, 2008, 10:30:25 AM11/20/08
to
"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in
news:eX7XVPpS...@TK2MSFTNGP03.phx.gbl:

>
> "Tom Serface" <tom.n...@camaswood.com> ha scritto nel messaggio
> news:02461D6B-4548-4346...@microsoft.com...
>> It can easily be done with MFC now :o)
>
> I think not.

I was just playing with virtual lists and discovered some interesting
(subtle) UI things... I already use getdispinfo (insert object into data
item, so the list is keeping my objects, rather than me).

Development
- have to delete all calls to listctrl.SortItems (it'll assert, for my
tests, I just ignored the assert - and ignored the fact that it didn't
sort)
- don't use listctrl.GetItemData - replace with direct access to your
data store (didn't even think of that at first - until I ran the program
and crashed!)

Use
- autosizing of columns only works on the visible rows. This makes it
interesting when you add 1000 items then scroll - and see "..." after a
bunch of things. (at first I thought I'd broken something - then I
realized what had happened)
- selection (and multiple selection) just works. That was a pleasant
surprise.

I didn't go any further than that (for instance, dealing with state). But
it did show me that while virtual lists definitely have their use, their
behavior is different.

Dave Connet

Joseph M. Newcomer

unread,
Nov 20, 2008, 11:07:39 AM11/20/08
to
See below...

On Wed, 19 Nov 2008 22:58:20 -0800, "Tom Serface" <tom.n...@camaswood.com> wrote:

>I think, with a listbox, you can do something a simple as:
>
> // Set the horizontal scroll width
> int oldwidth = m_ListBox.GetHorizontalExtent();
> CDC* pDC = m_ListBox.GetWindowDC();
> if (pDC) {
> int newwidth = pDC->GetTextExtent(msg, _tcslen(msg)).cx;
> m_ListBox.ReleaseDC(pDC);
> if (newwidth > oldwidth)
> m_ListBox.SetHorizontalExtent(newwidth);
> }
> // Delete old entries
> if (m_ListBox.GetCount() >= 300)
> m_ListBox.DeleteString(0);
> // Add the new string at the end
> m_ListBox.AddString(msg);
> }

****
That's pretty much the code I use. Note that for the case where I keep the "startup log",
what I do is DeleteString(n) where n is the item that is marked as the first candidate.
Also, if I delete elements, the first time I actually insert an element at position n
which tells me how many items I've deleted, and increment n by 1, so it displays
============Deleted 26 entries================
to show that the log is no longer contiguous. Each time I delete an element, I increment
the counter (since it is owner-draw, it will display the correct amount;
GetItemRect/InvalidateRect handles this if the element is visible)
*****

Joseph M. Newcomer

unread,
Nov 20, 2008, 11:09:15 AM11/20/08
to
You can do this yourself by hand-editing the vcproj/sln files; just change the compiler
version number.
joe

On Tue, 18 Nov 2008 20:58:01 -0800, Gary <Ga...@discussions.microsoft.com> wrote:

>Thanks Giovanni.


>
>I have Visual Studio 2005, so not able to open your solution file version
>2008.
>Is it possible for you to convert it to a 2005 version source code ?
>

>Thanks,
>Gary


>
>"Gary" wrote:
>
>> Thanks a lot for the code, appreciated.
>>

>> I have replied to your previous comments about the way I am using the
>> CListCtrl.
>> In my case the list keeps on updating and I use EnsureVisible() to
>> automatically scroll to the last item that will be visible to the user.
>>
>> The only scenario I need to access the list control data is when the user
>> asks me to save it to a text file. In that case I need to go through each
>> item and save it to a text file.
>>
>> My list control will be empty when I startup and build up at runtime.
>>
>> So still in this case do you recommend me using a virtual list control ?


>>
>> I tried adding 350, 000 items, they are added successfully but the list
>> control flcikers a lot after that.
>>

>> Thanks,
>> Gary
>>
>> "Giovanni Dicanio" wrote:
>>
>> >
>> > "Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> ha scritto nel
>> > messaggio news:uCEEWDWS...@TK2MSFTNGP04.phx.gbl...
>> >
>> > > For such a big number of items, I think that you should use owner-data
>> > > listview controls.
>> >
>> > I did a simple MFC test, filling a listview with 100,000 records (each
>> > record containing three strings).
>> >
>> > On this computer (Intel Core 2 Duo @ 2.3 GHz, with 3 GB RAM), with normal
>> > listview, the user must wait *more than 5 seconds* to see the listview on
>> > screen, that is bad for user experience.
>> >
>> > Instead, with owner-data listview, the same 100,000 records listview appears
>> > immediately to the user.
>> >
>> > The VS2008 source code for this simple test can be downloaded from here:
>> >
>> > http://www.geocities.com/giovanni.dicanio/vc/ListViewTests_src.zip
>> >
>> > And the release-mode .exe's can be downloaded from here:
>> >
>> > http://www.geocities.com/giovanni.dicanio/vc/ListViewTests_exe.zip
>> >
>> > Giovanni

Tom Serface

unread,
Nov 20, 2008, 12:07:36 PM11/20/08
to
We all agree on that. I bet if you lined up the developers working on .NET
libraries and those working on MFC libraries today there would be two
different sized lines.

:o)

Tom

"Leo Violette" <le...@primenet.com> wrote in message

news:%23yQyF4w...@TK2MSFTNGP06.phx.gbl...

Tom Serface

unread,
Nov 20, 2008, 12:14:17 PM11/20/08
to
Great idea. That'sa good visual.

Tom

"Joseph M. Newcomer" <newc...@flounder.com> wrote in message

news:fj2bi45eth60qlqbm...@4ax.com...

Tom Serface

unread,
Nov 20, 2008, 12:13:09 PM11/20/08
to
Interesting point about the autosizing thing. I'd never noticed that since
I don't use that feature, but I can see how the list wouldn't know about the
size of the data without displaying it. I also agree about the item data.
No real need for that any more since you can store anything in your own
data. One nice artifact is you can also modify the data being displayed in
a row based on run time criteria and not have to remove and add back the
row. You can display any text at all based on flags you may have set and
that's a nice feature.

I use SetItemCountEx() to trick the list into thinking it has the number of
items in it rather than going to the trouble of setting up LVITEMS with the
callback. It just seems a lot easier and faster to set up and you get the
same effect. I'm guessing that item data must be stored somewhere in the
control as well, but I don't know for sure.

Tom

"David Connet" <st...@agilityrecordbook.com> wrote in message
news:lofVk.738$jZ1...@flpi144.ffdc.sbc.com...

Leo Violette

unread,
Nov 20, 2008, 2:25:26 PM11/20/08
to
> I recall that VC6 had a startup tool-tip that told "We used it before you
> do: VC6 is written using MFC", or something similar.)

LOL! Absolutely! I remember that tooltip!

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message

news:eBL1syxS...@TK2MSFTNGP03.phx.gbl...

Leo Violette

unread,
Nov 20, 2008, 2:27:05 PM11/20/08
to
Once of the lists could quite comfortably be kept in a normal CListCtrl. I
bet the other would
call for a Virtual CListCtrl. There, that should clear up any confusion on
the differences between
a virtual and non-virtual list control. Ha Ha.

"Tom Serface" <tom.n...@camaswood.com> wrote in message

news:88D41D28-0539-4CDE...@microsoft.com...

Tom Serface

unread,
Nov 20, 2008, 6:03:05 PM11/20/08
to
My favorite was the T-shirt that said "My compiler compiled yours" or
something like that.

Tom

"Leo Violette" <le...@primenet.com> wrote in message

news:O4rc%23W0SJ...@TK2MSFTNGP06.phx.gbl...

Giovanni Dicanio

unread,
Nov 20, 2008, 6:14:24 PM11/20/08
to

"Tom Serface" <tom.n...@camaswood.com> ha scritto nel messaggio
news:B796AD2B-D17C-4DD6...@microsoft.com...

> My favorite was the T-shirt that said "My compiler compiled yours" or
> something like that.

I would love to have that T-shirt :)
(I only heard about that T-shirt here in this newsgroup.)

I think that it referred to the C++ compiler that is used to compile the CLR
(which is written in native code) and the C# compiler.

Giovanni


Gary

unread,
Nov 20, 2008, 7:46:00 PM11/20/08
to

I am getting an assetion and my virtual list control is not working.
I am doing somthing wrong ?

mStringList[mItemsCount] = data;
mItemsCount++;

// Update the item count
DWORD flags = LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL;
mMyListCtrl.SetItemCountEx( mItemsCount, flags );

In the above code I get assertion at SetItemCountEx() method.........
When I looked at this method in winctrl2.cpp I see the below assertion:

// can't have dwFlags on a control that isn't virutal
ASSERT(dwFlags == 0 || (GetStyle() & LVS_OWNERDATA));

But my control is virtual I do set the extended style to LVS_OWNERDATA.

// Set extended style to full row select
DWORD exStyle = mMyListCtrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT
| LVS_EX_INFOTIP | LVS_OWNERDATA;
mMyListCtrl.SetExtendedStyle( exStyle );

Any pointers ?

Gary

"Tom Serface" wrote:

> Here's some info. Basically, you just change it to be owner drawn and add a
> GetDispInfo() handler. Then you have to supply the data for each item when
> it is requested in the callback. If you want a specific example drop me an
> email with your address and I'll send you a sample project I just worked up
> for an article I'm doing about using bitmap files as the icons in a list
> control (virtual).
>
> http://msdn.microsoft.com/en-us/library/ye4z8x58(VS.80).aspx


>
> Tom
>
> "Gary" <Ga...@discussions.microsoft.com> wrote in message

> news:8490D69D-40A3-4815...@microsoft.com...
> > Thanks Tom.
> >
> > Do you have an example of converting a CListStrl to a virtual list control
> > ?
> > Do I just need to use the flag LVS_OWNERDATA in my call to
> > setExtendedStyle() method of CListCtrl ?
> > Does setting the flag take care of making it a virtual list control ?


> >
> > Thanks,
> > Gary
> >
> > "Tom Serface" wrote:
> >

> >> I fully agree. It is so easy to set up and use it almost seems like it
> >> should be the default. It is certainly not any more trouble than setting
> >> up
> >> the normal way. And with the ability to set the number of items
> >> "virtually"
> >> as well you can even have the thumb in the scroll bar work as though the
> >> list was actually populated.
> >>
> >> Tom
> >>
> >> "AliR (VC++ MVP)" <Al...@online.nospam> wrote in message


> >> news:UUBUk.11884$Ws1...@nlpi064.nbdc.sbc.com...
> >> > Even a couple of hundred items with 2 or 3 sub items will take long
> >> > enough
> >> > that you will have to switch to virtual list mode. If you ask me
> >> > virtual
> >> > list mode should be standard on list control, they should do away with
> >> > the
> >> > normal mode.
> >> >

> >> > AliR.
> >> >
> >> >
> >> > "Serge Wautier" <se...@wautier.nospam.net> wrote in message
> >> > news:uez$7GXSJH...@TK2MSFTNGP02.phx.gbl...


> >> >>> I am not using virtual list control.....

> >> >>> I just want to keep on adding possibly millions of items at runtime
> >> >>

> >> >> Then you're out of luck. My own experience is that virtual list mode
> >> >> is
> >> >> necessary to keep the list responsive at load AND destroy time as soon
> >> >> as
> >> >> you have more than a couple thousands items.
> >> >>
> >> >> See Giovanni's answers for more details. FWIW, "owner-data" = "virtual
> >> >> list"
> >> >>
> >> >> HTH,
> >> >>
> >> >> Serge.
> >> >> http://www.apptranslator.com - Localization tool for your MFC
> >> >> applications


> >> >>
> >> >>
> >> >> "Gary" <Ga...@discussions.microsoft.com> wrote in message

> >> >> news:FCACADAD-7521-4333...@microsoft.com...


> >> >>> Hi,
> >> >>>
> >> >>> I would like to know how many items can I insert into a CListCtrl....
> >> >>> ?
> >> >>> I am not using virtual list control.....
> >> >>> I am just using CListCtrl in a form view..........
> >> >>>
> >> >>> I just want to keep on adding possibly millions of items at runtime
> >> >>> and
> >> >>> save
> >> >>> them to a text file is user wants to...........
> >> >>>
> >> >>> I don't want to load those many items..........
> >> >>>
> >> >>> InsertItem() takes "int" as parameter index......so CListCtrl should
> >> >>> atleast
> >> >>> support

> >> >>> (-2,147,483,648 to 2,147,483,647) items..........

Gary

unread,
Nov 20, 2008, 7:58:01 PM11/20/08
to
I tried setting the extended style by using SendMesage() but still it doesn't
work:

mMyListCtrl.SendMessage( LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_OWNERDATA,
LVS_OWNERDATA );

Gary

Gary

unread,
Nov 20, 2008, 8:06:01 PM11/20/08
to
My OnGetDIaspInfo() function is also straighforward:

NMLVDISPINFO * pDispInfo = (NMLVDISPINFO *)pNMHDR;
*pResult = 0;

if (pDispInfo->item.mask & LVIF_TEXT)
{
CString & parseStr = mStringList[pDispInfo->item.iItem];
if (parseStr.GetLength() > 0)
{
_tcsncpy_s( pDispInfo->item.pszText,
pDispInfo->item.cchTextMax - 1,
(LPCTSTR)parseStr,
_TRUNCATE );
}
else
{
CString txt = SafeLoadString( IDS_VIL_TEXT_ERR0 );
_tcsncpy_s( pDispInfo->item.pszText,
pDispInfo->item.cchTextMax - 1,
(LPCTSTR)txt,
_TRUNCATE );
}
}

Any pointers would be appreciated.

Gary

Gary

unread,
Nov 20, 2008, 8:48:00 PM11/20/08
to
Ok, resolved the issue by setting the Owner Data to "true" through the
Properties window, I guess that is the way to do it, setting extended style
won't work.

But now my virtual list control doesn't display anything.

I did add a method corresponding to the macro:

ON_NOTIFY_REFLECT( LVN_GETDISPINFO, OnGetItemInfo )

Do I need to do anything else ?

Gary

Gary

unread,
Nov 20, 2008, 9:11:01 PM11/20/08
to
I guess my OnGetItemInfo() function corresponding to the ON_GETDISPINFO macro
is never geting called ?

If so then why would that be happening ?

Thanks,
Gary

Tom Serface

unread,
Nov 21, 2008, 1:30:08 AM11/21/08
to
Hi Gary,

I sent you email with what I think is going on in your process. If so it
will be easy to fix. I think you need to use ON_NOTIFY() rather than
ON_NOTIFY_REFLECT() in this case. I don't think there is such a thing as
ON_GETDISPINFO, but you would use the form:

ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST1, OnGetItemInfo)

The control on the dialog will notify the dialog (where the handler lives)
when it needs data to display in a line.

As I mentioned in my email you can also add the handler in the properties
window to have it set all this up for you. You just have open the dialog,
select it, then click the little lightning bolt icon on the top of the
properties window. From there you can open the tree for the list control
and hook into all kinds of notification messages and it will set up the code
for you (at least the functions, you have to fill in what you want to do in
the functions of course).

FWIW, once you have this set up it will be really easy for you to extend it
and use this idea in other programs. It's just doggone learning curve
thing.

Hope that helps,

Tom


"Gary" <Ga...@discussions.microsoft.com> wrote in message

news:CDD2142F-71A4-41F8...@microsoft.com...

Giovanni Dicanio

unread,
Nov 21, 2008, 4:20:16 AM11/21/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:CDD2142F-71A4-41F8...@microsoft.com...

>I guess my OnGetItemInfo() function corresponding to the ON_GETDISPINFO
>macro
> is never geting called ?

It's easy to check that: just put a breakpoint in that function body, and
see if the debugger stops there.

Giovanni

Gary

unread,
Nov 21, 2008, 1:43:03 PM11/21/08
to
Thanks a lot Tom, appreciated.

I should be using ON_NOTIFY as you suggested and it does seem to work.
Sorry about ON_GETDISPINFO, it was just a typo, I meant LVS_GETDISPINFO.

One thing I observed was that the list control flickers.
I am using EnsureVisible() so that the last time is visible and it is
automatically scrolled.

Is it possible to reduce the flickering ?

Thanks,
Gary

Gary

unread,
Nov 21, 2008, 1:46:05 PM11/21/08
to
Yes.

The problem was I was using ON_NOTIFY_REFLECT when I should be using
ON_NOTIFY as Tom mentioned.

But now I see the control flickering.

Thanks,
Gary

Gary

unread,
Nov 21, 2008, 2:09:00 PM11/21/08
to
Using this reduces the flicering but still it is there.

mMyListCtrl.SendMessage( LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER);

Thanks,
Girish

Gary

unread,
Nov 21, 2008, 2:56:05 PM11/21/08
to
Just tried using LockWindowUpdate and UnLockWindowUpdate() and they seem to
do the trick along with the double buffering style. A lot less flickering.

I am doing something wrong or it is fine to use double buffering and lock
and unclock window update when I am updating my internal data storage and
updating the count in the list control using ??

mMyListCtrl.LockWindowUpdate()

mMyListCtrl.SetItemCountEx( mItemsCount, flags );

mMyListCtrl.UnLockWindowUpdate()

Thanks,
Gary

Gary

unread,
Nov 21, 2008, 4:39:01 PM11/21/08
to
Sorry to buy you guys again.

am I doing something fundamentally wrong here ?

When I minimize my application and it is still running I see that all the
icons on my desktop are flickering.

All I am doing is this below when I receive a new data item:

// Lock window update so that user doesn't see flicker as we populate
mMyListCtrl.LockWindowUpdate();

// Update the sentence list map
mStringList[mItemsCount] = sentenceData;

// Update the item count
mItemsCount++;

// Update the item count in virtual list control


DWORD flags = LVSICF_NOINVALIDATEALL | LVSICF_NOSCROLL;
mMyListCtrl.SetItemCountEx( mItemsCount, flags );

// Scroll and ensure that the last item is always visible
mMyListCtrl.EnsureVisible( mItemsCount - 1, FALSE );

// Unlock window update
mMyListCtrl.UnlockWindowUpdate();

Thanks,
Gary

Gary

unread,
Nov 21, 2008, 4:50:01 PM11/21/08
to
wow.......found out that LockWindowUpdate and UnLockWindowUpdate() are the
real culprits for all the desktop icons flickering.

Any other alternative to reduce the flickering in addition to
LVS_EX_DOUBLEBUFFER which seem to help in reducing flickering a lot.

Thanks,
Gary

"Gary" wrote:

> > > Gary

Gary

unread,
Nov 21, 2008, 5:00:05 PM11/21/08
to
I tried using SetRedraw() but it doesn't seem to help much.

To give you an idea I am adding 8-10 items per second to the ListCtrl.

Any other alternative to reduce the flickering in addition to

LVS_EX_DOUBLEBUFFER which seem to help in reducing flickering a bit.

Thanks,
Gary

Tom Serface

unread,
Nov 21, 2008, 5:06:25 PM11/21/08
to
Gary,

Since you are adding things so rapidly, what if you set a timer in your
dialog that turns on and off SetRedraw() for the list control every 2
seconds or so and that way it would not continue to draw so much. Another
idea would be to only call EnsureVisible() at that time as well. You may
also want to put in a checkbox or something that will not do the
EnsureVisible() call so users can scroll back in the text without it popping
to the end automatically.

I couldn't resist the jab on ON_GETDISPINFO... I new what you means :o)

FWIW, you'd have even more trouble with this using a non-virtual control so
you're heading down the right path.

Tom

"Gary" <Ga...@discussions.microsoft.com> wrote in message

news:5A212F51-2EE7-4F54...@microsoft.com...

Tom Serface

unread,
Nov 21, 2008, 5:09:04 PM11/21/08
to
I think you figured out that calling LockWindowUpdate()/UnlockWindowUpdate()
was causing the problem on the desktop.

Now you just need a way to throttle your output so it doesn't get refreshed
so often.

Tom

"Gary" <Ga...@discussions.microsoft.com> wrote in message

news:03A7D156-9842-48A5...@microsoft.com...

Giovanni Dicanio

unread,
Nov 21, 2008, 5:49:50 PM11/21/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:F0EB9705-E60A-4BE6...@microsoft.com...

>I tried using SetRedraw() but it doesn't seem to help much.
>
> To give you an idea I am adding 8-10 items per second to the ListCtrl.
>
> Any other alternative to reduce the flickering in addition to
> LVS_EX_DOUBLEBUFFER which seem to help in reducing flickering a bit.

To try to speed things up you may consider another way for giving text
information to the listview in response to LVN_GETDISPINFO notification.

I read from another post here that you do a deep copy of the string in the
pszTex field (using some from of "strcpy", probably _tcscpy_s) when
processing LVN_GETDISPINFO.

I would suggest to try a faster technique, i.e. passing just the *address*
of the string (and not doing a deep-copy).
In fact, if you read the documentation of NMLVDISPINFO, you can note that
pszText can also contain just a pointer to the string (and this is cheaper
than doing a string copy, in this context of optimizations to avoid
flickering):

NMLVDISPINFO Structure
http://msdn.microsoft.com/en-us/library/bb774780.aspx

<quote>
[...]
You can either copy text to the buffer or assign the address of a string to
the pszText member. In the latter case, you must not change or delete the
string until the corresponding item text is deleted or two additional
LVN_GETDISPINFO messages have been sent.
</quote>

Giovanni


Tom Serface

unread,
Nov 21, 2008, 5:58:22 PM11/21/08
to
Hi G,

That is a great idea for Gary to try, but he may find out that the flicker
is because it is updating too fast rather than the opposite. I think the
control is just scrolling quickly and always pinning it to the bottom makes
a lot of calls to EnsureVisible() happen (I think he said as many as 10 a
second).

Tom

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message

news:OSCMKvCT...@TK2MSFTNGP04.phx.gbl...

Giovanni Dicanio

unread,
Nov 21, 2008, 6:20:34 PM11/21/08
to

"Tom Serface" <tom.n...@camaswood.com> ha scritto nel messaggio
news:AD3BBE0D-1E6C-4A20...@microsoft.com...

> That is a great idea for Gary to try

Thanks Tom.

>, but he may find out that the flicker

Another idea that is popping in my mind is the use of CMemDC to avoid the
flickering (again, I did not verify that with code, but the OP may give it a
try):

http://www.codeproject.com/KB/GDI/flickerfree.aspx

Giovanni Dicanio

unread,
Nov 21, 2008, 6:29:46 PM11/21/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:B78E3431-4892-4DE1...@microsoft.com...

> But now I see the control flickering.

You may want to try using CMemDC:

http://www.codeproject.com/KB/GDI/flickerfree.aspx
http://www.codeproject.com/KB/GDI-plus/what_is_a_basename_.aspx


Giovanni

Giovanni Dicanio

unread,
Nov 21, 2008, 6:31:05 PM11/21/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:B78E3431-4892-4DE1...@microsoft.com...

> But now I see the control flickering.

You may want to try using CMemDC:

Gary

unread,
Nov 21, 2008, 6:50:06 PM11/21/08
to
Yes, I m using it in my base class.

I am using a base class:

EnhancedList mMyCListCtrl;

In the EnhancedList class I am using CMemDC class to do paint OnPaint() and
OnSize() for memory device context.

Do I need to again use OnPaint() method in my derived class to use CMemDC ?

Thanks,
Gary

Gary

unread,
Nov 21, 2008, 8:30:01 PM11/21/08
to
I tried the timer for redrawing and EnsureVisible() but it won't be feasible
in my case as the redraw(2 seconds) will always be lagging behind the latest
count of items I will be adding (every second) to the list control.

Now I put the SetRedraw() at strategic places(disable before adding new set
of items received in 1 second and enable after adding new set of items) and
it seems to be working much better.

I did put a check box for user to disable/enable auto scrolling.
Also planning to disable auto scrolling when a user clicks/select an item in
the list control.

Giovanni Dicanio

unread,
Nov 22, 2008, 4:24:03 AM11/22/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:5441A19F-2D28-4F04...@microsoft.com...

> Yes, I m using it in my base class.
>
> I am using a base class:
>
> EnhancedList mMyCListCtrl;
>
> In the EnhancedList class I am using CMemDC class to do paint OnPaint()
> and
> OnSize() for memory device context.
>
> Do I need to again use OnPaint() method in my derived class to use CMemDC
> ?

I don't know what your code exactly is, but If the derived class somehow
calls the base class implementation, you don't need to repeat the CMemDC
code in the derived class.
However, what is important is that whoever does the painting (in this case
the derived class) is actually painting to a *memory DC* (kind of
back-buffer in double-buffering terminology) and not to the front buffer
(main DC).

BTW: I think that if your architecture consists in deriving a class from
CListCtrl, you may consider the "reflected" version of the notification
(LVN_...), such that you can proper group that code in the CListCtrl derived
class instead of scattering it between the dialog class and the derived
class.

Giovanni

Gary

unread,
Nov 22, 2008, 2:45:01 PM11/22/08
to

I am not calling OnPaint() in my mMyListCtrl class....which is derived from
EnhancedListCtrl class where I am using MemDC.........

But in my class I am using an Object and not actually directly deriving from
the base class in a form view.

So my class derives from FormView and I define the object in the derived
class............like below:
class MyDataControl : public FormView
{
EnhancedListCtrl mMyListCtrl;
}

So I am not calling OnPaint() in MyDataControl.

-Gary

Gary

unread,
Nov 22, 2008, 2:49:01 PM11/22/08
to
Also I cannot use the reflected notification as Tom pointed out earlier.
So I had to use LVN_NOTIFY instead of LVN_..._REFLECT

Gary

Gary

unread,
Nov 22, 2008, 7:31:01 PM11/22/08
to

One related question:

I want to determine when a user click on an item in my list control and I
want to stop scrolling at the time.

How to determine if a user clicked on my list control ?

I don't see any funtions in CListCtrl() for the same.

Thanks,
Gary

Gary

unread,
Nov 22, 2008, 7:52:00 PM11/22/08
to
Got it.

Capturing ON_NOTIFY( NM_CLICK) to determine click in my list control.

Gary

Giovanni Dicanio

unread,
Nov 23, 2008, 3:56:45 AM11/23/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:1E4C25A6-EFB9-40B3...@microsoft.com...

> Also I cannot use the reflected notification as Tom pointed out earlier.
> So I had to use LVN_NOTIFY instead of LVN_..._REFLECT

I don't know what Tom exactly wrote, but I think that Tom must have meant
something different...

I believe that the LVN_GETDISPINFO notification can be handled by the parent
window (e.g. dialog box) or it can be reflected back to the listview
control.
And this second way (reflected to listview) is preferred if you want to pack
all the listview management code in a CListCtrl derived class, as it seems
to me you are going to do.

Giovanni

Giovanni Dicanio

unread,
Nov 23, 2008, 6:55:08 AM11/23/08
to

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> ha scritto nel
messaggio news:u8SzQmUT...@TK2MSFTNGP05.phx.gbl...

I've just verified with a simple test with VS2008 that LVN_GETDISPINFO can
be used in its reflected form and handled inside the CListCtrl-derived
class.

Giovanni

Giovanni Dicanio

unread,
Nov 23, 2008, 7:24:41 AM11/23/08
to

"Tom Serface" <tom.n...@camaswood.com> ha scritto nel messaggio
news:AD3BBE0D-1E6C-4A20...@microsoft.com...

> That is a great idea for Gary to try, but he may find out that the flicker
> is because it is updating too fast rather than the opposite. I think the
> control is just scrolling quickly and always pinning it to the bottom
> makes a lot of calls to EnsureVisible() happen (I think he said as many as
> 10 a second).

Hi Tom,

I think that 10 updates per seconds are few :)

I tried 100 updates in less than a second, and using the technique of
painting to a CMemDC (as I posted above), I have zero flickering.

I belive the key here is to use CMemDC as described here:

http://69.10.233.10/KB/GDI-plus/what_is_a_basename_.aspx

The handlers for WM_ERASEBACKGROUND, WM_PAINT and WM_SIZE for a class I
derived from CListCtrl are like these:

<code>
BOOL CMyListCtrl::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default

UNUSED_ALWAYS(pDC);

// return CListCtrl::OnEraseBkgnd(pDC);

return TRUE;
}

void CMyListCtrl::OnSize(UINT nType, int cx, int cy)
{
CListCtrl::OnSize(nType, cx, cy);

GetClientRect(m_rectClient);

CHeaderCtrl* pHC;
pHC = GetHeaderCtrl();
if (pHC != NULL)
{
CRect rectHeader;
pHC->GetItemRect( 0, &rectHeader );
m_rectClient.top += rectHeader.bottom;
}
}

void CMyListCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting

// Paint to a memory device context to reduce screen flicker.
CodeProject::CMemDC memDC(&dc, &m_rectClient);

// Let the window do its default painting...
CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 );
}

</code>

Note that I used a custom CodeProject:: namespace above, because it seems
that VS2008 SP1 (ex Feature pack) defines a new CMemDC class (but I wanted
to use the CodeProject's one).

I use also a LVN_GETDISPINFO notification in is reflected form, such that it
can be handled in the CListCtrl-derived class, and the body of this handler
is something like this:

<code>
void CMyListCtrl::OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO*>(pNMHDR);
*pResult = 0;

if (pDispInfo->item.iItem < 0 ||
pDispInfo->item.iItem >= GetDB()->Count())
{
return; // requesting invalid item
}

if (pDispInfo->item.mask & LVIF_TEXT) {
const Database::Record * pRec =
GetDB()->GetAt(pDispInfo->item.iItem);

LPCTSTR pszResult = TEXT("");
switch (pDispInfo->item.iSubItem)
{
case COL_NAME: pszResult = pRec->Name.GetString();
break;
case COL_SURNAME: pszResult = pRec->Surname.GetString();
break;
case COL_CITY: pszResult = pRec->City.GetString();
break;
}
pDispInfo->item.pszText = const_cast<LPTSTR>(pszResult);
}

if (pDispInfo->item.mask & LVIF_IMAGE) {
pDispInfo->item.iImage = -1;
}

if (pDispInfo->item.mask & LVIF_STATE) {
pDispInfo->item.state = 0;
}
}

</code>

G

Giovanni Dicanio

unread,
Nov 23, 2008, 10:56:39 AM11/23/08
to

"Gary" <Ga...@discussions.microsoft.com> ha scritto nel messaggio
news:1E4C25A6-EFB9-40B3...@microsoft.com...

> Also I cannot use the reflected notification as Tom pointed out earlier.
> So I had to use LVN_NOTIFY instead of LVN_..._REFLECT

Gary:

this thread became too much nested and complex to follow, at least for me.

So, I opened up a new thread with subject "Owner-data listview without
flickering".

I show there that you can use the reflected LVN_GETDISPINFO notification,
and that you can use CMemDC to avoid flickering.

You may want to follow up on the new thread.

Quick links here:

[...]
The exe (with MFC statically linked) can be downloaded here:
http://www.geocities.com/giovanni.dicanio/vc/TestVirtualListView_EXE.zip


The source code can be downloaded here:
http://www.geocities.com/giovanni.dicanio/vc/TestVirtualListView_SRC.zip


HTH,
Giovanni


Tom Serface

unread,
Dec 2, 2008, 1:23:31 PM12/2/08
to
Hi G,

You are correct that it depends on where the GetDispInfo() function is
located. I typically handle it in the dialog because I don't create
specialized versions of the control (don't derive a class) and it just seems
more straightforward. Plus, I don't like giving the control access to data
outside of it. This is when the control is in a dialog of course, not when
a listview is being used. I never use a CListView since I almost always
need other controls on the dialog so a CFormView makes more sense.

I'm not sure about "the preferred" method, but my preferred method is to let
the CFormView handle the data and return the values to the control.

Tom

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message

news:uVJx6JWT...@TK2MSFTNGP04.phx.gbl...

Tom Serface

unread,
Dec 2, 2008, 1:25:35 PM12/2/08
to
I've never tried the CMemDC method so I can't comment, but I'm glad it
worked for him. I've never noticed any annoying flicker either so I
probably would try to get rid of it if I were writing that often to my list
control. This is useful information for that eventuality.

Tom

"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message

news:eQSkEaWT...@TK2MSFTNGP03.phx.gbl...

AliR (VC++ MVP)

unread,
Dec 2, 2008, 4:00:29 PM12/2/08
to
CMemDC is pretty cool. It is simply an extention of CDC that automatically
creates a bitmap and selects it into the memory dc, and when the destructor
is called it bitblts it content onto the original dc.

http://www.codeproject.com/KB/GDI/flickerfree.aspx

AliR.


"Tom Serface" <tom.n...@camaswood.com> wrote in message
news:C121425E-5320-4180...@microsoft.com...

0 new messages