Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Zeichnen sowie ab wann ist alles verfügbar? (https://www.delphipraxis.net/160568-zeichnen-sowie-ab-wann-ist-alles-verfuegbar.html)

Memnarch 19. Mai 2011 22:54


Zeichnen sowie ab wann ist alles verfügbar?
 
NAbend,
ich habe ein problem.

Aufgrund gewisser umstände wird meine Zeichenfläche momentan mit einem timer konstant aktualisiert.
Der timer ist auf der selben form wie meine zeichenfläche(die übrigens eine ableitung von TPaintBox ist).

Ich habe verschiedenes probiert: Timer default auf enabled, enabled am ende von MYFormCreate, oder timer enabled in FormActivate.

Aus irgend einem grund bekomme ich Random Accessviolations beim starten. Logging mit smartinspect kann ich vergessen, sobald das eingeschaltet ist, gibt es kein problem mehr >.<.

Zuvor hatte ich es so, dass ich in WMMouseMove beine zeichenarbeit erledigt habe, und dann von dort refreshed habe. Leider wird wmmove sooft gefeuert dass die CPU apknickt und win7 irgendwan meldet die app sei futsch.

Meine TPaintBox ableitung erstellt noch ein paar objecte in ihrem constructor(nen buffer, und noch 2 benötigte bitmaps).

Jemand nen rat wie ich das zeichnen durch den User am besten aktualisiere?

Luckie 19. Mai 2011 23:06

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Zeichne auf ein Bitnmap im Speicher und kopiere es im OnPaint auf die Zeichenfläche. Dann sparst du dir den Timer und es ist immer aktuell.

Memnarch 20. Mai 2011 01:45

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Okay.
Und unter welchen umständen wird onPAint aufgerufen?

Wenn ich z.b eine Linie zeichne würde sie ja in den buffer geschrieben, muss ich danach per Refresh das onPaint triggern?(Sonst wird ja erst wieder gezeichnen wenn windows es benötigt bzw die vcl)

Bora4d 20. Mai 2011 01:48

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Nach Aufruf von SetParent ist der Canvas- oder Fenster-Handle gültig.
Überschreibe in dein abgeleiteten Control oder in Form SetParent und setzte dein Timer dort aktiv. Du mußt nur achten dass der Handle gültig ist. Also auf <>0 überprüfen. Beim zerstören des Controls wird SetParent mit 0 aufgerufen.

Das ist die Funktion:

protected
procedure SetParent(AParent: TWinControl); virtual;

Luckie 20. Mai 2011 07:22

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Zitat:

Zitat von Memnarch (Beitrag 1101907)
muss ich danach per Refresh das onPaint triggern?(Sonst wird ja erst wieder gezeichnen wenn windows es benötigt bzw die vcl)

Richtig. Du kannst das ganze natürlich auch von Hand auslösen.

Uwe Raabe 20. Mai 2011 07:29

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Grundsätzlich sollte bei einer PaintBox immer über Invalidate das OnPaint getriggert werden und alle Zeichenoperationen finden ausschließlich im OnPaint statt.

Memnarch 20. Mai 2011 08:36

AW: Zichenen sowie ab wann ist alles verfügbar?
 
@Uwe: Das heißt aber dass ich meinen Buffer aber auch woanders füllen kann, das zeichnen auf den canvas der Paintbox selbst sollte dann dort stehen, oder?


MFG
Memnarch

Uwe Raabe 20. Mai 2011 08:52

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Zitat:

Zitat von Memnarch (Beitrag 1101920)
@Uwe: Das heißt aber dass ich meinen Buffer aber auch woanders füllen kann, das zeichnen auf den canvas der Paintbox selbst sollte dann dort stehen, oder?

Genau!

Memnarch 20. Mai 2011 09:04

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Ah gut....vielleicht bekomm ich mein Tool jetzt endlich mal gefixxed. v1.3 lässt wegen dem fehler schon auf sich warten :D

Satty67 20. Mai 2011 09:41

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Eine bischen gespielt...
Delphi-Quellcode:
unit UPaintboxBuffer;

interface

uses
  ExtCtrls, Graphics;

type
  TPaintboxBuffer = class
  private
    FPaintBox : TPaintBox;
    FBitmapA,
    FBitmapB : TBitmap;
    FWorkBmp : TBitmap; // either FBitmapA or FBitmapB
    procedure CreateBitmap(var Bmp : TBitmap; W, H : Integer);
    procedure OnPaintHandler(Sender: TObject);
  public
    constructor Create(APaintBox : TPaintBox);
    destructor Destroy;
    procedure SwitchBitmap;
    property Bitmap : TBitmap read FWorkBmp;
  end;

implementation

constructor TPaintboxBuffer.Create(APaintBox : TPaintBox);
begin
  FPaintBox := APaintBox;
  CreateBitmap(FBitmapA, FPaintBox.Width, FPaintBox.Height);
  CreateBitmap(FBitmapB, FPaintBox.Width, FPaintBox.Height);
  FWorkBmp := FBitmapA;
  FPaintBox.OnPaint := OnPaintHandler;
end;

procedure TPaintboxBuffer.CreateBitmap(var Bmp : TBitmap; W, H : Integer);
begin
  Bmp := TBitmap.Create;
  Bmp.Width := W;
  Bmp.Height := H;
end;

destructor TPaintboxBuffer.Destroy;
begin
  FPaintBox.OnPaint := NIL;
  FBitmapA.Free;
  FBitmapB.Free;
end;

procedure TPaintboxBuffer.OnPaintHandler(Sender: TObject);
begin
  FPaintBox.Canvas.StretchDraw(FPaintBox.Canvas.ClipRect, FWorkBmp);
end;

procedure TPaintboxBuffer.SwitchBitmap;
begin
  if FWorkBmp = FBitMapA then
    FWorkBmp := FBitMapB
  else
    FWorkBmp := FBitMapA;
  FPaintBox.Invalidate;
end;

end.
Beispiel:
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  p : Pointer;
  s : String;
begin
  Timer1.Enabled := False;
  with PaintBoxBuffer do
  begin
    // Bitmap füllen
    p := Bitmap;
    s := DateTimeToStr(Now) +' Used Bitmap: $'+ IntToHex(Integer(p), 8);
    Bitmap.Canvas.FillRect(Bitmap.Canvas.ClipRect);
    Bitmap.Canvas.TextOut(10,10, s);
    // umschalten
    SwitchBitmap;
  end;
  Timer1.Enabled := True;
end;
Falls das nichts mit dem Ausgangs-Problem zu tun hat oder anderweitig unpassend ist... egal, hat mich von meiner regulären Arbeit abgehalten, wodurch sich das für mich schon gelohnt hat :lol:


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:13 Uhr.
Seite 1 von 2  1 2      

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