Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Canvas mit Handle auf Bitmap.Canvas (https://www.delphipraxis.net/83302-canvas-mit-handle-auf-bitmap-canvas.html)

igel457 30. Dez 2006 18:41


Canvas mit Handle auf Bitmap.Canvas
 
Hallo,

in meiner 2D Engine habe ich mir selbst eine Klasse von TCanvas abgeleitet:

Delphi-Quellcode:
TSurfaceCanvas = class(TCanvas)
  private
    FBitmap:TBitmap;
  public
    constructor Create;
end;
Nun möchte ich dass alle Zeichenbefehle die auf dem Canvas ausgeführt werden auf dem Bitmap erfolgen.
Also habe ich einfach...
Delphi-Quellcode:
constructor TSurfaceCanvas.Create;
begin
  inherited Create;
  Handle := FBitmap.Canvas.Handle;
end;
...geschrieben, was aber (wie ihr euch sicherlich denken könnt) nicht geht.
Wie bringe ich das zum laufen? Es wäre klasse wenn es mit dem Bitmap gehen würde, damit erspare ich mir nämlich einigen Ärger.

Danke,
Igel457

Sunlight7 30. Dez 2006 19:07

Re: Canvas mit Handle auf Bitmap.Canvas
 
Hallo,

so spontan würd' ich mal fragen, setzt Du irgendwo die größe des Bitmaps?

Denn das funkt:

Kompo:
Delphi-Quellcode:
constructor TSurfaceCanvas.Create;
begin
  inherited Create;
  FBitmap:=TBitmap.Create;
  FBitmap.Width:=80;
  FBitmap.Height:=80;
  Handle:=FBitmap.Canvas.Handle;
end;

procedure TSurfaceCanvas.Save;
begin
   FBitmap.SaveToFile('Test.bmp');
end;
Ausführen:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
   var sc:TSurfaceCanvas;
begin
   sc:=TSurfaceCanvas.Create;
   sc.TextOut(0, 0, 'Text');
   sc.Save;
end;
Grüßle!

igel457 30. Dez 2006 21:04

Re: Canvas mit Handle auf Bitmap.Canvas
 
Du hast recht...
Problem ist, dass ich nach einer Größenänderung das Handle neu zuweisen muss...
In einer kleinen Konsolenanwendung läuft es bei mir jetzt auch. Aber irgendwo muss ich noch einen Fehler haben.

Schonmal Danke!

Sunlight7 30. Dez 2006 21:19

Re: Canvas mit Handle auf Bitmap.Canvas
 
Bitte.

Kannst Dich ja nochmal melden, wenns wo hackt.

igel457 30. Dez 2006 21:37

Re: Canvas mit Handle auf Bitmap.Canvas
 
Ich bin jetz mal einen Schritt weiter:
Es funktioniert nur (warum auch immer), wenn ich mein Canvas innerhalb einer Prozedur erstelle und damit Arbeite.
Sobald ich das Canvas z.B. in "Form-Create" erstelle und in "Button1-Click" damit arbeite geht es nicht, die Ausgabe bleibt einfach weiß.

Kann ich dieses Problem irgendwie umgehen, ohne jedes mal mein Canvas neu erstellen zu müssen? Woran liegt dies überhaupt?

Schonmal Danke,
Igel457

jbg 30. Dez 2006 21:54

Re: Canvas mit Handle auf Bitmap.Canvas
 
Zitat:

Zitat von igel457
Woran liegt dies überhaupt?

Die VCL räumt nach jeder Window-Message alle DCs der Controls und alle Bitmap-DCs auf um GDI Resourcen zu sparen. Dem unterliegt natürlich auch dein Bitmap.

igel457 30. Dez 2006 21:56

Re: Canvas mit Handle auf Bitmap.Canvas
 
OK. Das hört sich logisch an. Kann ich das DC irgendwie sperren? Oder muss ich jedes mal ein neues erzeugen?

Sunlight7 30. Dez 2006 22:16

Re: Canvas mit Handle auf Bitmap.Canvas
 
Selber eins machen, dann müßts IMHO erhalten bleiben.

Aus genau den von jbg genannten Gründen hab ich mir ne eigene Bitmap Kompo gemacht, weil mir das Handle gewechsle aufn Zeiger ging.

jbg 30. Dez 2006 22:17

Re: Canvas mit Handle auf Bitmap.Canvas
 
Du musst ein neues erzeugen und das Bitmap-Handle dort selektieren, damit in das Bitmap gezeichnet wird

Delphi-Quellcode:
type
  TSurfaceCanvas = class(TCanvas)
  private
    FBmp: TBitmap;
    FOldBitmapHandle: HBITMAP;
    FOldPaletteHandle: HPALETTE;
  protected
    procedure CreateHandle; override;
  public
    constructor Create(AWidth, AHeight: Integer);
    destructor Destroy; override;

    property Bitmap: TBitmap read FBmp;
  end;

{ TSurfaceCanvas }

constructor TSurfaceCanvas.Create(AWidth, AHeight: Integer);
begin
  Assert(AWidth * AHeight > 0);
  inherited Create;
  FBmp := TBitmap.Create;
  FBmp.Width := AWidth;
  FBmp.Height := AHeight;
end;

procedure TSurfaceCanvas.CreateHandle;
begin
  Handle := CreateCompatibleDC(0);
  FOldBitmapHandle := SelectObject(Handle, FBmp.Handle);
  if not FBmp.IgnorePalette then
  begin
    FOldPaletteHandle := SelectObject(Handle, FBmp.Palette);
    // RealizePalette(FBmp.Palette); FALSCH
    RealizePalette(Handle); // RICHTIG
  end;
end;

destructor TSurfaceCanvas.Destroy;
var
  DC: HDC;
begin
  if Handle <> 0 then
  begin
    SelectObject(Handle, FOldBitmapHandle);
    if FOldPaletteHandle <> 0 then
      SelectObject(Handle, FOldPaletteHandle);
    DC := Handle;
    Handle := 0;
    DeleteDC(DC);
  end;
  FBmp.Free;
  inherited Destroy;
end;

DGL-luke 30. Dez 2006 22:19

Re: Canvas mit Handle auf Bitmap.Canvas
 
Wie wärs, wenn du gleich auf NonVCL gehst? Unter torry.net gibts ne schöne GDI+-Kapselung...


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:19 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz