Entwickler-Ecke

Multimedia / Grafik - Grafikproblem: Flimmern bei Verschieben von Polygonen


JDKDelphi - Mi 18.08.10 13:58
Titel: Grafikproblem: Flimmern bei Verschieben von Polygonen
Hallo Delphi-Freunde,

ich habe folgendes Problem:

Ein von mir entwickeltes Steuerelement erlaubt ein Verschieben von Polygonen innerhalb einer Bitmap.Canvas.
Das Steuerelement besteht aus einer Scrollbox mit einem Image. Zweck dieses Steuerelemntes ist, datenbankunabhängig
Polygone zu plazieren und zu bearbeiten. Das ganze funktioniert auch schön und als OCX ist das nun auch verfügbar.
Wir binden das in unserem ERP-System(Betonverarbeitung) ein, um Produktionsplanung zur Verfügung zu stellen.

Ein kleiner Schönheitsfehler ist, das wenn ich etwas interaktiv verschiebe, die ganze Grafik flimmert.

Wie kann ich "REPAINT" "Inavalidate" etc. im Moment der Verschiebeaktion unterbinden?

Vielleicht habt Ihr einen schnellen Tip auf lager.


Vielen Dank

und

Gruß


glotzer - Mi 18.08.10 14:08

yep, double buffering ist der trick..

du zeichnest das bild auf eine graphik im speicher, und in regelmäsigen abständen zeichnest du die graphik dann auf das formular oder sontswohin.
nicht vergessen die graphik vor jeden neuen bezeichnen "freizuräumen" also mit weiß füllen oder so


JDKDelphi - Mi 18.08.10 14:10

Danke.

Das hatte ich auch schon gedacht.
Allerdings braucht das Steuerelement ganz schön viel Speicher.
Gibts da nicht noch einen Trick, das Neuzeichnen vom Betriebssystem einfach zu unterdrücken und nur bei Ende der Operation aufzurufen?


JDKDelphi - Mi 18.08.10 14:15

Bei TImage gibt's leider keine Property Doublebufferd

Die kommt nur bei TWinControl


glotzer - Mi 18.08.10 14:34

paint message von abfangen und nur zeichnen wenn erwünscht?


JDKDelphi - Mi 18.08.10 14:43

Danke.

Wäre ja schön, wenn das auch bei onMouseMove(..) geht.
Wie gesagt, ein markiertes Objekt soll verschoben werden. Zur Anzeige nutze ich DrawFocusRect(..).
Vorher wird das umschließende Rechteck der Grafik ermittelt, damit der User die Umrisse sieht.

Ich poste hier mal kurz Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
procedure TLane.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
var apos    : Tpoint;
    iRec    : TRect;
begin
  if ssleft in Shift THEN
  BEGIN
    //
    IF fmouseact = madraw THEN
    BEGIN
      image1.Canvas.DrawFocusRect(rect(fp_ol.X,fp_ol.Y,fp_ur.X,fp_ur.Y));
      image1.Canvas.DrawFocusRect(rect(fp_ol.X,fp_ol.Y,X,Y));
    END;
    //
    IF fmouseact = mamove THEN
    BEGIN
      IF fAktiveObj < 0 THEN
      BEGIN
        image1.Canvas.Brush.Color := clWhite;
        image1.Canvas.Pen.Color := clBlack;
        image1.Canvas.DrawFocusRect(fmfokus);
      //
        fp_ol.X := x;  fp_ol.Y := y;
        fmfokus.TopLeft := fp_ol;
        apos.X := fm_rect.Right+fp_ol.X;
        apos.Y := fm_rect.Bottom + fp_ol.Y;
        fmfokus.BottomRight := apos;
        fmfokus := srect(fmfokus);
        image1.Canvas.Pen.Color := clBlack;
        image1.Canvas.DrawFocusRect(fmfokus);
      END
      ELSE
      BEGIN
        image1.Canvas.Brush.Color := clWhite;
        image1.Canvas.Pen.Color := clBlack;
        image1.Canvas.DrawFocusRect(fmfokus);
        fp_ol.X := x;  fp_ol.Y := y;
        irec  := fworkobjekt.PrepareDrawRect;
        fmfokus.TopLeft := fp_ol;
        apos.X := irec.Right + fp_ol.X;
        apos.Y := irec.Bottom + fp_ol.Y;
        fmfokus.BottomRight := apos;
        fmfokus := srect(fmfokus);

        image1.Canvas.Pen.Color := clBlack;
        image1.Canvas.DrawFocusRect(fmfokus);
      END;
    END;
    fp_ur.X := x;  fp_ur.Y := y;
  END;
end;


Das ganze Steuerelement besteht aus ca. 5500 Zeilen Code.
Nur dieser kleine Schönheitsfehler, den würde ich ganz gerne mal wegbekommen.

Danke nochmals


glotzer - Mi 18.08.10 14:45

dann wirst du wohl um eine graphik im speicher nicht drumm herum kommen


JDKDelphi - Mi 18.08.10 14:52

Ich glaube auch.

Im Anhang findet Ihr mal ein PDF, wie das ganze im ERP-System aussieht

Grüße


platzwart - Mi 18.08.10 15:19

Das DoubleBuffered musst du bei der Form1 auf true setzen, das gilt dann Programmweit...


Xion - Mi 18.08.10 15:51

user profile iconplatzwart hat folgendes geschrieben Zum zitierten Posting springen:
Das DoubleBuffered musst du bei der Form1 auf true setzen, das gilt dann Programmweit...

So stimmt das glaub ich nicht ganz. Allerdings ist das wohl die einfachste Realisierung, nur musst du:

user profile iconJDKDelphi hat folgendes geschrieben Zum zitierten Posting springen:
Das Steuerelement besteht aus einer Scrollbox mit einem Image.


ScrollBox.DoubleBuffered:=True; setzen. (falls das Image da drin liegt)


JDKDelphi - Mi 18.08.10 17:34

Hey Xion,

DASS IST DER TIPP

Ich probier's morgen mal..

Wenn dass klappt, GROSSES DANKE AN ALLE IM DELPHIFORUM !!!!


mit Gruss


JDKDelphi - Do 19.08.10 07:51

Hallo Delphifreunde,

das Problem mit dem Flimmern ist gelöst!!

Kleine Anweisung, große Wirkung....


Vielen Dank


JDKDelphi - Do 19.08.10 18:23

@XION

Beste Grüße und ein großes Danke für Deinen Tipp.

Hat funktioniert..


Grüße