Delphi-PRAXiS

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:

Memnarch 20. Mai 2011 11:03

AW: Zichenen sowie ab wann ist alles verfügbar?
 
wenn du mir kurz erklärst warum du im hintergund immer die birmaps Bitmaps switched?
den wenn beim ersten mal auf A gezeichnet wird, und beim zweiten mal auf B, ist der inhalt ja nicht gleich ..oder? o.O

DeddyH 20. Mai 2011 11:07

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Ich habe den Code nicht wirklich nachvollzogen, aber so etwas macht man aus Performance-Gründen. Während die eine Bitmap dargestellt wird, können währenddessen bereits Aktualisierungen auf der zweiten erfolgen und diese dann auf einen Rutsch bei Eintreten eines definierten Ereignisses wiederum dargestellt werden. Inwieweit das für Dich sinnvoll oder erfoderlich ist musst Du selbst entscheiden.

Memnarch 20. Mai 2011 11:19

AW: Zichenen sowie ab wann ist alles verfügbar?
 
tja, nur werden die bitmaps nicht abgeglichen. Es wird nacheinander auf 2 verschiedene bitmaps zu unterschiedlichen zeitpunkten gezeichnet.

Resultat -> Asynchroner inhalt..

Satty67 20. Mai 2011 11:51

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Ist ja nur ein Konzept, das ganze auf nur ein Bitmap zu reduzieren ist ja nicht verboten.

Wie weit der Inhalt sich entwickelt und dabei nicht komplett neu aufgebaut wird, wusste ich ja nicht.

Luckie 20. Mai 2011 12:09

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Hier das ganze mit einem Bitmap: http://www.michael-puff.de/Programmi...enBitmap.shtml

Wolfgang Mix 20. Mai 2011 12:51

AW: Zichenen sowie ab wann ist alles verfügbar?
 
Ändere mal bitte deinen Titel. So bekommt man Augenkrebs :-)

Memnarch 20. Mai 2011 14:15

AW: Zeichnen sowie ab wann ist alles verfügbar?
 
Wollte ich gestern schon geändert haben, hate aber da nur den schnelleditor benutzt wo dass nicht geht, hatte ganz vergessen im erweiterten editor nachzugucken :wall:

Sunlight7 20. Mai 2011 15:49

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

ab wann ist alles verfügbar?
Eigentlich sollte das der Fall sein, wenn Delphi-Referenz durchsuchenLoaded aufgerufen wird.

Du kannst Loaded überschreiben um Deinen Senf dazu zu geben.
Die Objekte sind zu diesem Zeitpunkt noch nicht sichtbar.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:49 Uhr.

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