Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Verständnisfrage GDI+ Bewegen von gezeichneten Objekten (https://www.delphipraxis.net/192017-verstaendnisfrage-gdi-bewegen-von-gezeichneten-objekten.html)

TheProfi 13. Mär 2017 18:08


Verständnisfrage GDI+ Bewegen von gezeichneten Objekten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Moin zusammen,

ich hoffe ich stelle hier nicht eine Frage die es schon als Antwort gibt. Gesucht hatte ich schon.

Ausgangssituation:
Ich nutze die GDI+ Library von www.bilsen.com/gdiplus und schreibe derzeit eine Komponente die Objekte (Shapes) z.B. filledRectangles mit Verbindungslinien erstellt, Datenbank gebunden.

Das Zeichnen funktioniert soweit ganz gut. Was mir noch nicht klar ist, muss ich immer alles neu Zeichnen, wenn ich ein Shape verschiebe?

Bislang mache ich folgendes bei
MouseDown: Objekt identifizieren (Hit) und merken
MouseMove: Objekt löschen und mit neuen Koordinaten von der Mousebewegung neu zeichnen, da aber noch einige Linien daran hängen und Linien durch Objekte laufen, zeichne immer alles neu. Das führt zu flackern trotz doublebuffered.

Fragen:
- Muss ich für alles sogenannte Kollisionabfragen machen, damit ich feststellen kann, welche Objekte ich neu zeichnen muss (reduzierte Menge).
- Gibt es bei GDI+ so etwas wie zeichnen mit Penmode mit Copy, XOR

Würde mich freuen wenn ihr Ratschläge habt die auch mit GDI+ funktionieren.

jfheins 13. Mär 2017 19:03

AW: Verständnisfrage GDI+ Bewegen von gezeichneten Objekten
 
Erstmal wäre ein bisschen Code hilfreich. Wenn du Repaint() benutzt: Das löscht erst mal alles und zeichnet dann neu. Das wird immer flackern.

Deine Grafik sieht jetzt nicht soo komplex aus, daher sollte es eigentlich kein Problem sein wenn du immer alles neu zeichnest. Es sei denn, diese Balken müssen jedes mal neu berechnet werden. Dann könntest du bspw. die Boxen auf eigene Bitmaps zeichnen (cachen) und dann diese auf das große Canvas malen.

DoubleBuffered kannst du eigentlich auch aus machen, das machst du ja ohnehin selbst, oder? Also erst mal ein neues Bitmap anlegen, dann schön alles hin zeichnen und dann in einem Schritt das Bitmap auf die Paintbox malen.

stahli 13. Mär 2017 19:38

AW: Verständnisfrage GDI+ Bewegen von gezeichneten Objekten
 
Zwei Überlegungen:

Du könntest das Neuzeichnen in einem Thread und einem extra Bitmap durchführen und erst das Ergebnis in dein Formular kopieren.

Oder Du könntest nur Deine Controls beim Verschieben neu zeichnen und die Linien später nachträglich in einem Thread berechnen, wenn die Positionen feststehen.

EWeiss 13. Mär 2017 22:14

AW: Verständnisfrage GDI+ Bewegen von gezeichneten Objekten
 
Zitat:

Das Zeichnen funktioniert soweit ganz gut. Was mir noch nicht klar ist, muss ich immer alles neu Zeichnen, wenn ich ein Shape verschiebe?
Definitiv.
Zitat:

MouseDown: Objekt identifizieren (Hit) und merken
Nicht nötig kann man in MouseMove Ereignis analysieren. Siehe PtInRect.
Zitat:

Gibt es bei GDI+ so etwas wie zeichnen mit Penmode mit Copy, XOR
Klar gibt es das.
Zitat:

DoubleBuffered kannst du eigentlich auch aus machen, das machst du ja ohnehin selbst, oder? Also erst mal ein neues Bitmap anlegen, dann schön alles hin zeichnen und dann in einem Schritt das Bitmap auf die Paintbox malen.
Warum soll er den DoubleBuffer ausmachen?
Letztendlich macht doch Doublebuffer nichts anderes als ein temporäres Bitmap zu erstellen und darauf zu zeichnen.

Delphi-Quellcode:
function TSkinEngine.DoubleBuffer(hDC: longword; x: integer; y: integer;
  Action: TAction): HDC;
begin

  if Action = CreateBuffer then
  begin
    FDBufferhDCTemp := CreateCompatibleDC(hDC);
    FDBufferhBMTemp := CreateCompatibleBitmap(hDC, x, y);
    FDBufferhBMPrev := SelectObject(FDBufferhDCTemp, FDBufferhBMTemp);
    FDBufferXx := x;
    FDBufferYy := y;
    FDBufferUseDC := hDC;
    Result := FDBufferhDCTemp;
  end
  else
  begin
    // Zeichne das Resultat ins Target Window
    BitBlt(FDBufferUseDC, x, y, FDBufferXx, FDBufferYy, FDBufferhDCTemp,
      0, 0, SRCCOPY);
    // Befreie die system resourcen
    SelectObject(FDBufferhDCTemp, FDBufferhBMPrev);
    DeleteObject(FDBufferhBMTemp);
    DeleteDC(FDBufferhDCTemp);
    Result := 0;
  end;

end;
gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:36 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