There's a bug in TImage! It *will flicker* if you don't set its Stretch property to true. Strange, but true, no less (pardon that semi-pun).

Now, back to your other queries from the original post.

The flicker is caused by Windows being a pain in the arse. Whenever it updates a region, it clears the background to the form's colour first *before* you draw stuff onto it. The net result of this is that your program shows a 'grey' colour (usually, whatever your form's background colour is tho) which immediately gets overridden by whatever you draw. This is bad.

There are several ways to combat it. The first is to take the problem at the source - Windows sends a message WM_ERASEBKGND whenever it has to repaint the window. You can handle this and tell Windows "get lost, you pest!"

Have a look at the win32.hlp file (Win32 Programmer's Reference help file), assuming it exists in your version of Delphi. In the section under WM_ERASEBKGND, it tells you:

Return Values

An application should return nonzero if it erases the background; otherwise, it should return zero.

Remarks

The DefWindowProc function erases the background by using the class background brush specified by the hbrBackground member of the WNDCLASS structure. If hbrBackground is NULL, the application should process the WM_ERASEBKGND message and erase the background.
An application should return nonzero in response to WM_ERASEBKGND if it processes the message and erases the background; this indicates that no further erasing is required. If the application returns zero, the window will remain marked for erasing. (Typically, this indicates that the fErase member of the PAINTSTRUCT structure will be TRUE.)
In short, we catch the message and set its to something other than zero. This stops Windows from redrawing the background. To do this, you can add in a handler for your message. Find the interface section of the unit and look at the form's declaration:

[pascal]
type
TForm1 = class(TForm)
// some event handlers here
private
{ Private declarations }
// stuff here
procedure StopFlicker(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;
public
{ Public declarations }
end;
[/pascal]
Notice the added function here, StopFlicker. This catches the Windows message WM_ERASEBKGND (hence the extra 'message' bit tagged onto the end of the procedure. The info for the message is passed in as a var message. You can use var msg: TMessage btw, but there's a specific type for each message (usually), so there's no harm in using that instead.

Now, go find the 'implementation' section of your form and bung this in:

[pascal]
implementation

procedure TForm1.StopFlicker(var Msg: TWMEraseBkgnd);
begin
Msg.Result := 1;
end;
[/pascal]

The above says "don't handle this message" (you may need a call to 'inherited' in the function - I forget!)

That's one way to stop flickering. The next is to figure out why the WM_ERASEBKGND message is being sent in the first place!

You can use the Invalidate procedure to update what needs to be drawn (as well as the InvalidateRgn procedure). These exist in the Windows API but are handled by Delphi. What you may not know, though, is the native API ones actually have another parameter, bErase, which says "do you want to erase the background when redrawing?" This *would* stop the flickering if we could access it!

It turns out that components can use the csOpaque style in ControlStyle to say "I draw myself fully. Don't erase the background!" This comes in handy if you're creating your own graphical controls. You can add this line in the constructor:

[pascal]ControlStyle := ControlStyle + [csOpaque];[/pascal]

That line will reduce flicker for your controls.

This still hasn't got around to DoubleBuffered yet . When you enable DoubleBuffered for your TWinControl (i.e. the form in this case), it *doesn't* draw the stuff to screen immediately on an OnPaint event. Instead, it creates a device context (a thing you draw to) in memory and does its stuff there. The final result is copied to the screen. This means that you won't see anything being drawn while-it-is-being-rendered, as it were. The standard concept of double-buffering.

However, the best piece of advice I can give you is this: give up on TCanvas, TBitmap and all that malarky. There's an amazingly cool graphics library called "Graphics32" that is pretty much *flicker free* and gives you *optimised double buffering, alpha blending, rotation, scaling...* the whole works. Take the trouble to convert your stuff over to it. You'll be amazed at how much functionality it offers you.

Really. Get it here.