Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Umgang mit TScrollbox/TImage/TPaintbox (https://www.delphipraxis.net/175991-umgang-mit-tscrollbox-timage-tpaintbox.html)

Mikkey 5. Aug 2013 14:34

Delphi-Version: 5

Umgang mit TScrollbox/TImage/TPaintbox
 
Hallo Forum, ich bin sowohl hier neu als auch neu in Delphi.

Ich versuche ein Programm zu erstellen, in dem grafisch gezeige Objekte in einer Zeichenfläche bearbeitet werden.

Wenn beim Bearbeiten sich die Größe der Zeichenfläche (SetBounds()) ändert, während die Scrollposition gut vom Ursprung entfernt ist, erfolgt die neue Ausgabe der Grafik in der linken oberen Ecke des gezeigten Ausschnitts. Sie sollte aber in der linken oberen Ecke der Zeichenfläche beginnen, die natürlich dann nicht sichtbar ist.

Der Effekt tritt sowohl mit TPaintbox als auf mit TImage auf (jeweils einer TScrollBox untergeordnet).

Ich hoffe, ich habe nur irgendwas Dummes vergessen oder übersehen und hoffe auf Erkenntnis.

Mikkey

Mikkey 7. Aug 2013 15:49

Ergänzung
 
ich habe das Verhalten in einem einfachen Programm nachgestellt und bilde es hier ab.
Durch Mausklick irgendwo in die Zeichenfläche wird die Größe verändert. Ist die darstellung bereits gescrollt, beginnt das neue Zeichnen nicht oben im Dokument, sondern oben im gerade gezeigten Ausschnitt.

Delphi-Quellcode:
procedure TForm1.MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Randomize();
  fSize.cx := RandomRange(400, 5000);
  fSize.cy := RandomRange(400, 5000);
  szChanged := true;
  PaintPaintBox(PaintBox1);
  Invalidate();
end;

procedure TForm1.PaintPaintBox(Sender: TObject);
var
  x, y: Integer;
  s:String;
  pt: TPoint;
begin
  PaintBox1.canvas.Font.Height := 14;
  if szchanged then begin
    PaintBox1.SetBounds(0, 0, fSize.cx, fSize.cy);
    szChanged := false;
  end;
  pt.X := 0; pt.Y := 0;
  pt := ScrollBox1.ParentToClient(pt, nil);
  pt.X := 0; pt.Y := 0;
  pt := ScrollBox1.ClientToParent(pt, nil);
  y := 0;
  while y < fSize.cy do begin
    x := 0;
    while x < fSize.cx do begin
      s := Format('(%d, %d)', [x, y]);
      pt.x := x;
      pt.Y := y;
      pt := PaintBox1.ClientToParent(pt);
      PaintBox1.canvas.TextOut(pt.x, pt.y, s);
      x := x + 200;
    end;
    y := y + 100;
  end;
end;
Ich hoffe, irgendjemand mag sich das mal anschauen.

stahli 7. Aug 2013 16:22

AW: Umgang mit TScrollbox/TImage/TPaintbox
 
Ich weiß zwar noch nicht genau, was Du meinst, aber hilöft Dir vielleicht, die aktuellen Positionen der Scrollbars vom Offset abzuziehen?
Du beginnst dann nicht bei 0,0 sondern bei -HorzScrollBar.Position, -VertScrollBar.Position.

Hilft das irgendwie?

sx2008 7. Aug 2013 17:31

AW: Umgang mit TScrollbox/TImage/TPaintbox
 
Du kannst doch im OnPaint-Event der Paintbox nicht die Größe der Paintbox ändern!
So forderst du die Probleme ja geradezu heraus.

Mikkey 7. Aug 2013 17:58

AW: Umgang mit TScrollbox/TImage/TPaintbox
 
Vielen Dank für die Idee. Das war's zwar nicht, aber wenn man als untere Grenzen bei SetBounds die ermittelte Scrollposition (negativ) einsetzt

- und die oberen Grenzen so beibehält -

Dann funktioniert es.

Komische Logik...

Gruß, Mikkey

stahli 7. Aug 2013 18:10

AW: Umgang mit TScrollbox/TImage/TPaintbox
 
Schön, aber sx2008 hat Recht.
Im OnPaint-Event sollte man keine Größenänderung durchführen und keine Neuzeichnung initiieren.
Falls PaintPaintBox Deine OnPaint-Behandlung ist, dann solltest Du das nochmal überarbeiten.

Z.B. könntest Du einen Timer starten, der dann die Größe der Paintbox anpasst.
Oder häng mal hier ein kleines Dempoprojekt an, dann können wir das mal genauer anschauen...

Mikkey 8. Aug 2013 06:50

AW: Umgang mit TScrollbox/TImage/TPaintbox
 
Zitat:

Zitat von stahli (Beitrag 1223912)
Schön, aber sx2008 hat Recht.
Im OnPaint-Event sollte man keine Größenänderung durchführen und keine Neuzeichnung initiieren.
Falls PaintPaintBox Deine OnPaint-Behandlung ist, dann solltest Du das nochmal überarbeiten.

Das mag ja sein, aber wenn ich das obige Programmstück so modifiziere, tritt der beschriebene Effekt ebenfalls auf (PaintPaintbox ist jetzt die OnPaint-Routine):


Delphi-Quellcode:
procedure TForm1.MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  pt: TPoint;
begin
  Randomize();
  fSize.cx := RandomRange(4000, 5000);
  fSize.cy := RandomRange(4000, 5000);
  pt.X := 0; pt.Y := 0;
  pt := PaintBox1.ClientToParent(pt, nil);
  //PaintBox1.SetBounds(pt.x, pt.y, pt.x + fSize.cx, pt.y + fSize.cy);
  PaintBox1.SetBounds(0, 0, pt.x + fSize.cx, pt.y + fSize.cy);
  Invalidate();
end;

procedure TForm1.PaintPaintBox(Sender: TObject);
var
  x, y: Integer;
  s:String;
begin
  PaintBox1.canvas.Font.Height := 14;
  y := 0;
  while y < fSize.cy do begin
    x := 0;
    while x < fSize.cx do begin
      s := Format('(%d, %d)', [x, y]);
      PaintBox1.canvas.TextOut(x, y, s);
      x := x + 200;
    end;
    y := y + 100;
  end;
end;
Wenn die andere SetBounds-Zeile aktiviert wird, ist alles ok (*), in dieser Variante beginnt die Ausgabe mitten im Dokument. Das "Programm" besteht aus nicht mehr als den geposteten beiden Methoden.

(*) Das Dokument sollte nach SetBounds in beiden Richtungen eine Größe von 4000-5000 Pixeln haben, tatsächlich ist die letzte Ausgabe aber immer (1800, 1400), der Bereich außerhalb von ca. 2000,1500 ist grau.

Any Idea?

Gruß, Mikkey

Volker Z. 9. Aug 2013 01:51

AW: Umgang mit TScrollbox/TImage/TPaintbox
 
Hallo,

ich weiß jetzt nicht, ob ich Dein Problem so richtig verstanden habe; aber vielleicht bringt Dich nachfolgender Code ein Stückchen weiter.
Delphi-Quellcode:
uses System.Math;

procedure TForm1.FormCreate(Sender: TObject);
begin
  PaintBox1.Font.Size := 14;
  Randomize
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  px , py : Integer;
begin
  px := ScrollBox1.HorzScrollBar.Position;
  py := ScrollBox1.VertScrollBar.Position;

  ScrollBox1.HorzScrollBar.Position := 0;
  ScrollBox1.VertScrollBar.Position := 0;
  PaintBox1.SetBounds (0, 0, RandomRange (4000, 5000), RandomRange (4000, 5000));

  ScrollBox1.HorzScrollBar.Position := px;
  ScrollBox1.VertScrollBar.Position := py
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  x, y : Integer;
begin
   y := 0;
   while y < Paintbox1.Height do
     begin
       x := 0;
       while x < Paintbox1.Width do
         begin
           PaintBox1.Canvas.TextOut (x, y, Format ('(%d, %d)', [x, y]));
           Inc (x, 200)
         end;

       Inc (y, 100)
     end
end;
Gruß

Mikkey 12. Aug 2013 10:44

AW: Umgang mit TScrollbox/TImage/TPaintbox
 
Zitat:

Zitat von Volker Z. (Beitrag 1224087)
Hallo,
ScrollBox1.HorzScrollBar.Position := 0;
ScrollBox1.VertScrollBar.Position := 0;
PaintBox1.SetBounds (0, 0, RandomRange (4000, 5000), RandomRange (4000, 5000));

ScrollBox1.HorzScrollBar.Position := px;
ScrollBox1.VertScrollBar.Position := py

Vielen dank für diese Idee, das müsste im Prinzip auch funktionieren. Aber inzwischen geht es ja auch mit den etwas merkwürdig gesetzten Parametern in SetBounds.

Gruß, Mikkey


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