views:

75

answers:

1

I'm having a fairly strange problem with a TImage component's width and height properties. As a test, I draw a red dot in (what is supposed to be) the center of the TImage component by taking the midpoint of the TImage's width and height and drawing the dot there so that it is centered (centerPoint2D is a TPoint):

// The center point is the center of the display area.
centerPoint2D.X := Trunc(Image1.Width / 2);
centerPoint2D.Y := Trunc(Image1.Height / 2);

Image1.Canvas.Brush.Color := clRed;
Image1.Canvas.Brush.Style := bsSolid;
Image1.Canvas.Ellipse(centerPoint2D.X - 5, centerPoint2D.Y - 5, centerPoint2D.X + 5, centerPoint2D.Y + 5);

The red dot does not appear in the center of the TImage but somewhere well below and to the right to it. In addition, any text I print to the component appears stretched. It's as if the TImage is much larger than the reported dimensions, larger than what is visible from the apparent viewport, as if what is visible is clipped.

Additional Details. The TImage control sits on a TPanel that sits on a TGroupBox that sits on the TFrame. However, all of those components have their Align property set to alClient. The TFrame itself has it's Align property set to alNone. However, the instance of it that sits on the Form has it's Align property set to alClient at design time. In other words, it should not be a case of the TImage component being larger than the portion of it that is visible at runtime. In addition, the dimensions reported do appear to match the size of the component as it appears on screen to my eye, but I do not have "pixel ruler" utility to confirm that objectively.

+4  A: 

The TImage control is normally used to display image files (e.g. *.bmp files). Hence the control can load an image of any dimension, and then render it on the control's canvas using the specified properties (Center, Stretch, and Proportional). With that in mind, it is not that surprising that the width of the TImage control on the form differ from the size of the, well, Canvas, the Canvas of the associated bitmap, or whatever it might be.

If you do not load images, but rather want a control with a canvas to draw on, you should use TPaintBox. Or why not draw directly on the TForm?

Andreas Rejbrand
Hello Andreas. That did the trick. I guess though I'll have to print to another TBitmap first and then BitBlt() that TBitmap to TPaintBox if I want to get rid of the flickering with TPaintBox. That was one of the reasons I used TImage, to avoid flicker by setting it's Stretched property to TRUE.
Robert Oschler
@Robert: When I want to have full control and draw flicker-free animations using Windows GDI (that is, using a `TCanvas`) I create a custom control, decending from `TCustomControl`, and paint on it. To reduce flicker, I always respond to the `WM_ERASEBKGND` message (and do nothing). Also, double-buffering is imperative. Do all your drawing on an off-screen `TBitmap`, and then write a `Swap` procedure that `BitBlt`s the `TBitmap` onto the control on-screen, at command. Then you can swap every time the scene is complete, and no intermediate steps are shown.
Andreas Rejbrand