Board index » cppbuilder » Re: ListView with 40,000+ items is really SLOW on P4 3GHz

Re: ListView with 40,000+ items is really SLOW on P4 3GHz


2004-04-27 11:27:57 PM
cppbuilder100
On Tue, 27 Apr 2004 14:47:04 +0100, Mark Jacobs wrote:
Quote
I've just tried virtual listview with checkboxes, and it draws the gap for the checkbox, but there is no
control rendered there.
Huh? that much I had a chance to try myself (I wanted to see what happened
when you clicked on it) and it drew the check box just fine. Of course
nothing did happen when I clicked on it.
But I've just done a further google and it looks like you'll have to resort
to OwnerDraw and probably also OnMouseDown/Up. What a PITA.
--
Andrue Cope
[Bicester UK]
 
 

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

On Tue, 27 Apr 2004 14:47:04 +0100, Mark Jacobs wrote:
Further note:Although the checkbox is drawn I tried setting ::Checked to
true in the OnData handler but the check didn't appear. So it does like
you'll have to:
* OnMouseDown make a note if the cursor is within the check box.
* OnMouseUp verify cursor is still within the same checkbox.
* OnClick if the cursor was within the box according to OnMouseDown/Up
toggle the checked state for that item in your 'database' or whereever
OnData gets its data from.
* Use OwnerDraw to draw the check itself.
It's not excessively difficult but certainly a PITA. You might want to try
a search for alternative third party list views. Someone's probably done
all this already :)
BTW:I'm using BCB6 - are you using something earlier?
--
Andrue Cope
[Bicester UK]
 

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

"Mark Jacobs" < XXXX@XXXXX.COM >wrote in
message news: XXXX@XXXXX.COM ...
Quote
When the user clicks a checkbox on the visible part of the
ListView, how do I know :-
1) Whether they clicked a checkbox, or just the caption?
You will have to calculate that manually. Have a look at the
TListView::GetHitTestInfoAt() method.
Quote
2) Did they activate or deactivate the check?
In your stored structure, include a bool for the current check state, and
then simply toggle it when you detect a click within the visible checkbox.
In the OnData event, set the Item's Checked property to the current value of
the bool.
Quote
3) Which item did they click?
Look at the TListView::GetItemAt() method. Best to use with the OnMouse...
events since they provide coordinates for the clicking. If you want to use
a different event (OnChange, OnClick, etc), then you will have to calculate
the click coordinates manually.
Gambit
 

{smallsort}

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

"Mark Jacobs" < XXXX@XXXXX.COM >wrote in
message news: XXXX@XXXXX.COM ...
Quote
however, there is no "clean" way to programmatically
detect when someone changes a checkbox
Sure there is:
void __fastcall TForm1::ListView1MouseDown(TObject* Sender, TMouseButton
Button, TShiftState Shift, int X, int Y)
{
if( Button == mbLeft )
{
if( ListView1->GetHitTestInfoAt(X, Y).Contains(htOnStateIcon) )
{
// clicking on the check box, do something to toggle the
check...
TListItem *Item = ListView1->GetItemAt(X, Y);
if( Item )
{
MyStructure &ItemInfo = MyStorage[Item->Index];
ItemInfo.Checked = !ItemInfo.Checked;
ListView1->UpdateItems(Item->Index, Item->Index);
}
}
}
}
Alternatively:
void __fastcall TForm1::ListView1MouseDown(TObject* Sender, TMouseButton
Button, TShiftState Shift, int X, int Y)
{
if( Button == mbLeft )
{
LV_HITTESTINFO Info = {0};
Info.pt = Point(X, Y);
int Index = ListView_HitTest(ListView1->Handle, &Info);
if( (Index != -1) && (Info.flags & LVHT_ONITEMSTATEICON) )
{
// clicking on the check box, do something to toggle the
check...
MyStructure &ItemInfo = MyStorage[Index];
ItemInfo.Checked = !ItemInfo.Checked;
ListView1->UpdateItems(Index, Index);
}
}
}
Gambit
 

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

"Andrue Cope" < XXXX@XXXXX.COM >wrote in message
Quote
Of course nothing did happen when I clicked on it.
You probably weren't updating the TListItem::Checked property in the OnData
event. *EVERY* aspect of an item's information, other than its index, must
be provided by the OnData event. That includes the checkbox state.
Quote
But I've just done a further google and it looks like you'll have
to resort to OwnerDraw and probably also OnMouseDown/Up.
OwnerDraw is not needed.
Gambit
 

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

On Tue, 27 Apr 2004 08:49:11 -0700, Remy Lebeau (TeamB) wrote:
Quote
You probably weren't updating the TListItem::Checked property in the OnData
event. *EVERY* aspect of an item's information, other than its index, must
be provided by the OnData event. That includes the checkbox state.
Nope, I went back and tried that to no avail.
Quote
OwnerDraw is not needed.
I sure hope so for Mark's sake.
--
Andrue Cope
[Bicester UK]
 

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

So far, with your kind help, I have now loaded all the files on hard disk into the ListView in double-quick
time. Yep, I'm happy with this. OK dudes - I'm using BCB v5 with the patch. Perhaps this is why I do not see
any checkbox on an OwnerData ListView with CheckBoxes=true; . If so, is there a way to draw it on the Canvas
of the ListView's Item? Current salient code :-
typedef struct LVRECORD
{
char fnm[MAXPATH],att[5],foutxt[31];
unsigned long fage,fbig,fouwh,foulg;
bool chkd;
}
lvrec;
// Yes, it allocates a big wadge of memory, but this is just for testing ..
lvrec mjlv[250000];
void __fastcall TForm1::ListView1Data(TObject *Sender, TListItem *Item)
{
AnsiString dtdsp=FileDateToDateTime(mjlv[Item->Index].fage).DateTimeString();
Item->Caption=mjlv[Item->Index].fnm;
Item->Checked=mjlv[Item->Index].chkd;
if (Item->SubItems->Count>0) Item->SubItems->Strings[0]=dtdsp;
else Item->SubItems->Append(dtdsp);
dtdsp=mjfmtnm(mjlv[Item->Index].fbig);
if (Item->SubItems->Count>1) Item->SubItems->Strings[1]=dtdsp;
else Item->SubItems->Append(dtdsp);
dtdsp=AnsiString(mjlv[Item->Index].att);
if (Item->SubItems->Count>2) Item->SubItems->Strings[2]=dtdsp;
else Item->SubItems->Append(dtdsp);
}
The hit test for the check box would be great, *IF* I could see a checkbox. However, the code is still useful
for the non-OwnerData version of my app. Many thanks so far - any ideas about these invisible checkboxes and
BCB5 would be greatly appreciated. TIA,
--
Mark Jacobs
DK Computing
www.dkcomputing.co.uk
XXXX@XXXXX.COM
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Mark Jacobs" < XXXX@XXXXX.COM >wrote in
message news: XXXX@XXXXX.COM ...

>When the user clicks a checkbox on the visible part of the
>ListView, how do I know :-
>1) Whether they clicked a checkbox, or just the caption?

You will have to calculate that manually. Have a look at the
TListView::GetHitTestInfoAt() method.

>2) Did they activate or deactivate the check?

In your stored structure, include a bool for the current check state, and
then simply toggle it when you detect a click within the visible checkbox.
In the OnData event, set the Item's Checked property to the current value of
the bool.

>3) Which item did they click?

Look at the TListView::GetItemAt() method. Best to use with the OnMouse...
events since they provide coordinates for the clicking. If you want to use
a different event (OnChange, OnClick, etc), then you will have to calculate
the click coordinates manually.


Gambit


 

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

"Mark Jacobs" < XXXX@XXXXX.COM >wrote in
message news: XXXX@XXXXX.COM ...
Quote
is there a way to draw it on the Canvas of the ListView's Item?
Use one of the On...Draw... events for that. Alternatively, make your own
checkbox images, put them into a TImageList, assign the ImageList to the
ListView's SmallImages property, and then fill in the TListItem::StateIndex
property in the OnData event.
Gambit
 

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

On Tue, 27 Apr 2004 17:18:14 +0100, Mark Jacobs wrote:
Quote
If so, is there a way to draw it on the Canvas
of the ListView's Item?
You can draw anything you want using TListView::Canvas so I suppose you can
draw a rectangle of the correct size/shape/colour but I hope you don't have
to go that route.
More likely you can send a message to the list box. This might also be the
way to resolve the issue on my machine where I get the box but can't make a
check appear in it. Not that I've played with it much but it doesn't look
good should I ever need to do this :(
Hopefully Remy (who's a lot more knowledgeable on VCL/API matters) can
confirm this.
--
Andrue Cope
[Bicester UK]
 

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

I have now got my checkboxes working. I used the StateImages and StateIndex properties to achieve this, and
now I can choose exactly how I'd like my checkboxes to appear. Thanks again - I think this topic can now be
finally closed. Please contact me if you want any BCB5 code samples for OwnerData ListViews. (I love this
newsgroup!!)
--
Mark Jacobs
DK Computing
www.dkcomputing.co.uk
XXXX@XXXXX.COM
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Mark Jacobs" < XXXX@XXXXX.COM >wrote in
message news: XXXX@XXXXX.COM ...

>is there a way to draw it on the Canvas of the ListView's Item?

Use one of the On...Draw... events for that. Alternatively, make your own
checkbox images, put them into a TImageList, assign the ImageList to the
ListView's SmallImages property, and then fill in the TListItem::StateIndex
property in the OnData event.


Gambit


 

Re:Re: ListView with 40,000+ items is really SLOW on P4 3GHz

Mark
TLisTView is notoriously slow with large datasets. You need to make it
a virtual listview. Look into the property 'OwnerData'
David