Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Image in einer ScrollBox richtig positionieren... (https://www.delphipraxis.net/184752-image-einer-scrollbox-richtig-positionieren.html)

Thunder1968 18. Apr 2015 19:26


Image in einer ScrollBox richtig positionieren...
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo und Guten Abend,

seit langem habe ich mal wieder ein Problemchem. Ich habe eine ScrollBox die ein TImage enthält. In dieses TImage wird dann ein PNG-File geladen was ca. 2,5 MB groß ist. Das verschieben des TImages funktioniert problemlos. Aber jetzt möchte ich das ganze mit dem Mausrad vergrößern und auch verkleinern. Mein Problem liegt jetzt darin das ich gerne den aktuellen Mittelpunkt der ScrollBox / TImage auch mittig bleiben soll. Wenn ich das Mausrad betätige (vergrößern, verkleinern) verschiebt sich das TImage so das der aktuell angezeigte Mittelpunkt sich verschiebt und ich dann mit der Maus das die alte Position wieder in die Mitte ziehen muß um es beim nächsten Zoom-Vorgang nicht wieder aus den Augen zu verlieren. :wall: Wo liegt mein Denkfehler oder hat jemand eine Idee??? Wäre auch Dankbar für ein komplettes Beispiel...:oops: Den Quellcode habe ich angehängt und für eine rasche Hilfe wäre ich Euch sehr Dankbar... Bei den beiden Bilder im Anhang soll verdeutlicht werden wie sich das ganze auswirkt und darstellt... :cry: Viele Grüße... :hi::hi::hi:


Delphi-Quellcode:
function TFormMain.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean;
var
   NewScrollPosX, NewScrollPosY : Integer;
   OldScrollPosX, OldScrollPosY : Integer;
   TempValue : Integer;

begin
     // Bild zoomen

     if ssCtrl in Shift then
     begin
          Image1.AutoSize := False;
          Image1.Center := True;
          Image1.Proportional := True;
          Image1.Stretch := True;

          OldScrollPosX := ScrollBox1.HorzScrollBar.Position;
          OldScrollPosY := ScrollBox1.VertScrollBar.Position;

          Image1.Left := Round(Image1.Left - (((Image1.Width * ZoomFactor) - Image1.Width) / 2));
          Image1.Top := Round(Image1.Top - (((Image1.Height * ZoomFactor) - Image1.Height) / 2));
          Image1.Width := Round(Image1.Width * ZoomFactor);
          Image1.Height := Round(Image1.Height * ZoomFactor);

          TempValue := Round(OldScrollPosX * ZoomFactor);
          NewScrollPosX := Round((OldScrollPosY - TempValue) / (ZoomFactor));

          TempValue := Round(OldScrollPosX * ZoomFactor);
          NewScrollPosY := Round((OldScrollPosY - TempValue) / (ZoomFactor));

          ScrollBox1.HorzScrollBar.Position := ScrollBox1.HorzScrollBar.Position + (NewScrollPosX div 2);
          ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position + (NewScrollPosY div 2);
     end;

     Image1.Repaint;

     ScrollBox1.DoubleBuffered := True;
end;

function TFormMain.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean;
var
   NewScrollPosX, NewScrollPosY : Integer;
   OldScrollPosX, OldScrollPosY : Integer;
   TempValue : Integer;

begin
     // Bild verkleinern

     if ssCtrl in Shift then
     begin
          Image1.AutoSize := False;
          Image1.Center := True;
          Image1.Proportional := True;
          Image1.Stretch := True;

          OldScrollPosX := ScrollBox1.HorzScrollBar.Position;
          OldScrollPosY := ScrollBox1.VertScrollBar.Position;

          Image1.Left := Round(Image1.Left + (((Image1.Width * ZoomFactor) - Image1.Width) / 2));
          Image1.Top := Round(Image1.Top + (((Image1.Height * ZoomFactor) - Image1.Height) / 2));
          Image1.Width := Round(Image1.Width / ZoomFactor);
          Image1.Height := Round(Image1.Height / ZoomFactor);

          TempValue := Round(OldScrollPosX / ZoomFactor);
          OldScrollPosX := Round((OldScrollPosX - TempValue) / (ZoomFactor));

          TempValue := Round(OldScrollPosY / ZoomFactor);
          OldScrollPosY := Round((OldScrollPosY - TempValue) / (ZoomFactor));

          ScrollBox1.HorzScrollBar.Position := ScrollBox1.HorzScrollBar.Position - (OldScrollPosX div 2);
          ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position - (OldScrollPosY div 2);
     end;

     Image1.Repaint;

     ScrollBox1.DoubleBuffered := True;
end;

mh18058 22. Mai 2016 22:51

AW: Image in einer ScrollBox richtig positionieren...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Thunder1968,
und an Alle, die sich auch mit dem Thema befassen,

Ich hatte so eine ähnliche Frage, nur daß ich statt eines TImage eine TPaintBox habe.
Die PaintBox ist auf einer ScrollBox und ich zeichne auf die PaintBox eine Vektorgrafik.
Natürlich ist die PaintBox größer als die ScrollBox und die Zeichnung soll sich beim
Zoomen nicht verschieben, sondern genau unter der Maus bleiben.

Ich habe dazu folgende Lösung gefunden:
Im WheelUp und WheelDown ist eine Positionskorrektur durchzuführen. Dazu nehme ich den
Abstand vom Mittelpunkt der PaintBox und der Maus (Fluchtpunkt) und skaliere diesen
Abstand mit Hilfe des Zoom-Faktors nur für diesen einen Schritt. D.h. ich berechne die
Änderung dX/dY um die sich der Mittelpunkt bei einem Zoomschritt verschiebt.
Um diese dX/dY-Werte verschiebe ich dann die Zeichnung unter der Maus sozusagen zurück.
Zum Schluß wird alles mit redraw mit der gewünschten Skalierung neu gezeichnet.
Logischerweise ist der Korrekturfaktor in WheelUp und WheelDown unterschiedlich.
Außerdem: Scrollby(dX,dY) funktioniert zwar, nimmt aber die Scrollbalken nicht mit.
Das alles sieht dann so aus:

Gruß
Martin
P.S.: Wer Lust hat, kann sich auch meinen ZoomTest anschauen.

Delphi-Quellcode:
procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
var P: TPoint;
    dX,dY: Integer;
begin
  inc(MouseWheelTics);
  if MouseWheelTics > 2 then begin
    MouseWheelTics := 0;

    if ((ZoomLevel-1 >= -ZoomLevelRange) and
        (ZoomLevel-1 <= ZoomLevelRange)) then begin
      P := get_MausPos_on_PB;
      zoomIn;

   // Mittelpunktverschiebung korrigieren
      dX := ArithRound((PaintBox1.Width div 2 - P.X) * (ZoomStep-1)/ZoomStep);
      dY := ArithRound((PaintBox1.Height div 2 - P.Y) * (ZoomStep-1)/ZoomStep);
//      ScrollBox1.Scrollby(dX,dY);
      with ScrollBox1 do begin
        with HorzScrollBar do Position := Position + dX;
        with VertScrollBar do Position := Position + dY;
      end;

      redraw(true);
    end;
  end;
end;


procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
var P: TPoint;
    dX,dY: Integer;
begin
  inc(MouseWheelTics);
  if MouseWheelTics > 2 then begin
    MouseWheelTics := 0;

    if ((ZoomLevel+1 >= -ZoomLevelRange) and
        (ZoomLevel+1 <= ZoomLevelRange)) then begin
      P := get_MausPos_on_PB;
      zoomOut;

   // Mittelpunktverschiebung korrigieren
      dX := ArithRound((PaintBox1.Width div 2 - P.X) * (ZoomStep-1));
      dY := ArithRound((PaintBox1.Height div 2 - P.Y) * (ZoomStep-1));
//      ScrollBox1.Scrollby(dX,dY);
      with ScrollBox1 do begin
        with HorzScrollBar do Position := Position - dX;
        with VertScrollBar do Position := Position - dY;
      end;

      redraw(true);
    end;
  end;
end;

Thunder1968 21. Jun 2016 09:02

AW: Image in einer ScrollBox richtig positionieren...
 
Hallo mh18058,

sorry das ich mich jetzt erst melde. Hatte noch andere Projekte und habe deshalb auch nicht mehr so den Fokus auf diesen Beitrag. Vor allem vielen Dank für Dein Beispiel. Sieht echt super aus und funktioniert. Genau soetwas habe ich gesucht.

Vielen Dank... :-D :oops: :thumb:

mh18058 21. Jun 2016 17:41

AW: Image in einer ScrollBox richtig positionieren...
 
Hallo Thunder1968,

gerne doch! :-D
Für Alle, die den Code verwenden wollen:
Ich habe inzwischen festgestellt, daß statt :oops:
Delphi-Quellcode:
  inc(MouseWheelTics);
  if MouseWheelTics > 2 then begin
    MouseWheelTics := 0;
auch einfach :wink:
Delphi-Quellcode:

Handled := true;
geschrieben werden kann. :)
Grüße


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