利用VB、Delphi轻松实现图像漫游

  许多基于Windows操作系统的多媒体、游戏、图像处理软件,为用户提供了功能强大、技术复杂的图像漫游功能。软件运行时,用户只需轻松移动鼠标(或操纵键盘方向键),即可观察屏幕显示区域之外的其余图像。那么,如何在自己的程序中实现图像漫游技术?不少文章就此问题提出过解决方案,例如:①通过调用Windows API函数(如StretchBlt);②通过直接读写内存等。上述方法的优点是:直接调用系统底层资源,程序运行速度较快;缺点是:①法可能产生屏幕闪烁现象,不利于用户使用;②法程序设计复杂、不易掌握,容易出错。在开发某应用软件系统过程中,笔者总结出利用VB、Delphi等RAD实现图像漫游的便捷方法,现介绍如下。

  1. 基本思路

    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),产生不需拖动、图像随鼠标即指即移的漫游效果。

  2. 编程步骤

    ㈠利用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.