But you didn't explain earlier WHY you need to preserve the HDC, only that you want to use it across "two tasks", without any example or explanation of what those tasks actually are. And, as Delija already mentioned, you can simply Lock the TBitmap's Canvas to prevent the VCL from releasing the HDC automatically. Just make sure you Unlock it before you resize or free the TBitmap, and re-Lock it again after resizing.
That makes no sense. If you are using the TBitmap's HDC for both functions, then there is no need to wait for a paint event to draw the string onto the TBitmap. Since you are not drawing the string onto a display HDC directly, there is no need to wait for a paint event. You can just draw onto the TBitmap whenever you want, since it is all just in-memory data. If you want to draw the TBitmap onto a display Canvas so the user can see the image, that certainly needs to be done in a paint event, but that does not mean you have to draw onto the TBitmap itself in the paint event. And in fact, you shouldn't do it that way. Prepare the TBitmap image ahead of time, and then just draw the TBitmap as-is whenever a paint event occurs, and then invalidate the display window whenever the TBitmap image changes so a new paint event can display the updated image. And this way, you don't even need the TBitmap's HDC to be persistent over time, you only need it when you are updating your image.
For example:
type
TTextPanel = class(...)
private
procedure BmpChanged(Sender: TObject);
procedure UpdateData;
protected
procedure Paint; override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;
constructor TTextPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FBmp := TBitmap.Create;
FBmp.OnChange := BmpChanged;
end;
destructor TTextPanel.Destroy;
begin
FBmp.Free;
inherited Destroy;
end;
procedure TTextPanel.BmpChanged(Sender: TObject);
begin
Invalidate;
end;
procedure TTextPanel.Paint;
begin
inherited Paint;
...
Canvas.Draw(0, 0, FBmp);
...
end;
procedure TTextPanel.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
inherited SetBounds(ALeft, ATop, AWidth, AHeight);
FBmp.SetSize(Width, Height);
UpdateData;
end;
procedure TTextPanel.UpdateData;
begin
// update FBmp image as needed...
end;
I think you are making this task harder than it really needs to be. If you think I'm wrong, feel free to provide an example demonstrating exactly what you are trying to accomplish.