VB中实现“擦视”技术

软件世界

想必大家都留意到了,在多媒体设计中应尽量避免“跳跃分隔”的镜头画面,同样在设计软件时,窗体间切换时也应该做到平滑自然,这就是所说的“擦视技术”。如何实现“擦视技术”,大家都会想到一个功能强大的API函数──位块传输Bitblt( )函数,本文主要探讨以下两个问题:
(1)Bitblt( )函数只能实现图像的位块传输,那么如何实现背景与控件界面一同擦视?
(2)调用Bitblt( )函数需要传递一长串繁琐的参数,那么如何用一个通用过程将它模块化,使其通用性强,使用简单。
窗体中的控件虽然不能被擦视,但图像能实现,我们可以首先“拍”下要切换的两个窗体界面的图片。(方法一:按下键盘上Alt + Print Screen键,截取当前活动窗体,然后到Windows中的画图工具中选择“编辑”->“粘贴”,再把图片保存下来即可;方法二,使用其他截图软件抓图,如著名的HyperSnap。)当需要擦视切换时,将一个载有该图片的过渡窗体Show出来,在该窗体上实现擦视切换(以下给出了5种擦视方法)。擦视完毕后将它Hide,并将第二个窗体Show出来,这样在视觉上毫无破绽,具体实现过程如下:
(1)启动VB,新建一个标准EXE工程,将窗体的属性设置如下:
Name属性: FrmWipe;
AutoRedraw属性: True;
ScaleMode属性: 3-pixel;
BorderStyle属性:0-None;
然后在窗体添加一个PictureBox控件,属性设置如下:
Name属性: PicResource;
AutoRedraw属性: True;
ScaleMode属性: 3-pixel;
Visible属性:False;
(2)添加一个标准模块ModWipe.bas,其代码如下:
Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long,ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Public FrmOriginal As Form
Public FrmNextOne As Form
Public WipeMode As Integer
Public strDestine, strResource As String
' 编写一个通用的Wipe过程实现擦视
Public Sub Wipe(iMode As Integer, WipeStrDestine As String, WipeStrResource As String,frmHide As Form, frmShow As Form)
'iMode为擦视方式,WipeStrDestine和WipeStrResource为图片路径 ,frmHide和frmShow 为相互切换的两个窗体
WipeMode = iMode 'frmShow为切换窗体
Set FrmNextOne = frmShow
Set FrmOriginal = frmHide
strDestine = WipeStrDestine
strResource = WipeStrResource
FrmWipe.Show 'Show出过渡窗体
End Sub
(3)在FrmWipe窗体的Form_Initialize( )、Form_Activate( )和Form_Deactivate( )事件中添加代码如下:
Private Sub Form_Activate()
Dim iMoveStep, xMax, yMax, iEndMax As Integer
Dim w, h, iTemp, i, X1, Y1, ij As Integer
Dim kxy As Single
Dim blnStop As Boolean
MousePointer = 11 '让鼠标成沙漏
FrmWipe.Picture = LoadPicture(strDestine)
PicResource.Picture = LoadPicture(strResource)
blnStop = False
iMoveStep = 0
xMax = FrmWipe.ScaleWidth / 2
yMax = FrmWipe.ScaleHeight / 2
kxy = yMax / xMax
h = FrmWipe.ScaleHeight
While blnStop = False
Select Case WipeMode '擦视方式
Case 1 '从中间向周围擦视
iEndMax = xMax
X1 = xMax - iMoveStep
w = iMoveStep * 2
Y1 = CInt(yMax - iMoveStep * kxy)
h = CInt(2 * iMoveStep * kxy)
i = BitBlt(FrmWipe.hDC, X1, Y1, w, h, PicResource.hDC, X1, Y1, &HCC0020)
Case 2 '从左向右擦视
iEndMax = xMax
w = iMoveStep * 2
i = BitBlt(FrmWipe.hDC, 0, 0, w, h, PicResource.hDC, X1, Y1, &HCC0020)
Case 3 '从左右向中间擦视
iEndMax = xMax
w = iMoveStep
i = BitBlt(FrmWipe.hDC, 0, 0, w, h, PicResource.hDC, 0, 0, &HCC0020)
X1 = ScaleWidth - iMoveStep
i = BitBlt(FrmWipe.hDC, X1, 0, w, h, PicResource.hDC, X1, 0, &HCC0020)
Case 4 '呈百叶窗状擦视
iEndMax = CInt(2 * xMax / 10)
iTemp = CInt(2 * xMax / 10)
w = iMoveStep - 7
For ij = 0 To 9
i = BitBlt(FrmWipe.hDC, iTemp * ij, 0, w, h, PicResource.hDC, iTemp * ij, 0, &HCC0020)
Next
Case 5 '从中间向左右
iEndMax = xMax
w = iMoveStep * 2
X1 = xMax - iMoveStep
i = BitBlt(FrmWipe.hDC, X1, 0, w, h, PicResource.hDC, X1, 0, &HCC0020)
End Select
iMoveStep = iMoveStep + 8 '加上不同的常量可改变擦视速度
If iMoveStep > iEndMax Then '结束条件
blnStop = True
End If
Loop
FrmNextOne.Show 'show出第二个窗体
FrmOriginal.Hide '隐藏原窗体,也可以Unload
FrmWipe.Hide '隐藏过渡窗体,也可以Unload
End Sub
Private Sub Form_Deactivate()
FrmWipe.Picture = LoadPicture() '清空图片释放内存
PicResource.Picture = LoadPicture()
End Sub
Private Sub Form_Initialize()
FrmWipe.WindowState = FrmOriginal.WindowState ' 使各个窗体的大小、位置一致
If FrmOriginal.WindowState <> 2 Then
FrmWipe.Width = FrmNextOne.Width
FrmWipe.Height = FrmNextOne.Height
FrmWipe.Top = FrmOriginal.Top
FrmWipe.Left = FrmOriginal.Left
FrmNextOne.Top = FrmOriginal.Top
FrmNextOne.Left = FrmOriginal.Left
FrmNextOne.Width = FrmOriginal.Width
FrmNextOne.Height = FrmOriginal.Height
End If
End Sub
(3)应用举例
当程序设计中窗体切换需要擦视时,只需将上述窗体FrmWipe.frm和模块ModWipe.bas添加到你的工程中,并在你需要擦视的事件中调用Wipe过程即可轻松地实现擦视技术。假设你需要通过单击按钮(名为CmdForm1ToForm2和CmdForm2ToForm1),在Form1和Form2间相互擦视切换,可在Form1中的CmdForm1ToForm2_Click( )和Form2中的CmdForm2ToForm1_Click( )事件中调用Wipe过程。这里假设“拍”下来两幅界面图片放在:c:\windows\desktop目录下,名称分别为:PicForm1.jpg和PicForm2.jpg。
代码如下:
Private Sub CmdForm1ToForm2_Click()
ModWipe.Wipe 4, App.Path + "c:\windows\desktop\PicForm1.jpg", App.Path + "c:\windows\desktop\PicForm2.jpg", Form1, Form2
End Sub ‘调用Wipe过程,4表示用第四种方法擦视
Private Sub CmdForm2ToForm1_Click()
ModWipe.Wipe 1, App.Path + "c:\windows\desktop\PicForm2.jpg", App.Path + "c:\windows\desktop\PicForm1.jpg", Form2, Form1
End Sub
按下F5运行程序,任意点击两个窗体中的切换按钮,程序将以百叶窗的过渡方式从一个窗体界面切换到另一个界面,感觉很酷吧!有兴趣的朋友,可以改变一下wipe过程中参数iMode的值,试试不同的擦视效果,看看哪种过渡方式最适合你。以上程序在VB6中文版和Win98上调试通过。