Board index » cppbuilder » Two images on a TBitBtn.....how?

Two images on a TBitBtn.....how?


2005-09-07 04:34:01 AM
cppbuilder96
Hello, I'm trying to display an additional bitmap image on a TBitBtn besides the one already there. I don't need additional up/down/disabled images on this thing, I just need another image on the opposite side of the text from the bitmap that normally shows up there. I would like to do this by creating a new component and inheriting from TBitBtn (or TButton) and not have to create a completely new component from scratch. I know how to create new TBitmaps and I also know how to draw one on a TCanvas object. The problem is getting a TCanvas object onto a TButton or TBitBtn so I can pop the bitmap in there (I know Borland had to, somehow, to make the TBitBtn in the first place). Thanks.
 
 

Re:Two images on a TBitBtn.....how?

"Andy Piskur" < XXXX@XXXXX.COM >wrote in message
Quote
The problem is getting a TCanvas object onto a TButton or TBitBtn
so I can pop the bitmap in there (I know Borland had to, somehow,
to make the TBitBtn in the first place).
TButton is not an owner-drawn control. The OS draws everything for TButton.
The VCL does not draw anything for it.
TBitBtn creates an instance of TCanvas in its constructor. Whenever the
TBitBtn redraws itself, it assigns the TCanvas::Handle property to whatever
HDC the OS provides to TBitBtn for drawing onto. However, you do not have
access to the TCanvas that TBitBtn uses. It is declared as private.
In order to change TBitBtn's drawing behavior, you will have to intercept
the CN_DRAWITEM message and then use your own TCanvas object.
Gambit
 

Re:Two images on a TBitBtn.....how?

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

TBitBtn creates an instance of TCanvas in its constructor. Whenever the
TBitBtn redraws itself, it assigns the TCanvas::Handle property to whatever
HDC the OS provides to TBitBtn for drawing onto. However, you do not have
access to the TCanvas that TBitBtn uses. It is declared as private.

Thanks for the quick response. As to the TCanvas, I assume this also describes the behaviour of a SpeedButton? I discovered that the SpeedButton is derived from TGraphicControl which has a TCanvas. Since I am creating my own component, would it be possible to use this TCanvas or even redeclare it as public in order to effectively "draw" an additional bitmap on the button?
Quote
In order to change TBitBtn's drawing behavior, you will have to intercept
the CN_DRAWITEM message and then use your own TCanvas object.

Ok, this makes sense except that I am relatively new to Windows programming. I am unsure of how I could intercept this message and then insert my own TCanvas object. Any help is appreciated. Thanks.
 

{smallsort}

Re:Two images on a TBitBtn.....how?

"Andy Piskur" < XXXX@XXXXX.COM >wrote in message
Quote
As to the TCanvas, I assume this also describes the behaviour of a
SpeedButton?
TSpeedButton also has a TControlCanvas that is created in he TGraphicControl
constructor, and then the TControlCanvas::Handle is assigned to an HDC that
is provided by the WM_PAINT message.
Quote
I discovered that the SpeedButton is derived from TGraphicControl which
has a TCanvas. Since I am creating my own component, would it be possible
to use this TCanvas or even redeclare it as public in order to effectively
"draw" an additional bitmap on the button?
You do not have to redeclare anything. TGraphicControl provides a protected
Canvas property that is accessible to descendant classes. Simple override
the virtual Paint() method to do your own drawing.
Gambit
 

Re:Two images on a TBitBtn.....how?

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote
TSpeedButton also has a TControlCanvas that is created in he TGraphicControl
constructor, and then the TControlCanvas::Handle is assigned to an HDC that
is provided by the WM_PAINT message.
You do not have to redeclare anything. TGraphicControl provides a protected
Canvas property that is accessible to descendant classes. Simple override
the virtual Paint() method to do your own drawing.
Thanks for the info on that one. I finally figured out how to call the ancestor Paint() method before adding in my picture to the button. One problem I am having is that I cannot figure out how to make it refresh my image after a resize. I tried overriding the Repaint() method but that didn't help. When I attempted to override the Resize() method from TControl, it bombed. I'm not sure how the original Glyph is getting redrawn after a resize either as I am not very pascal/delphi literate (the pascal source is included with Builder, I found out). I would also like to find out how to make my image center itself when the drawing space is smaller than the image itself (I am using a TImageList). Thanks.
 

Re:Two images on a TBitBtn.....how?

Nevermind about the TImageList and trying to get that to work. I am just drawing the bitmap directly on the canvas as I should have done all along using the Draw or StretchDraw methods. I am still having trouble with the new secondary image not getting redrawn after a resize though. Whatever the trigger is to make the original glyph and the text re-adjust and then redraw itself, I would like to know so that I can call my adjust function and then redraw the second bitmap. This problem occurs whenever I change the properties as well. If there was an OnChange event that I could manipulate I would do so but there doesn't appear to be an OnChange anywhere in the hierarchy. As before, when I try to override the Resize() method and then place the new component on a form, I get an error message and it never gets placed. Any help is appreciated. Thanks.
 

Re:Two images on a TBitBtn.....how?

"Andy Piskur" < XXXX@XXXXX.COM >wrote in message
Quote
One problem I am having is that I cannot figure out how to
make it refresh my image after a resize.
You shouldn't have to do anything for that. A resize operation
automatically redraws the component, causing Paint() to be called again.
Simply take the current dimensions into account whenever Paint() is called.
Quote
I'm not sure how the original Glyph is getting redrawn after a resize
When the component is resized, it becomes invalidated, which causes the OS
to issue a new WM_PAINT message when appropriate. Paint() is called in
response to WM_PAINT.
Quote
I would also like to find out how to make my image center itself
when the drawing space is smaller than the image itself (I am using
a TImageList).
It doesn't matter whether you use a TImageList or not. You are still
responsible for specifying the X and Y coordinates where the image is to be
drawn. Inside of Paint(), simply take the current dimensions of the
component, calculate a suitable X and Y for the drawing, and then Draw() the
image.
Gambit
 

Re:Two images on a TBitBtn.....how?

"Andy Piskur" < XXXX@XXXXX.COM >wrote in message
Quote
I am still having trouble with the new secondary image not getting
redrawn after a resize though. Whatever the trigger is to make the
original glyph and the text re-adjust and then redraw itself, I would
like to know so that I can call my adjust function and then redraw
the second bitmap.
That is exactly what overriding the Paint() method is for. You need to
recalculate and redraw your image every time Paint() is called.
Quote
This problem occurs whenever I change the properties as well. If
there was an OnChange event that I could manipulate I would do so
but there doesn't appear to be an OnChange anywhere in the hierarchy.
TBitmap does have an OnChange event that the component uses for the primary
image to Invalidate() itself so that the OS sends a new WM_PAINT message to
the component, thus triggering the Paint() method.
Quote
As before, when I try to override the Resize() method and then place
the new component on a form, I get an error message and it never
gets placed.
Then stop overriding Resize() to begin with. You are obviously not using it
correctly. The native components don't override it for drawing anyway.
Gambit
 

Re:Two images on a TBitBtn.....how?

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

"Andy Piskur" < XXXX@XXXXX.COM >wrote in message
news:4325af6b$ XXXX@XXXXX.COM ...

>One problem I am having is that I cannot figure out how to
>make it refresh my image after a resize.

You shouldn't have to do anything for that. A resize operation
automatically redraws the component, causing Paint() to be called again.
Simply take the current dimensions into account whenever Paint() is called.

>I'm not sure how the original Glyph is getting redrawn after a resize

When the component is resized, it becomes invalidated, which causes the OS
to issue a new WM_PAINT message when appropriate. Paint() is called in
response to WM_PAINT.

>I would also like to find out how to make my image center itself
>when the drawing space is smaller than the image itself (I am using
>a TImageList).

It doesn't matter whether you use a TImageList or not. You are still
responsible for specifying the X and Y coordinates where the image is to be
drawn. Inside of Paint(), simply take the current dimensions of the
component, calculate a suitable X and Y for the drawing, and then Draw() the
image.


Gambit