 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Ralph Gamble Guest
|
Posted: Wed May 16, 2007 6:30 pm Post subject: OwnerDraw LisBbox & Scrolling |
|
|
I have an OwnerDraw ListBox On the left side of the ListBbox I have a
series of bitmaps.
Depending a condition I want to output a Text On top of the Bit map. I
have inserted
The code to output the Text in the bit map in OnDrawItem. It seems to
work correctly
except when I scroll. When I scroll and a bit map that needs Text is
at the bottom
it draws correctly, but as soon as I move down one more position it
disappears.
What am I missing and how do I fix this.
Thanks in advance
Ralph |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Wed May 16, 2007 9:32 pm Post subject: Re: OwnerDraw LisBbox & Scrolling |
|
|
"Ralph Gamble" <ralphgamble (AT) rogers (DOT) com> wrote in message
news:464b0785$1 (AT) newsgroups (DOT) borland.com...
| Quote: | When I scroll and a bit map that needs Text is at the bottom it
draws correctly, but as soon as I move down one more position
it disappears. What am I missing and how do I fix this.
|
Please show your actual code.
Gambit |
|
| Back to top |
|
 |
Ralph Gamble Guest
|
Posted: Wed May 16, 2007 10:26 pm Post subject: Re: OwnerDraw LisBbox & Scrolling |
|
|
Here is code
//---------------------------------------------------------------------------
void __fastcall TMainForm::ListBoxDrawItem(TWinControl *Control, int
Index,
TRect &Rect, TOwnerDrawState State)
{
TBitBtn *Btn = ((TBitBtn*)(ListBox->Items->Objects[Index]));
Btn->Left = Rect.Left;
Btn->Top = Rect.Top;
Btn->Visible = true;
TBitBtn *BtnAhead = BAH[Index];
BtnAhead->Top = Rect.Top;
if( !Btn->Visible ) Btn->Visible = true;
else Btn->Repaint(); // to remove some color shift when button
looses
focus
TRect rect = Rect;
rect.Left += Btn->Width;
TCanvas *Cvs = ((TListBox*)Control)->Canvas;
Cvs->FillRect(rect);
if( State.Contains(odFocused) ) Cvs->DrawFocusRect(rect);
if( State.Contains(odSelected) ) {
Cvs->Brush->Color = clHighlight;
Cvs->Pen->Color = clHighlightText;
} else {
Cvs->Brush->Color = clWindow;
Cvs->Pen->Color = clWindowText;
}
if (ListBox->Items->Strings[Index]!=""){
OutPutTextString(Cvs,ListBox->Items->Strings[Index],rect.Left+5,
rect.Top+6);
}
Cvs->Brush->Color = clWindow;
TCData* APtr=GetDataPtr(Btn->Tag);
if (APtr!=NULL){
if ((Index==0)&&(AuctionOver())) BtnAhead->Visible = false;
else BtnAhead->Visible = true;
// This is the text that dissapears
if (APtr->TotalMeaning>1) Astrix(Cvs,rect.left,rect.top);
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Astrix(TCanvas* Cvs, int x1, int y1)
{
// save old
//TColor old=Cvs->Font->Color;
//TColor oldBrush=Cvs->Brush->Color;
//int oldSize=Cvs->Font->Size;
// draw Blue astrix
Cvs->Brush->Color=clBtnFace;
Cvs->Font->Color=clBlue;
Cvs->Font->Size=14;
Cvs->TextOut(x1-10,y1,"*");
// restore old
//Cvs->Brush->Color=oldBrush;
//Cvs->Font->Color=old;
//Cvs->Font->Size=oldSize;
}
The Second line from bottom od drawitem is the line of code that draws
the
disaperaring test
Ralph |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu May 17, 2007 12:01 am Post subject: Re: OwnerDraw LisBbox & Scrolling |
|
|
"Ralph Gamble" <ralphgamble (AT) rogers (DOT) com> wrote in message
news:464b3ee5$1 (AT) newsgroups (DOT) borland.com...
| Quote: | Btn->Left = Rect.Left;
Btn->Top = Rect.Top;
Btn->Visible = true;
TBitBtn *BtnAhead = BAH[Index];
BtnAhead->Top = Rect.Top;
if( !Btn->Visible ) Btn->Visible = true;
else Btn->Repaint();
|
You should not be manipulating buttons (or any control, for that
matter) from inside a drawing event. Intercept the WM_HSCROLL and
WM_VSCROLL messages instead.
Alternatively, instead of trying to synchronize a real button to the
ListBox, you could simply use the DrawFrameControl() function to draw
an image of a button directly onto the Canvas each time the OnDrawItem
event is triggered. Then you don't need a real button at all, and the
scrolling will always work without extra processing on your part. As
for button clicks, you can use the ListBox's ItemAtPos() and
ItemRect() methods inside the OnMouse... events, check if the clicking
is occuring in the button area, and then react accordingly.
| Quote: | TRect rect = Rect;
rect.Left += Btn->Width;
TCanvas *Cvs = ((TListBox*)Control)->Canvas;
Cvs->FillRect(rect);
|
You are not clearing out the area of the the Canvas that cooresponds
to the button. The previous drawing will be preserved in the new
drawing. You should always clear the entire TRect area. The button
will redraw itself over the new drawing later, so you should always be
sure to start with a blank slate each time.
| Quote: | if( State.Contains(odFocused) ) Cvs->DrawFocusRect(rect);
|
That should be your last drawing operation, not your first.
| Quote: | // This is the text that dissapears
|
You are clearing the area of the Canvas that contains the text (as you
should be) but you are then drawing the text conditionally. So
chances are, your conditions are not being met every time you expect
them to be, so the text is not being redrawn when you want it to be.
Gambit |
|
| Back to top |
|
 |
Ralph Gamble Guest
|
Posted: Thu May 17, 2007 7:19 pm Post subject: Re: OwnerDraw LisBbox & Scrolling |
|
|
Thanks Remy I can see what I was doing cannot work.
During scrolling the button is redrawn on top of the text (astrix)
that I just output. I guess my brain was out of gear when I wrote
this.
I wanted the appearance of a real button with a glyph in it so the
reason for TBitBtn. When I Looked at DrawFrameControl()
I cannot see how to Draw a bit Button with a glyph.
I can also see how I could change the Glyph to get the desired effect
but am now concerned with your comment
| Quote: | You should not be manipulating buttons (or any control, for that
matter) from inside a drawing event.
|
I cant see what is wrong with changing position & visibility.
(The buttons are activated through the ListBox OnClick event)
Could you please briefly explain why the above general rule applies.
| Quote: | Intercept the WM_HSCROLL and
WM_VSCROLL messages instead.
|
I'm going to try the above approach, I've never done it before, but
from some of your previous
posts I should be able to work through it. (good for my education).
Once again thanks for your detailed analysis and comments.
Ralph |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu May 17, 2007 10:03 pm Post subject: Re: OwnerDraw LisBbox & Scrolling |
|
|
"Ralph Gamble" <ralphgamble (AT) rogers (DOT) com> wrote in message
news:464c6473$1 (AT) newsgroups (DOT) borland.com...
| Quote: | I wanted the appearance of a real button with a glyph in
it so the reason for TBitBtn. When I Looked at
DrawFrameControl() I cannot see how to Draw a bit
Button with a glyph.
|
Just draw a normal button (DFC_BUTTON, DFCS_BUTTONPUSH), and then draw
your glyph on top of that. You can overlap drawing as much as you
want within a single OnDrawItem event.
| Quote: | You should not be manipulating buttons (or any control, for
that matter) from inside a drawing event.
I cant see what is wrong with changing position & visibility.
|
Drawing events are called very often. Their sole purpose is to update
the display, nothing else. That is very bad place to move things
around, or do any kind of intense processing that is not related to
drawing. Think about it - your list has a button on it. Something
happens and the list needs to be repainted onscreen. But then you
change the button mid-draw and now the list has to be repainted all
over again to account for that change that was not necessary in the
first place.
| Quote: | (The buttons are activated through the ListBox OnClick event)
|
That is where you should be updating the visibility and poistioning.
Not in the OnDrawItem event.
Gambit |
|
| Back to top |
|
 |
Ralph Gamble Guest
|
Posted: Mon May 21, 2007 11:21 pm Post subject: Re: OwnerDraw LisBbox & Scrolling |
|
|
Thank you for all your help. I tried the DrawFrameControl() route
and intercepting the vertical scroll message. The DrawframeControl()
did not perform exacly what I wanted for appearance. So I
rewrote the button synchronization method moving all the code
outside the OnDrawItem event and everything works perfectly now.
I had the wrong idea on draw item events. thanks for point me in right
direction.
Thanks again
Ralph |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|