I have a VCL MDI Application in Delphi 10.4, and I have an image browser in it using a modal form. Recently I was asked to implement a zooming functionality in that form. It's not a mandatory requirement, but I was trying with a zoom triggered by the mouse wheel, and centered at the mouse cursor.
I got the code suggested here
procedure TfrmVisualizaImagem.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
const
ZoomFactor: array[Boolean] of Single = (0.9, 1.1);
var
R: TRect;
Postion: TPoint;
begin
Position := ImgRecibo.ScreenToClient(MousePos);
if PtInRect(imgRecibo.ClientRect, Position) and ((WheelDelta > 0) or
((WheelDelta < 0) and (imgRecibo.Height > 20) and (imgRecibo.Width > 20))) then
begin
R := imgRecibo.BoundsRect;
R.Left := imgRecibo.Left + Position.X - Round(ZoomFactor[WheelDelta > 0] * Position.X);
R.Top := imgRecibo.Top + Position.Y - Round(ZoomFactor[WheelDelta > 0] * Position.Y);
R.Right := R.Left + Round(ZoomFactor[WheelDelta > 0] * imgRecibo.Width);
R.Bottom := R.Top + Round(ZoomFactor[WheelDelta > 0] * imgRecibo.Height);
imgRecibo.BoundsRect := R;
Handled := True;
end;
end;
At first glance it works fine, but after zooming in a few times the image begin to slide to the right and up. I put a memo in the form to visualize what was happening inside the Mouse wheel event and I realized that, even with the mouse steady at the same point, after a few zooming in, the MousePos began to change.
MousePos: 851,439 Position: 215,175 Rect: -22,-18,690,989 Imagem: 712,1007
MousePos: 851,439 Position: 237,193 Rect: -46,-37,737,1071 Imagem: 783,1108
MousePos: 851,439 Position: 261,212 Rect: -72,-58,789,1161 Imagem: 861,1219
MousePos: 851,439 Position: 287,233 Rect: -101,-81,846,1260 Imagem: 947,1341
MousePos: 851,439 Position: 316,256 Rect: -133,-107,909,1368 Imagem: 1042,1475
MousePos: 984,546 Position: 481,389 Rect: -181,-146,965,1477 Imagem: 1146,1623*
So, anyone knows why this is happening and how to fix it?
I have a VCL MDI Application in Delphi 10.4, and I have an image browser in it using a modal form. Recently I was asked to implement a zooming functionality in that form. It's not a mandatory requirement, but I was trying with a zoom triggered by the mouse wheel, and centered at the mouse cursor.
I got the code suggested here
procedure TfrmVisualizaImagem.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
const
ZoomFactor: array[Boolean] of Single = (0.9, 1.1);
var
R: TRect;
Postion: TPoint;
begin
Position := ImgRecibo.ScreenToClient(MousePos);
if PtInRect(imgRecibo.ClientRect, Position) and ((WheelDelta > 0) or
((WheelDelta < 0) and (imgRecibo.Height > 20) and (imgRecibo.Width > 20))) then
begin
R := imgRecibo.BoundsRect;
R.Left := imgRecibo.Left + Position.X - Round(ZoomFactor[WheelDelta > 0] * Position.X);
R.Top := imgRecibo.Top + Position.Y - Round(ZoomFactor[WheelDelta > 0] * Position.Y);
R.Right := R.Left + Round(ZoomFactor[WheelDelta > 0] * imgRecibo.Width);
R.Bottom := R.Top + Round(ZoomFactor[WheelDelta > 0] * imgRecibo.Height);
imgRecibo.BoundsRect := R;
Handled := True;
end;
end;
At first glance it works fine, but after zooming in a few times the image begin to slide to the right and up. I put a memo in the form to visualize what was happening inside the Mouse wheel event and I realized that, even with the mouse steady at the same point, after a few zooming in, the MousePos began to change.
MousePos: 851,439 Position: 215,175 Rect: -22,-18,690,989 Imagem: 712,1007
MousePos: 851,439 Position: 237,193 Rect: -46,-37,737,1071 Imagem: 783,1108
MousePos: 851,439 Position: 261,212 Rect: -72,-58,789,1161 Imagem: 861,1219
MousePos: 851,439 Position: 287,233 Rect: -101,-81,846,1260 Imagem: 947,1341
MousePos: 851,439 Position: 316,256 Rect: -133,-107,909,1368 Imagem: 1042,1475
MousePos: 984,546 Position: 481,389 Rect: -181,-146,965,1477 Imagem: 1146,1623*
So, anyone knows why this is happening and how to fix it?
Share Improve this question edited Feb 4 at 19:05 Luis Enrique asked Feb 3 at 2:25 Luis EnriqueLuis Enrique 111 silver badge2 bronze badges 3 |2 Answers
Reset to default 2When you calculate some positions with rounding a lot of times, small errors are accumulated, so you can see shifting and sometimes diistortions.
You have to exclude recalculating based on current position.
Instead calculate shift and scale factors and apply it on initial coordinates
This is happening because you have Proportional property set to true.
What Proportional
property does is it shrinks the image in order to fit the control while maintaining the aspect ration. But if the size of TImage
is larger than the dimensions of the picture the picture never gets stretched in order to fit the TImage
control.
And since picture position within TImage
control is always aligned to top left corner and you are changing the position of your TImage
control it seems as the image starts moving in left and up direction.
How to solve this? Instead of setting Proportional
property to True
set the Stretch property to True
.
However you will need to make sure that you adjust the Width
and Height
of your TImage
in order to maintain aspect ratio of the loaded picture. After that your code will work just nicely.
How do you do this? Check the FormCreate
event method in the linked SO answer you got your code from.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745251772a4618720.html
MousePos
variable does not represent the position of the mouse on the screen, but the position in theImgRecibo
control. And you move that control with setting itsBoundRect
. Please show us your code that writes the output. – NGLN Commented Feb 4 at 14:56