2009耳2月 电 脑 学 习 第1期
运用VB编程实现鼠标平滑移动图像
林世琼’
摘 要:介绍利用VB缠程.实现置标平滑拖动图像的方法。
关键词:VB缩程 置标拖动 大图像
中图分类号: TP311.11 文献标识码: B 文章编号:1002—2422(2009)01-0072-02
Smoothly Moving Image by Mouse Drive in VB Programming
Lin Shiqiong
Abstract: The paper presents the methods to smoothly moving images by mouse drive in VB pl amIlling.
Keyword: VB PI mmil喀 Mouse Drive Big Image
1算法
在X坐标方向上:△x=x2一xl
1.1如何移动 在 Y坐标方向上:Ay=y2一y1
在 Picture控件中显示的图片,实际上是由若干个像素
点构成,这些像素点排列成若干行和若干列,形成一个矩形
区域,也就是 Picture控件的内部工作区域.如果图片尺寸
大于控件的内部工作区域,只能看到图片的一部分,相当于
在图片上取了和控件的内部工作区域大小相同的一矩形块
显示在控件中。如果能按鼠标移动的轨迹,不断地从原图片
中取出要显示在控件中的那部分矩形块,即可实现鼠标移
动图像的功能,上述分析用图形来
述如图 1所示。
ca 初始位置 量 餮 型 (c 营誉黎 銎
图 1随鼠标的移动,显示原图片中
不同位置上的相同大小的矩形块
1.2坐标的确定
A点坐标和 B点坐标是原始图片中的坐标点,在实际
操作中,由于可获得的坐标值是控件 内部的坐标,因此必须
对这两个坐标系统进行转换。假设在 Picture控件中的a
(xl,y1)点按下 鼠标左键,按住并移动到 b(x2.y2)点,那么
鼠标移动的距离为:
同样,可认为鼠标是在原图上移动了相同的距离,即:
在 X坐标方向上移动了△x,在 Y坐标方向上移动了Ay。
设 Picture控件所显示的图形块是原图片左上角的一片区
域 ,即图 1中的初始位置 (原图片的坐标原点 0(O,0)
上),在 Picture控件中鼠标移动了一段距离 (△x,△y),在
原图片中也同样移动了相同的距离到达 A点,那么 A点在
原图片中的坐标值即为:(Ax,Ay);如果鼠标再在 Picture
控件中移动一定的距离 (△x1,Ay1),在原图片中也同样
移动了相同的距离到达 B点,那么 B点在原图片中的坐标
值即为:(Ax+△xl,Ay+△y1),依此类堆。
由此可见,在原图中坐标点的确定是由鼠标在 Picture
控件中移动的距离而定的。从每次在 Picture控件中按下鼠
标左键移动的距离,即可得到原图中鼠标移动的轨迹 (即
各个坐标点值),并根据这个轨迹来获得图像移动的效果。
1-3平滑移动
如果把上述的移动距离△x或Ay取值为 1,即按一个
像素点一个像素点来移动,理论上应该是平滑移动,但实际
操作上是无法做到的。一是这样做运算量太大,每移动一个
像素点就要在原图片中取出一个矩形块重画 Picture控件,
难以实现;二是人操作鼠标时会发生抖动的情况,实际效果
也是抖动的。解决这个问题可利用计时器平均时间,即每隔
Engine ;
char‘p=NULL;
if(! (ep=engOpen(NULL)))
return 0:
eagEvalString(ep, =^【2,5,1;3,7,2;4,9,11】”);
engOutputBuff~r(ep,P,1)
engEvalString(ep.“rank(A)”);
COUI<< 矩阵的秩为:、ll”;
cout<
设计
与应用
【M】.北京:清华大
学出版社,2007.
相同时间取一次坐标值的办法来实现平滑。当然这个时间
间隔不能太小,也不能太大,通过实验发现其取值在 20~
80ms之间效果较好,这与机器的运算速度和 Picture控件显
示区域大小有关,可通过具体测试而定。
3程序代码
Option Explicit
Private Type POINTAPI
x As L)Ilg
Y As Long
End Type
StretchBh API函数声明
Private
Declare Function StrctchBh Lib gdi32
(ByVM hDC As Long,ByVMx AS 呜 ByV8l
Y As Lo ng,ByVM nWidth As Lo ng~
ByVal nHeight As Long,ByVal hSrcDC As
Long,
_
ByVal xSrc As Long.ByVal ySrc As Long,
ByVal nSrcWidth AS Long,
. .
ByVal nSrcHeight As Long。ByVal dwRop
As Long) As Long
GetCumorPos API函数声明
Private Declare Function GctCursorPos Lib
user32”(1pPoint As POINTAPI)As ng
Dim oldX AS Long
Dim oldY As Long
Dim ScrX As Ilg
Dim ScrY As Long
Dim da As POIN.FAPI
Private Sub Command 1_Click()
On Error G0,r0 ERR1
CD1.CaneelError= True
CD1.Filter= 图片文件 (·.bmp; .dib; .g
.JPg; .wraf)l .bmp;’.dib; .S4f; .jPg;’.wmf-
CD1.ShowOpen
Picture1.Picture=LoadPicture()
PicL.Picture=LoadPictur~(CD1.FileName)
Call StretchBh(Picture1.hDC,0,0, Pie—
ture1.ScaleWidth,Picture1.ScMeHeiSat,
一
PicL.hDC,0,0, Picture1.ScaleWidtIl, Pie—
ture1.ScaleHeight,vbSrcCopy)
Exit Sub
ERRl:
End Sub
2界面设计
新建一个工程,在窗体中放入两个图片框控件 Picture!
和 PicL,Picture1用于显示图片内容,PicL用于装入原始图
片:一个计时器控件 Timerl;一个通用对话框控件 CD1:两
个命令按钮 Commandl和 Command2。
Picture1.MousePointer= 0
Timer1.Enabled = False
End Sub
Private Sub Command2—Click()
Unload Me
End Sub
Priv~e Sub Form_load()
Picture1.ScaleMode = 3
Picture1.AutoRedraw ; Tnle
Picture1.AutoSize : Falsc
PicL.ScaleMode = 3
PieL.AutoRedraw = Tme
PieL.AutoSize = Tnle
PieL.Visible = False
Timer1.Enabled = False
ScrX = 0
scrY = 0
End Sub
Private Sub PictureI
—
MouseDowitl (Button
As Integer,Shift As Integer,x As Single,
y AS Single)
Picture1.MousePointer= 99
CaⅡ GetCursorPos(da)
01dX = da.x
oldY = da.y
Timer1.Enablecl= Tme
End Sub
Private Sub Picturel
—
MouseMove (Button
As Integer, Shift As Integer,x As Single。
Y As Single)
H Timer1.Enabled then
C8U GetCursorPos(d8)
End Ⅱ
End Sub
Private Sub Picture1
_
MouscUp (Button As
Integer,Sh As Integer,x As Single,Y
As Single)
4结束语
在程序中用到两个 API函数,StretchBh函数用于将一幅
位图从一个设备场景复制到另一个设备场景。在复制前,语
句 Picture1.Picture=LoadPicture()不可少,用于设置 Pic—
turel的设备场景。GetCursorPos函数用于获取鼠标指针的当
前位置。
参考文献
Private Sub Timed_Timet()
Dim pWidth As ng
Dim pHeisat As Long
Dim dltaX As L0ng
Dim dltaY As Long
pWidth = PietureI.ScaleWidth
pHeisat=Pieture1.ScaleHeisat
Can GctCmsorPos(da)
dltaX = oldX — da.x
dltaY = oldY — da.y
SerX = ScrX 4-dltaX
ScrY = SerY 4-dhaY
oldX =da.x
oldY =da.Y
If$erX < 0 'rhea
ScrX = 0
ElseIf SerX > PicL.Sc8lew_idth — Pieture1.
SealeWidth Then
ScrX = PicL.Sc8leWidth- Picture1.$caleW—
idth
End If
H scrY < 0 Then -
ScrY = 0
ElseH Sc f>PieL.ScaleHeisat—Pictum1.
ScaleHeisat Then
ScrY = PicL.ScaleHeight— Picture1.Scale-
Hei曲t
End If
Picture1.Picture=LoadPictur~()
Call StretehBh(Picture1.hI)C,0.o.pWidth,
pHei曲t,一
PicL.hDC, ScrX,ScrY。pWidth,pHeight,
vbSrcCopy)
End Sub
【l】(美)Rogers D F著.计算机图形学的算法基础.北京;机械工
业出版社,2004--03.
【2】马靖.利用 API增强VB的图像处理功能.北京:微计算机信息
(测控仪表 自动化),2003(9).
【3】臧玉琴.Visual Basic界面、多媒体与操作系统程序设计.北京:
人民邮电出版社.20o5-01.
· 73 ·