Board index » cppbuilder » Customdraw is confusing me

Customdraw is confusing me


2006-10-22 12:24:26 PM
cppbuilder102
I have the following code that creates a progressbar in a
listview column. When I select any of the rows, the area with
the progressbar seems to stay white. If I click on the progress
bar itself, nothing happens. I really don't know where to look
anymore.
Here is the code that I am using. I am just testing by using a
button to insert the progressbar into the listview.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int pbColumnIndex = 1;
int pbMax = 100;
TRect pbRect;
TListItem* li = ListView1->Items->Add();
li->Caption = "Item " + IntToStr(ListView1->Items->Count);
//create a ProgressBar and place it in the second column
TProgressBar* pb = new TProgressBar(this);
pb->Parent = ListView1;
li->Data = pb;
pbRect = li->DisplayRect(drBounds);
pbRect.Left = pbRect.Left + ListView1->Columns->Items[-1+pbColumnIndex]->Width;
pbRect.Right = pbRect.Left + ListView1->Columns->Items[pbColumnIndex]->Width;
pb->Top = pb->Top - (pb->BoundsRect.Bottom - pb->BoundsRect.Top);
pb->BoundsRect = pbRect;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListView1AdvancedCustomDrawItem(TCustomListView *Sender,
TListItem *Item, TCustomDrawState State, TCustomDrawStage Stage,
bool &DefaultDraw)
{
DefaultDraw = true;
if(Stage == cdPostPaint)
{
RECT ItemRect;
RECT LineRect;
ItemRect = Item->DisplayRect(true);
LineRect = Item->DisplayRect(false);
HDC hDC = Sender->Canvas->Handle;
COLORREF clBackground = GetSysColor(COLOR_WINDOW);
COLORREF clText = GetSysColor(COLOR_WINDOWTEXT);
if(State.Contains(cdsSelected))
{
clBackground = GetSysColor(COLOR_BTNFACE);
clText = GetSysColor(COLOR_WINDOWTEXT);
DrawFocusRect(hDC, &LineRect);
}
}
}
Something seems to be wrong somewhere, maybe in this code, I
really don't know. I would like the entire selected row to be
selected and display the default selected colors.
Right now it looks pretty weird when I select the entire row,
the other selected parts of the row has the default blue
background with white text. But the area with the progressbar
remains white. Even when I click on it progressbar nothing
happens
Can anyone help me out with this?
 
 

Re:Customdraw is confusing me

"Newbie" < XXXX@XXXXX.COM >wrote in message
Quote
I have the following code that creates a progressbar in a
listview column.
That is a very inflexible way to handle it. It would be better to use the
ListView's drawing events to custom-draw the progress bar directly onto the
ListView's Canvas instead. Do not use a TProgressBar at all. For example:
void __fastcall TForm1::ListView1AdvancedCustomDrawItem(TCustomListView
*Sender, TListItem *Item, TCustomDrawState State, TCustomDrawStage Stage,
bool &DefaultDraw)
{
DefaultDraw = true;
if( Stage == cdPostPaint )
{
TRect ItemRect = Item->DisplayRect(drBounds);
TRect pbRect = ItemRect;
pbRect.Left += ListView1->Columns->Items[0]->Width;
pbRect.Right = pbRect.Left +
ListView1->Columns->Items[1]->Width;
pbRect.Left += 2;
pbRect.Right -= 2;
pbRect.Top += 2;
pbRect.Bottom -= 2;
if( State.Contains(cdsSelected) )
Sender->Canvas->Brush->Color = clHighlightText;
else
Sender->Canvas->Brush->Color = ListView1->Font->Color;
Sender->Canvas->FrameRect(pbRect);
pbRect.Left += 1;
pbRect.Right -= 1;
pbRect.Top += 1;
pbRect.Bottom -= 1;
pbRect.Right = (pbRect.Left + ((pbRect.Width() *
ProgressBetween1And100) / 100));
Sender->Canvas->Brush->Color = clBlue;
Sender->Canvas->FillRect(pbRect);
if( State.Contains(cdsSelected) )
Sender->Canvas->DrawFocusRect(ItemRect);
}
}
Gambit
 

Re:Customdraw is confusing me

Quote
That is a very inflexible way to handle it. It would be better to use the
ListView's drawing events to custom-draw the progress bar
This is great, thanks a lot, it works great now.
Would you happen to have any other techniques when it comes
to drawing icons or bitmaps in the columns too?
Or even drawing the sorting triangle on the header, I am going
to try and attempt that one eventually.
Thanks again for the help.
 

{smallsort}

Re:Customdraw is confusing me

"Newbie" < XXXX@XXXXX.COM >wrote:
Quote

[...] Or even drawing the sorting triangle on the header, I
am going to try and attempt that one eventually.
tinyurl.com/ybfhmu
~ JD
 

Re:Customdraw is confusing me

Thank you very much.
"JD" < XXXX@XXXXX.COM >wrote:
Quote
tinyurl.com/ybfhmu

~ JD

 

Re:Customdraw is confusing me

Quote
tinyurl.com/ybfhmu

~ JD

I have two questions on the code, this code is like way above
my head, hopefully you can let me in on the secrets.
1. Which part of the code is responsible for fudging the text
in the header a few spaces to the right?
2. Also which is responsible for placing the arrow? I would
like to see how I can move the arrow all the way to the end
of the header, instead of right next to the text.
Thanks again.
 

Re:Customdraw is confusing me

"Newbie" < XXXX@XXXXX.COM >wrote:
Quote

[...] this code is like way above my head
That's exactly how I felt when I first saw the sample so
don't feel bad.
TListView is just a wrapper class for a Window's native
ListView control. It's intended to make working with the
control easier and it does indeed do that until you need
more out of the control which then makes it more difficult.
Then, to top it all off, MS made the control in such a way
that it's actually more than one control working together
as one. It doesn't get more complicated that this.
Quote
hopefully you can let me in on the secrets.
The Tricky-dicky part is that it takes advantage of the
default behavior of the control by setting the column
header's Caption to an empty string.
Quote
Which part of the code is responsible for fudging the text
in the header a few spaces to the right?
In the DrawSortColumnHeader function, the TRect DataRect is
passed into the win32 API DrawText to define the boundries
of where the text should be drawn. Change the TRect and you'll
change where the text is drawn.
Quote
which is responsible for placing the arrow?
Same function : DrawSortColumnHeader. The above DataRect's
Right is used as a starting point for the arrow's Left.
Quote
I would like to see how I can move the arrow all the way to
the end of the header,
In the DrawSortColumnHeader function,
::SendMessage( hHeader, HDM_GETITEMRECT, (WPARAM)SortColumn, (LPARAM)&R )
causes the control to fill the TRect pointed to by the
LParam with the RECT for the column pointed to by the
WParam. So, the TRect R represents the entire drawing
area for the particular column header in client relative
coordinates (not non-client and not screen relative).
Quote
instead of right next to the text.
That's your choice but be aware that that code mimics exactly
the behavior of Windows Explorer. Your users should be use to
it and some will expect it.
~ JD
 

Re:Customdraw is confusing me

Quote
That's exactly how I felt when I first saw the sample so
don't feel bad.
I'm glad i'm not the only one hehe.
Quote
In the DrawSortColumnHeader function, the TRect DataRect is
passed into the win32 API DrawText to define the boundries
Thanks for pointing out the necessary areas to me, now I can
start playing around and see what I can destroy :)
Quote
That's your choice but be aware that that code mimics exactly
the behavior of Windows Explorer. Your users should be use to
it and some will expect it.
The only user who is going to be using this is me, but I do
like the look of the arrow right justified.
Thanks again for the help.