许多基于Windows操作系统的多媒体、游戏、图像处理软件,为用户提供了功能强大、技术复杂的图像漫游功能。软件运行时,用户只需轻松移动鼠标(或操纵键盘方向键),即可观察屏幕显示区域之外的其余图像。那么,如何在自己的程序中实现图像漫游技术?不少文章就此问题提出过解决方案,例如:①通过调用Windows API函数(如StretchBlt);②通过直接读写内存等。上述方法的优点是:直接调用系统底层资源,程序运行速度较快;缺点是:①法可能产生屏幕闪烁现象,不利于用户使用;②法程序设计复杂、不易掌握,容易出错。在开发某应用软件系统过程中,笔者总结出利用VB、Delphi等RAD实现图像漫游的便捷方法,现介绍如下。
- 基本思路
1、为感知鼠标事件,应对控件的MouseDown、MouseUp、MouseMove事件进行编程。
2、为感知键盘事件,应对窗体的KeyDown事件进行编程。
3、为获得不同图像漫游效果,可设置一逻辑变量MoveOrNot。
效果一:在MouseDown事件中将MoveOrNot设为True;在MouseUp事件中将MoveOrNot设为False;在MouseMove事件中当MoveOrNot为True时改变Image控件的(Left,Top),否则不移动Image,产生类似于著名看图软件ACDSee32中拖动图像的漫游效果。
效果二:在MouseDown事件中将MoveOrNot设为True;在MouseMove事件中改变Image控件的(Left,Top),产生不需拖动、图像随鼠标即指即移的漫游效果。
- 编程步骤
㈠利用VB编程
1、在Visual Basic IDE中新建工程1(包含Form1),在Form1上放置Image1、Label1。
2、“通用”棗“声明”代码如下:
Private Type POINTAPI '类型声明
X As Long
Y As Long
End Type
Dim Old As POINTAPI '保存鼠标原来的X、Y坐标
Dim ImageLeft, ImageTop As Integer '保存Image原来的Left、Top值
Dim MoveOrNot As Boolean
3、Form_Load事件代码如下:
Private Sub Form_Load()
Me.WindowState = 2 '窗口最大化
Image1.Stretch = False
Image1.Picture = LoadPicture(App.Path + "Map.jpg")
Image1.Top = 0
Image1.Left = 0
Label1.BackStyle = 0 '使Label透明
Label1.Move 0, 0, Screen.Width, Screen.Height
End Sub
4、Form_KeyDown事件代码如下:
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode '判断上、下、左、右方向键
Case vbKeyLeft
If Image1.Left > Form1.Width - Image1.Width + 100 Then
Image1.Left = Image1.Left - 100
Else
Image1.Left = Form1.Width - Image1.Width
End If
Case vbKeyRight
If Image1.Left < -100 Then
Image1.Left = Image1.Left + 100
Else
Image1.Left = 0
End If
Case vbKeyUp
If Image1.Top > Form1.Height - Image1.Height + 100 Then
Image1.Top = Image1.Top - 100
Else
Image1.Top = Form1.Height - Image1.Height
End If
Case vbKeyDown
If Image1.Top < -100 Then
Image1.Top = Image1.Top + 100
Else
Image1.Top = 0
End If
End Select
End Sub
5、Label1_MouseDown事件代码如下:
Private Sub Label1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then '判断是否按下鼠标左键
Me.MousePointer = 99 '将鼠标形状改为手形
Me.MouseIcon = LoadPicture("C:新建文件夹h_point.cur")
Old.X = X
Old.Y = Y
ImageLeft = Image1.Left
ImageTop = Image1.Top
MoveOrNot = True
End If
End Sub
6、Label1_MouseMove事件代码如下:
Private Sub Label1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If MoveOrNot Then
If (ImageLeft + X - Old.X >= 0) Then
Image1.Left = 0
ElseIf (ImageLeft + X - Old.X < Form1.Width - Image1.Width) Then
Image1.Left = Form1.Width - Image1.Width
Else
Image1.Left = ImageLeft + X - Old.X
End If
If (ImageTop + Y - Old.Y >= 0) Then
Image1.Top = 0
ElseIf (ImageTop + Y - Old.Y < Form1.Height - Image1.Height) Then
Image1.Top = Form1.Height - Image1.Height
Else
Image1.Top = ImageTop + Y - Old.Y
End If
End If
End Sub
7、Label1_MouseUp事件代码如下:
Private Sub Label1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
'MoveOrNot = False '采用效果一或效果二
Me.MousePointer = 0 '恢复鼠标形状为默认值
End Sub
8、按F5运行程序。以上程序在VB5.0/6.0、Windows95/98/NT简体中文版环境下调试通过。
㈡利用Delphi编程
1、在Delphi IDE 中新建Project1(包含Form1s),在Form1上放置Image1、Label1。Image1.AutoSize为True,Label1.Align为alClient,Form1.WindowState为wsMaximized。
2、程序代码如下。如欲感知键盘事件,可参照上述VB代码修改代码。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, jpeg, ComCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
Label1: TLabel;
procedure Label1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Label1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Label1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1:TForm1;
Old:Tpoint;
ImageLeft:Integer;
ImageTop:Integer;
MoveOrNot:Boolean;
implementation
uses Unit2;
{$R *.DFM}
procedure TForm1.Label1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button=mbLeft then
begin
Label1.Cursor:=crHandPoint;
Old.X:=X;
Old.Y:=Y;
ImageLeft:=Image1.Left;
ImageTop:=Image1.Top;
MoveOrNot:=True;
end;
end;
procedure TForm1.Label1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if MoveOrNot then
begin
Image1.Left:=ImageLeft+(X-Old.X);
if (Image1.Left>=0) then
Image1.Left:=0
else if (Image1.Left < Form1.Width-Image1.Width) then
Image1.Left:=Form1.Width-Image1.Width;
Image1.Top:=ImageTop+(Y-Old.Y);
if (Image1.Top>=0) then
Image1.Top:=0
else if (Image1.Top < Form1.Height-Image1.Height) then
Image1.Top:=Form1.Height-Image1.Height;
end;
end;
procedure TForm1.Label1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
// MoveOrNot:=False;
Label1.Cursor:=crDefault;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
Image1.Left:=0;
Image1.top:=0;
end;
end.