Bitte beachten Sie den folgenden Code ein:TBitmap verliert Ausschneidebereich nach nicht verwandten Grafikcode
type
TBaseControl = class(TWinControl)
private
FBitmap : TBitmap;
public
constructor Create(AOwner : TComponent); override;
procedure DrawBorder;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
NewC : TBaseControl;
implementation
{$R *.dfm}
constructor TBaseControl.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
FBitmap := TBitmap.Create;
FBitmap.PixelFormat := pf24bit;
FBitmap.SetSize(100,100);
end;
procedure TBaseControl.DrawBorder;
var
Region : HRGN;
ContentRect : TRect;
begin
// Almost like a Client Area of a control
ContentRect := Rect(10,10,FBitmap.Width - 10,FBitmap.Height - 10);
// Create clipping region on FBitmap with ContentRect being excluded
Region := CreateRectRgnIndirect(Rect(0,0,Width,Height));
SelectClipRgn(FBitmap.Canvas.Handle,Region);
ExcludeClipRect(FBitmap.Canvas.Handle,ContentRect.Left,ContentRect.Top,
ContentRect.Right,ContentRect.Bottom);
DeleteObject(Region);
// Do Pre-drawing
FBitmap.Canvas.Brush.Style := bsSolid;
FBitmap.Canvas.Brush.Color := clRed;
FBitmap.Canvas.FillRect(Rect(0,0,FBitmap.Width,FBitmap.Height));
// Will comment out one of these statements
// The graphics one (.Caption) will cause the clipping to be lost. Any
// graphics code will do it as long as it is not related to FBitmap
// ========================================================================
Form1.Caption := 'You have just lost your Bitmap''s clipping';
// -----
Form1.Tag := Random(1000);
// ========================================================================
// Do some drawing afterwards
FBitmap.Canvas.Brush.Color := clGreen;
FBitmap.Canvas.FillRect(Rect(5,5,FBitmap.Width - 5,FBitmap.Height - 5));
// Want to see what it looks like
FBitmap.SaveToFile('d:\test.bmp');
// Test the tag setting
ShowMessage(InttoStr(Form1.Tag));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// Create an instance of TBaseControl
NewC := TBaseControl.Create(Self);
NewC.SetBounds(0,0,200,200);
NewC.Parent := Self;
// Tell it to draw
NewC.DrawBorder;
end;
In DrawBorder
, wenn ich nur ohne die Beschriftung Form1 Tag gesetzt werden, dann FBitmap der Clipping-Bereich gehalten wird und im gesamten Zeichnungscode respektiert. FBitmap wird wie folgt aussehen:
Aber wenn Beschriftung des Form1 gesetzt ist, dann FBitmap seine Clippingbereichs verlieren und wie folgt aussehen:
So scheint es, dass nach Form1 Caption war set FBitmap hat seinen Clipping-Bereich verloren. WindowOrigins (festgelegt über SetWindowOrgEx) gehen ebenfalls verloren, wenn dies geschieht.
Diese Bitmap hat ihre Zeichenfläche verloren (ihr Handle wird nach dem Ändern der Formularunterschrift in D2009 auf 0 gesetzt). Das Steuerelement wurde nicht neu erstellt. Hast du versucht, ein kleines braunes Eichhörnchen oder ein ähnliches Baumtier zu opfern? Es macht wirklich keinen Sinn. – Victoria
@Victoria macht es Sinn, wenn Sie berücksichtigen, dass die VCL GDI-Ressourcen zwischenspeichert und häufig (während der Nachrichtenbehandlung) Canvas-HDCs freigibt, die nicht aktiv gesperrt sind. Erwarten Sie nicht, dass GDI-Einstellungen im Laufe der Zeit beibehalten werden. Setzen Sie sie zurück, wenn Sie etwas zeichnen müssen. Die durch 'DrawBorder' festgelegte Region ist möglicherweise nicht gültig, nachdem die Ausführung zur Hauptnachrichtenschleife zurückgekehrt ist (z. B. aufgrund eines Repaints, ausgelöst durch die 'Caption'-Änderung) –