BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

OwnerDraw LisBbox & Scrolling

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage)
View previous topic :: View next topic  
Author Message
Ralph Gamble
Guest





PostPosted: Wed May 16, 2007 6:30 pm    Post subject: OwnerDraw LisBbox & Scrolling Reply with quote



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





PostPosted: Wed May 16, 2007 9:32 pm    Post subject: Re: OwnerDraw LisBbox & Scrolling Reply with quote



"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





PostPosted: Wed May 16, 2007 10:26 pm    Post subject: Re: OwnerDraw LisBbox & Scrolling Reply with quote



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





PostPosted: Thu May 17, 2007 12:01 am    Post subject: Re: OwnerDraw LisBbox & Scrolling Reply with quote

"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





PostPosted: Thu May 17, 2007 7:19 pm    Post subject: Re: OwnerDraw LisBbox & Scrolling Reply with quote

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





PostPosted: Thu May 17, 2007 10:03 pm    Post subject: Re: OwnerDraw LisBbox & Scrolling Reply with quote

"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





PostPosted: Mon May 21, 2007 11:21 pm    Post subject: Re: OwnerDraw LisBbox & Scrolling Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.