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
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
> 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
> 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
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.
"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..........
> 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
"AliR (VC++ MVP)" <Al...@online.nospam> wrote in message
news:UUBUk.11884$Ws1...@nlpi064.nbdc.sbc.com...
Tom
"Gary" <Ga...@discussions.microsoft.com> wrote in message
news:FCACADAD-7521-4333...@microsoft.com...
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
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
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
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
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
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
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
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
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...
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...
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.
My email is girish...@hotmail.com
Also if it possible for you to convert it to VS 2005 ?
Thanks,
Gary
> 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
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
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..........
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...
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
"Leo Violette" <le...@primenet.com> wrote in message
news:upWocyjS...@TK2MSFTNGP03.phx.gbl...
Tom
"Gary" <Ga...@discussions.microsoft.com> wrote in message
news:3E49EC80-1886-4C68...@microsoft.com...
Tom
"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message
news:%23f7ehXo...@TK2MSFTNGP05.phx.gbl...
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
"Gary" <Ga...@discussions.microsoft.com> wrote in message
news:B1B90527-D44A-4391...@microsoft.com...
Tom
"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message
news:eX7XVPpS...@TK2MSFTNGP03.phx.gbl...
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...
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
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...
>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
// 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...
"Tom Serface" <tom.n...@camaswood.com> wrote in message
news:FD240F87-AA22-4C1B...@microsoft.com...
> 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
>
> "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
>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)
*****
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
:o)
Tom
"Leo Violette" <le...@primenet.com> wrote in message
news:%23yQyF4w...@TK2MSFTNGP06.phx.gbl...
Tom
"Joseph M. Newcomer" <newc...@flounder.com> wrote in message
news:fj2bi45eth60qlqbm...@4ax.com...
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...
LOL! Absolutely! I remember that tooltip!
"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message
news:eBL1syxS...@TK2MSFTNGP03.phx.gbl...
"Tom Serface" <tom.n...@camaswood.com> wrote in message
news:88D41D28-0539-4CDE...@microsoft.com...
Tom
"Leo Violette" <le...@primenet.com> wrote in message
news:O4rc%23W0SJ...@TK2MSFTNGP06.phx.gbl...
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
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..........
mMyListCtrl.SendMessage( LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_OWNERDATA,
LVS_OWNERDATA );
Gary
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
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
If so then why would that be happening ?
Thanks,
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...
It's easy to check that: just put a breakpoint in that function body, and
see if the debugger stops there.
Giovanni
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
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
mMyListCtrl.SendMessage( LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER);
Thanks,
Girish
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
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
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
Any other alternative to reduce the flickering in addition to
LVS_EX_DOUBLEBUFFER which seem to help in reducing flickering a bit.
Thanks,
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...
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...
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
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...
> 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):
> 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
> But now I see the control flickering.
You may want to try using CMemDC:
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
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.
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
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
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
Capturing ON_NOTIFY( NM_CLICK) to determine click in my list control.
Gary
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
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
> 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
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
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
"Giovanni Dicanio" <giovanniD...@REMOVEMEgmail.com> wrote in message
news:eQSkEaWT...@TK2MSFTNGP03.phx.gbl...
http://www.codeproject.com/KB/GDI/flickerfree.aspx
AliR.
"Tom Serface" <tom.n...@camaswood.com> wrote in message
news:C121425E-5320-4180...@microsoft.com...