Board index » cppbuilder » SubItemImages

SubItemImages


2006-09-06 06:36:29 PM
cppbuilder17
Hi,
I have a TListView in which I want to put a different symbol in each row
of one of the subitem columns, drawn in a different colour. The only way
I can seem to achieve this is by doing it in the CustomDrawSubItem event
like this:
//---------------------------------------------------------------------------
void __fastcall TP12DXF::RecordsCustomDrawSubItem(TCustomListView *Sender,
TListItem *Item, int SubItem, TCustomDrawState State, bool
&DefaultDraw)
{
DefaultDraw = false;
TListView *L = (TListView*)Sender;
TPoint p = Item->GetPosition();
p.x = 5;
for(int i=0; i<SubItem; i++)
p.x += L->Column[i]->Width;
SubItem--;
L->Canvas->Brush->Color = clWhite;
L->Canvas->Pen->Color = clWhite;
L->Canvas->FloodFill(p.x, p.y, p.x + L->Column[SubItem]->Width - 1,
L->Canvas->TextHeight("X"));
L->Canvas->Pen->Color = clBlack;
if(SubItem == SYMBOL)
{
SymbolList->BkColor = Colour[parms.record[Item->Index].colour];
SymbolList->Draw(L->Canvas, p.x, p.y,
parms.record[Item->Index].symbol, dsNormal, itImage, true);
}
else if(SubItem == SYMBOL_SIZE)
L->Canvas->TextOut(p.x, p.y, parms.record[Item->Index].symbol_size);
else if(SubItem == LABEL_SIZE)
L->Canvas->TextOut(p.x, p.y, parms.record[Item->Index].label_size);
else if(SubItem == LABEL_POS)
L->Canvas->TextOut(p.x, p.y,
LabelPosition[parms.record[Item->Index].label_pos]);
else if(SubItem == LABEL_INT)
L->Canvas->TextOut(p.x, p.y, parms.record[Item->Index].label_int);
else if(SubItem == LAYER)
L->Canvas->TextOut(p.x, p.y,
LayerName[parms.record[Item->Index].layer]);
strcpy(LayerName[0], Item->Caption.c_str());
}
//---------------------------------------------------------------------------
However, this updates VERY slowly. Is there not a way of doing this
using the SubItemImages property?
Paul
 
 

Re:SubItemImages

"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
Quote
However, this updates VERY slowly. Is there not a way of doing this
using the SubItemImages property?
Simply assign a TImageList to the TListView::SmallImages property, and then
set the TListItem::SubItemImages property to the desired indexes.
Gambit
 

Re:SubItemImages

Hi,
When I try this I get an image in the first column when the row is
highlighted (in fact I dont want any image in the first column), but do
not get any image in the column I want. I am trying this:
...
Records->Items->Item[i]->SubItemImages[1] = parms.record[i].symbol;
...
Could it be something to do with the masking? I have tried all
combinations of settings but am getting nowhere!
Paul
Remy Lebeau (TeamB) wrote:
Quote

Simply assign a TImageList to the TListView::SmallImages property, and then
set the TListItem::SubItemImages property to the desired indexes.

 

{smallsort}

Re:SubItemImages

Another thing I have noticed in trying to solve this problem is that the
OnGetSubItemImage event is not being triggered - could this be related?
Paul
Remy Lebeau (TeamB) wrote:
Quote
"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
news:44fea45f$ XXXX@XXXXX.COM ...

>However, this updates VERY slowly. Is there not a way of doing this
>using the SubItemImages property?

Simply assign a TImageList to the TListView::SmallImages property, and then
set the TListItem::SubItemImages property to the desired indexes.


Gambit


 

Re:SubItemImages

I have found the problem: if the TListView has checkboxes then the
SubItemImages are not displayed.
Is there a way around this?
Paul
Remy Lebeau (TeamB) wrote:
Quote
"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
news:44fea45f$ XXXX@XXXXX.COM ...

>However, this updates VERY slowly. Is there not a way of doing this
>using the SubItemImages property?

Simply assign a TImageList to the TListView::SmallImages property, and then
set the TListItem::SubItemImages property to the desired indexes.


Gambit


 

Re:SubItemImages

"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
Quote
I have found the problem: if the TListView has checkboxes
then the SubItemImages are not displayed.
What you describe is caused by a bug (or intentionally design?) in the
ComCtrls unit, specifically in the ResetExStyles() method of
TCustomListView, that does not allow the LVS_EX_SUBITEMIMAGES and
LVS_EX_CHECKBOXES styles to be active at the same time. There are only two
workarounds:
1) set the CheckBoxes property to false (so that SubItemImages will work)
and then use your own TImageList for the StateImages property to manage the
checkbox images manually.
2) disable runtime packages in your project (if you have not already done
so), then add ComCtrls.pas to your project, and then change this line:
if FCheckboxes then Styles := LVS_EX_CHECKBOXES;
To this instead:
if FCheckboxes then Styles := Styles or LVS_EX_CHECKBOXES;
Gambit
 

Re:SubItemImages

Thanks for your help. I have in fact already gone for option 1) below
which works fine.
Paul
Remy Lebeau (TeamB) wrote:
Quote

What you describe is caused by a bug (or intentionally design?) in the
ComCtrls unit, specifically in the ResetExStyles() method of
TCustomListView, that does not allow the LVS_EX_SUBITEMIMAGES and
LVS_EX_CHECKBOXES styles to be active at the same time. There are only two
workarounds:

1) set the CheckBoxes property to false (so that SubItemImages will work)
and then use your own TImageList for the StateImages property to manage the
checkbox images manually.

 

Re:SubItemImages

Hello,
I cannot seem to display a TListView subitem image using:
for(int i=0; i<NumR; i++)
{
TListItem *I = ReceiverList->Items->Add();
I->Caption = "Line " + (AnsiString)receiver[i].linenum + " Receiver " +
(AnsiString)receiver[i].num + " index " +
(AnsiString)AlphaNum[receiver[i].ndx];
I->ImageIndex = 0;
I->Checked = true;
I->SubItems->Add(" ");
I->SubItemImages[0] = 1;
}
The style is vsReport, I have 2 images in the SmallImages list and no
problem displaying them as the listviw main item image.
Paul
 

Re:SubItemImages

"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
Quote
I cannot seem to display a TListView subitem image using:
<snip>
Works fine for me exactly as you have shown it. Which version of BCB are
you using? When exactly are you calling that code in your project?
Gambit
 

Re:SubItemImages

I am using BCB 6.
The code I posted is a check to see if the image shows - there is nothing
else relevant.
I was hoping to see an image - the seconf in the list - in the second column
of the TList View, but nothing appears. I wonder if if have an incorrect
setting in the published parameters for the TList View but everything else
works fine.
Paul
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
news:481f2886$ XXXX@XXXXX.COM ...

>I cannot seem to display a TListView subitem image using:
<snip>

Works fine for me exactly as you have shown it. Which version of BCB are
you using? When exactly are you calling that code in your project?


Gambit

 

Re:SubItemImages

"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
Quote
I am using BCB 6.
That is the same version I tested your code in, and it worked fine for me.
The images showed up as expected in both columns. How do you have the
ListView and TImageList properties configured?
Quote
The code I posted is a check to see if the image shows - there
is nothing else relevant.
Again, WHEN do you call the code, though?
Gambit
 

Re:SubItemImages

I am calling this code in one of the the list's popup menuitem click events.
I really don't know which of the listview properties could impact on this so
I have attached screen dumps of the properties in the attachments group
under
TListView SubitemImages problem
Paul
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>I am using BCB 6.

That is the same version I tested your code in, and it worked fine for me.
The images showed up as expected in both columns. How do you have the
ListView and TImageList properties configured?

>The code I posted is a check to see if the image shows - there
>is nothing else relevant.

Again, WHEN do you call the code, though?


Gambit


 

Re:SubItemImages

"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
Quote
I really don't know which of the listview properties could impact
on this
You have the ListView's CheckBoxes property set to true. That won't work in
this situation because there is a known bug in TListView that prevents
subimages (and infotips) from working property when the CheckBoxes property
is true. If you need to use checkboxes and subimages together, then you
will have to set the CheckBoxes property to false (and stop using the
TListItem::Checked property), then put your own checkbox images into a
TImageList that is assigned to the ListView's StateImages property, and then
use the TListItem::StateIndex property to "toggle" an item's checkbox on/off
in the OnMouse... events, ie:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Graphics::TBitmap *bmp = new Graphics::TBitmap;
bmp->Width = 16;
bmp->Height = 16;
RECT r = Rect(0, 0, 16, 16);
DrawFrameControl(bmp->Canvas->Handle, &r, DFC_BUTTON,
DFCS_BUTTONCHECK);
CheckBoxesImageList->Add(bmp, NULL);
DrawFrameControl(bmp->Canvas->Handle, &r, DFC_BUTTON,
DFCS_BUTTONCHECK | DFCS_CHECKED);
CheckBoxesImageList->Add(bmp, NULL);
delete bmp;
}
{
...
for(int i = 0; i < NumR; ++i)
{
TListItem *I = ReceiverList->Items->Add();
I->Caption = "Line " + AnsiString(receiver[i].linenum) + "
Receiver " + AnsiString(receiver[i].num) + " index " +
AnsiString(AlphaNum[receiver[i].ndx]);
I->ImageIndex = 0;
I->StateIndex = 1; // I->Checked = true;
I->SubItems->Add(" ");
I->SubItemImages[0] = 1;
}
...
}
void __fastcall TForm1::ReceiverListMouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if( Button == mbLeft )
{
THitTests ht = ReceiverList->GetHitTestInfoAt(X, Y);
if( ht.Contains(htOnStateIcon) )
{
TListItem *I = ReceiverList->GetItemAt(X, Y);
if( I )
I->StateIndex = !I->StateIndex;
}
}
}
Gambit
 

Re:SubItemImages

Aaahh, many thanks!
Paul
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

"Paul Dowd" < XXXX@XXXXX.COM >wrote in message
news:48207079$ XXXX@XXXXX.COM ...

>I really don't know which of the listview properties could impact
>on this

You have the ListView's CheckBoxes property set to true. That won't work
in this situation because there is a known bug in TListView that prevents
subimages (and infotips) from working property when the CheckBoxes
property is true. If you need to use checkboxes and subimages together,
then you will have to set the CheckBoxes property to false (and stop using
the TListItem::Checked property), then put your own checkbox images into a
TImageList that is assigned to the ListView's StateImages property, and
then use the TListItem::StateIndex property to "toggle" an item's checkbox
on/off in the OnMouse... events, ie:

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Graphics::TBitmap *bmp = new Graphics::TBitmap;
bmp->Width = 16;
bmp->Height = 16;
RECT r = Rect(0, 0, 16, 16);

DrawFrameControl(bmp->Canvas->Handle, &r, DFC_BUTTON,
DFCS_BUTTONCHECK);
CheckBoxesImageList->Add(bmp, NULL);

DrawFrameControl(bmp->Canvas->Handle, &r, DFC_BUTTON,
DFCS_BUTTONCHECK | DFCS_CHECKED);
CheckBoxesImageList->Add(bmp, NULL);

delete bmp;
}

{
...
for(int i = 0; i < NumR; ++i)
{
TListItem *I = ReceiverList->Items->Add();
I->Caption = "Line " + AnsiString(receiver[i].linenum) + "
Receiver " + AnsiString(receiver[i].num) + " index " +
AnsiString(AlphaNum[receiver[i].ndx]);
I->ImageIndex = 0;
I->StateIndex = 1; // I->Checked = true;
I->SubItems->Add(" ");
I->SubItemImages[0] = 1;
}
...
}

void __fastcall TForm1::ReceiverListMouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if( Button == mbLeft )
{
THitTests ht = ReceiverList->GetHitTestInfoAt(X, Y);
if( ht.Contains(htOnStateIcon) )
{
TListItem *I = ReceiverList->GetItemAt(X, Y);
if( I )
I->StateIndex = !I->StateIndex;
}
}
}


Gambit