I am struggling to understand if there is really a difference between both statements:
Image->Picture->Bitmap = bitmap; // bitmap is a TBitmap object
Image->Picture->Assign(bitmap);
The VCL help clearly says about the assignment via =
:
Note: When assigning the Bitmap property, TPicture assigns the properties of a another TBitmap object. It does not take ownership of the specified value.
This means that the first statement does NOT copy the bitmap into Image->Picture->Bitmap
but just the address of the bitmap
is taken over by Image->Picture->Bitmap
.
Why is then Image->Picture->Bitmap
displaying the picture on the screen correctly even after I deleted the bitmap object?
In this statement:
Image->Picture->Bitmap = bitmap;
What the documentation does not say, but what actually happens, is the TPicture::Bitmap
property setter calls Assign()
on the TBitmap
returned by the TPicture::Bitmap
property getter. IOW, it is identical to calling this:
Image->Picture->Bitmap->Assign(bitmap);
Where TPersistent::Assign()
copies data from one object to another compatible object. In this case, TBitmap
overrides Assign()
to copy the pixel data from another TBitmap
.
The TPicture::Bitmap
property getter ensures the TPicture
holds its own TBitmap
, creating a new one if it does not already have one, and freeing any previous non-bitmap graphic.
This is roughly equivalent to doing this:
if (!dynamic_cast<TBitmap*>(Image->Picture->FGraphic))
// or:
// if ((Image->Picture->FGraphic != NULL) &&
// (!Image->Picture->FGraphic->InheritsFrom(__classid(TBitmap))))
{
TBitmap *newBmp = new TBitmap;
delete Image->Picture->FGraphic;
Image->Picture->FGraphic = newBmp;
}
static_cast<TBitmap*>(Image->Picture->FGraphic)->Assign(bitmap);
In this statement:
Image->Picture->Assign(bitmap);
TPicture
overrides the Assign()
method to create a new TBitmap
that is a copy of the passed bitmap
and then takes ownership of it, freeing any previous graphic.
This is roughly equivalent to doing this:
TBitmap *newBmp = new TBitmap;
newBmp->Assign(bitmap);
delete Image->Picture->FGraphic;
Image->Picture->FGraphic = newBmp;
So, in both cases, the TPicture
ends up holding its own TBitmap
that has copied the data from the passed bitmap
.
This means that the first statement does NOT copy the bitmap into
Image->Picture->Bitmap
but just the address of thebitmap
is taken over byImage->Picture->Bitmap
.
That is not correct, and counter to the documentation you quoted. Taking just the address would be taking ownership, and that is exactly what the documentation explicitly says does not happen.
Why is then
Image->Picture->Bitmap
displaying the picture on the screen correctly even after I deleted thebitmap
object?
Because the TPicture
has made its own copy of the pixel data. What you do with the original bitmap
afterwards doesn't affect the TPicture
at all.