Graphics32:通过鼠标拖动平移,用鼠标滚轮放大到鼠标光标 [英] Graphics32: Pan with mouse-drag, zoom to mouse cursor with mouse wheel

查看:132
本文介绍了Graphics32:通过鼠标拖动平移,用鼠标滚轮放大到鼠标光标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我点击并拖动鼠标,并且使用鼠标滚轮的鼠标光标放大/缩小时,我需要实现一个平移。 (在Delphi 2010中,将图像锚定到左,右,顶部,底部的形式。)



我刚刚安装了Graphics32,并看到它的内置滚动酒吧和.Scale允许其中的一些。



问题:



Graphics32是一款很好的工具的东西?有没有其他(可能更简单?)工具,我可以研究一下?



有没有人有任何指针或示例代码如何实现上述?

谢谢。

解决方案

Graphics32提供了一个名为TImgView32的组件,可以通过设置比例财产。这样做的恰当方法是使用OnMouseWheelUp和-Down事件。将TabStop设置为True以触发这些事件并将居中设为假。但是以这种方式缩放不符合您希望将缩放操作置于鼠标光标的位置。所以在这一点上重新定位和调整大小是一个更好的解决方案。此外,据了解,图像始终对齐在组件的左上角,因此平移也必须通过重新定位组件来完成。

 使用
Windows,类,控件,表单,GR32_Image,GR32_Layers,Jpeg;

类型
TForm1 =类(TForm)
ImgView:TImgView32;
procedure FormCreate(Sender:TObject);
procedure ImgViewMouseWheel(Sender:TObject; Shift:TShiftState;
WheelDelta:Integer; MousePos:TPoint; var Handled:Boolean);
procedure ImgViewMouseDown(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer; Layer:TCustomLayer);
procedure FormMouseMove(Sender:TObject; Shift:TShiftState; X,
Y:Integer);
procedure FormMouseUp(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
private
FDragging:Boolean;
FFrom:TPoint;
结束

实现

{$ R * .dfm}

程序TForm1.FormCreate(发件人:TObject);
begin
ImgView.Bitmap.LoadFromFile('D:\Pictures\Mona_Lisa.jpg');
ImgView.TabStop:= True;
ImgView.ScrollBars.Visibility:= svHidden;
ImgView.ScaleMode:= smResize;
结束

procedure TForm1.ImgViewMouseWheel(Sender:TObject; Shift:TShiftState;
WheelDelta:Integer; MousePos:TPoint; var Handled:Boolean);
const
ZoomFactor:Array [Boolean]为Single =(0.9,1.1);
var
R:TRect;
begin
MousePos:= ImgView.ScreenToClient(MousePos);
与ImgView,MousePos do
如果PtInRect(ClientRect,MousePos)然后
开始
R:= BoundsRect;
R.Left:= Left + X - Round(ZoomFactor [WheelDelta> 0] * X);
R.Top:= Top + Y - Round(ZoomFactor [WheelDelta> 0] * Y);
R.Right:= R.Left + Round(ZoomFactor [WheelDelta> 0] * Width);
R.Bottom:= R.Top + Round(ZoomFactor [WheelDelta> 0] * Height);
BoundsRect:= R;
处理:= True;
结束
结束

procedure TForm1.ImgViewMouseDown(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer; Layer:TCustomLayer);
begin
FDragging:= True;
ImgView.Enabled:= False; {临时地将MouseMove转移到父项}
FFrom:= Point(X,Y);
结束

procedure TForm1.FormMouseMove(Sender:TObject; Shift:TShiftState; X,
Y:Integer);
begin
如果FDragging然后
ImgView.SetBounds(X - FFrom.X,Y - FFrom.Y,ImgView.Width,ImgView.Height);
结束

procedure TForm1.FormMouseUp(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
begin
FDragging:= False;
ImgView.Enabled:= True;
ImgView.SetFocus;
结束

编辑:替代TImage而不是TImgView32:

 使用
Windows,Classes,Controls,Forms,Jpeg,ExtCtrls;

type
TForm1 = class(TForm)
图片:TImage;
procedure FormCreate(Sender:TObject);
procedure FormMouseWheel(Sender:TObject; Shift:TShiftState;
WheelDelta:Integer; MousePos:TPoint; var Handled:Boolean);
procedure FormMouseMove(Sender:TObject; Shift:TShiftState; X,
Y:Integer);
procedure FormMouseUp(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
程序ImageDblClick(Sender:TObject);
procedure ImageMouseDown(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
private
FDragging:Boolean;
FFrom:TPoint;
FOrgImgBounds:TRect;
结束

实现

{$ R * .dfm}

程序TForm1.FormCreate(发件人:TObject);
begin
DoubleBuffered:= True;
Image.Picture.LoadFromFile('D:\Pictures\Mona_Lisa.jpg');
Image.Stretch:= True;
Image.Height:= Round(Image.Width * Image.Picture.Height / Image.Picture.Width);
FOrgImgBounds:= Image.BoundsRect;
结束

procedure TForm1.FormMouseWheel(Sender:TObject; Shift:TShiftState;
WheelDelta:Integer; MousePos:TPoint; var Handled:Boolean);
const
ZoomFactor:Array [Boolean]为Single =(0.9,1.1);
var
R:TRect;
begin
MousePos:= Image.ScreenToClient(MousePos);如果PtInRect(ClientRect,MousePos)和((WheelDelta> 0)和
(Height< Self.ClientHeight)和(Width< Self.ClientWidth))的
与Image,MousePos do
)或
((WheelDelta <0)和(Height> 20)和(Width> 20))然后
begin
R:= BoundsRect;
R.Left:= Left + X - Round(ZoomFactor [WheelDelta> 0] * X);
R.Top:= Top + Y - Round(ZoomFactor [WheelDelta> 0] * Y);
R.Right:= R.Left + Round(ZoomFactor [WheelDelta> 0] * Width);
R.Bottom:= R.Top + Round(ZoomFactor [WheelDelta> 0] * Height);
BoundsRect:= R;
处理:= True;
结束
结束

procedure TForm1.FormMouseMove(Sender:TObject; Shift:TShiftState; X,
Y:Integer);
begin
如果FDragging然后
Image.SetBounds(X - FFrom.X,Y - FFrom.Y,Image.Width,Image.Height);
结束

procedure TForm1.FormMouseUp(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
begin
Image.Enabled:= True;
FDragging:= False;
结束

procedure TForm1.ImageDblClick(Sender:TObject);
begin
Image.BoundsRect:= FOrgImgBounds;
结束

procedure TForm1.ImageMouseDown(Sender:TObject; Button:TMouseButton;
Shift:TShiftState; X,Y:Integer);
开始
如果没有(ssDouble在Shift)然后
开始
FDragging:= True;
Image.Enabled:= False;
FFrom:=点(X,Y);
MouseCapture:= True;
结束
结束


I need to implement a pan as I click and drag the mouse, and zoom/unzoom towards/away from the mouse cursor that uses the mouse wheel. (In Delphi 2010, with the image anchored to left,right,top,bottom the form.)

I've just installed Graphics32 and seen how its built-in scroll bars and .Scale allow some of this. It's tantalizingly easy to at least get that far.

Questions:

Is Graphics32 a good tool for this kind of thing? Are there other (perhaps more simple?) tools that I might look into?

Does anyone have any pointers or sample code on how to implement the above?

Thanks.

解决方案

Graphics32 provides a component named TImgView32 which can zoom by setting the Scale property. The appropriate way to do so is by using the OnMouseWheelUp and -Down events. Set TabStop to True for triggering these events and set Centered to False. But scaling in this manner does not comply with your wish to center the zooming operation at the mouse cursor. So repositioning and resizing around that point is a nicer solution. Further, as I understand, the image is always aligned in the top-left corner of the component, so panning must also be accomplished by repositioning the component.

uses
  Windows, Classes, Controls, Forms, GR32_Image, GR32_Layers, Jpeg;

type
  TForm1 = class(TForm)
    ImgView: TImgView32;
    procedure FormCreate(Sender: TObject);
    procedure ImgViewMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure ImgViewMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    FDragging: Boolean;
    FFrom: TPoint;
  end;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  ImgView.Bitmap.LoadFromFile('D:\Pictures\Mona_Lisa.jpg');
  ImgView.TabStop := True;
  ImgView.ScrollBars.Visibility := svHidden;
  ImgView.ScaleMode := smResize;
end;

procedure TForm1.ImgViewMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
const
  ZoomFactor: array[Boolean] of Single = (0.9, 1.1);
var
  R: TRect;
begin
  MousePos := ImgView.ScreenToClient(MousePos);
  with ImgView, MousePos do
    if PtInRect(ClientRect, MousePos) then
    begin
      R := BoundsRect;
      R.Left := Left + X - Round(ZoomFactor[WheelDelta > 0] * X);
      R.Top := Top + Y - Round(ZoomFactor[WheelDelta > 0] * Y);
      R.Right := R.Left + Round(ZoomFactor[WheelDelta > 0] * Width);
      R.Bottom := R.Top + Round(ZoomFactor[WheelDelta > 0] * Height);
      BoundsRect := R;
      Handled := True;
    end;
end;

procedure TForm1.ImgViewMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
  FDragging := True;
  ImgView.Enabled := False; { Temporarily, to get MouseMove to the parent }
  FFrom := Point(X, Y);
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if FDragging then
    ImgView.SetBounds(X - FFrom.X, Y - FFrom.Y, ImgView.Width, ImgView.Height);
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FDragging := False;
  ImgView.Enabled := True;
  ImgView.SetFocus;
end;

Edit: Alternative with TImage instead of TImgView32:

uses
  Windows, Classes, Controls, Forms, Jpeg, ExtCtrls;

type
  TForm1 = class(TForm)
    Image: TImage;
    procedure FormCreate(Sender: TObject);
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure ImageDblClick(Sender: TObject);
    procedure ImageMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    FDragging: Boolean;
    FFrom: TPoint;
    FOrgImgBounds: TRect;
  end;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  DoubleBuffered := True;
  Image.Picture.LoadFromFile('D:\Pictures\Mona_Lisa.jpg');
  Image.Stretch := True;
  Image.Height := Round(Image.Width * Image.Picture.Height / Image.Picture.Width);
  FOrgImgBounds := Image.BoundsRect;
end;

procedure TForm1.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;
begin
  MousePos := Image.ScreenToClient(MousePos);
  with Image, MousePos do
    if PtInRect(ClientRect, MousePos) and ((WheelDelta > 0) and
      (Height < Self.ClientHeight) and (Width < Self.ClientWidth)) or
      ((WheelDelta < 0) and (Height > 20) and (Width > 20)) then
    begin
      R := BoundsRect;
      R.Left := Left + X - Round(ZoomFactor[WheelDelta > 0] * X);
      R.Top := Top + Y - Round(ZoomFactor[WheelDelta > 0] * Y);
      R.Right := R.Left + Round(ZoomFactor[WheelDelta > 0] * Width);
      R.Bottom := R.Top + Round(ZoomFactor[WheelDelta > 0] * Height);
      BoundsRect := R;
      Handled := True;
    end;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if FDragging then
    Image.SetBounds(X - FFrom.X, Y - FFrom.Y, Image.Width, Image.Height);
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Image.Enabled := True;
  FDragging := False;
end;

procedure TForm1.ImageDblClick(Sender: TObject);
begin
  Image.BoundsRect := FOrgImgBounds;
end;

procedure TForm1.ImageMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if not (ssDouble in Shift) then
  begin
    FDragging := True;
    Image.Enabled := False;
    FFrom := Point(X, Y);
    MouseCapture := True;
  end;
end;

这篇关于Graphics32:通过鼠标拖动平移,用鼠标滚轮放大到鼠标光标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆