Graphics32提供了一個名爲TImgView32的組件,可以通過設置Scale屬性進行縮放。這樣做的適當方法是使用OnMouseWheelUp和-Down事件。將TabStop設置爲True以觸發這些事件並將居中設置爲False。但以這種方式縮放不符合您希望將縮放操作放在鼠標光標上的中心。因此,重新定位和調整這一點是一個更好的解決方案。此外,據我所知,圖像總是在組件的左上角對齊,所以平移也必須通過重新定位組件來完成。
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;
編輯:替代與TImage中,而不是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;
哇!這正是我所期待的,NGLN。歡迎來到SO!我通常會找出這樣的代碼,但AFAIK,這將是我唯一使用的G32,所以我真的很感謝你的幫助。最後一個問題:我如何將視圖重置爲程序啓動時的樣子? – RobertFrank 2011-05-18 20:51:19
將初始BoundsRect存儲在單獨的專用字段中,例如FOrgImgBounds。 – NGLN 2011-05-18 21:07:02
備註:除了Graphics32漂亮的繪圖技術之外,此代碼不使用TImgView32的任何高級功能。基本上,你也可以使用標準輕磅TImage。然後你必須重寫縮放代碼,因爲TImage是一個TGraphicControl,並且沒有OnMouseWheel事件。 – NGLN 2011-05-19 06:24:55