好多网站都提供精彩的屏保,但是我们在使用别人的屏保的时候,有没有想过自己做自己的屏保呢?
今天,我们就来用VB打造一个仿《黑客帝国》中下落字幕的屏幕保护,让精彩控制在你的手中。
我们将使用DirectX7来制作这个屏保,所以你的系统必须具备要有DX7SDK。推荐使用WindowsXP做开发平台,因为WindowsXP已经中包含了DX7和DX8的开发类库,我们可以直接进行DX程序的开发。
这个程序的思路很简单,在黑色的窗体上,通过DX将字母进行相应的下落操作即可实现。
下面我们就切入正题,开始制作这个屏保。首先新建一个VB工程。接着,将窗体的Name属性修改为frmMain,背景颜色设置为黑色,
BorderStyle设置为None。然后在这个窗体上添加一个Timer控件,将其Name属性设置为tmrMain。最终的设计效果如图1所示:
好了,基本的窗体设计以完成了,下面我们添加一个模块,这个模块中用来存放核心代码:
PublicDeclareFunctionShowCursorLib"user32"(ByValbShow
AsLong)AsLong
OptionExplicit
’声明DX7变量
PublicdxMatrixAsNewDxVBLib.DirectX7
PublicdxMatrixDrawAsDxVBLib.DirectDraw7
PublicdxMatrixDDSDESCAsDxVBLib.DDSURFACEDESC2
PublicdxMatrixDDSAsDxVBLib.DirectDrawSurface7
PublicdxMatrixDDSDESCBFAsDxVBLib.DDSURFACEDESC2
PublicdxMatrixDDSBFAsDxVBLib.DirectDrawSurface7
’定义类型
PublicTypeColumnItem
xAsInteger
yAsInteger
intGreenColourAsInteger
intCharacterAsInteger
EndType
PublicTypeColumn
Item()AsColumnItem
intXAsInteger
intYAsInteger
intLengthAsInteger
bolActiveAsBoolean
bolOffScreenAsBoolean
intCounterAsInteger
EndType
’79个字符
PublicintColumn(79)AsColumn
’字体
PublicfntCustomAsNewStdFont
’字符总数
PublicintTotalColumnsAsInteger
’是否轮换
PublicbolAlternateAsBoolean
’启动程序SubMain()
SelectCaseMid(Command,1,2)
Case"/c"
frmSettings.Show
Case"/s"
Initialize
Randomize
dxMatrixDDS.SetFontBackColorvbBlack
dxMatrixDDS.SetFontTransparencyFalse
WithfntCustom
.Name="Matrix"
.Size=8
.Bold=False
EndWith
dxMatrixDDS.SetFontfntCustom
DimiAsInteger,hAsInteger
Fori=0To79
intColumn(i).intLength=Int(Rnd*10) 30
ReDimintColumn(i).Item(intColumn(i).intLength)
intColumn(i).bolActive=False
intColumn(i).intCounter=0
intColumn(i).bolOffScreen=False
intColumn(i).intX=i
intColumn(i).intY=0
Forh=0TointColumn(i).intLength
intColumn(i).Item(h).intCharacter=Int(Rnd*43) 65
intColumn(i).Item(h).intGreenColour=Int(Rnd*255)
Nexth
Nexti
intTotalColumns=0
bolAlternate=True
frmMain.tmrMain.Enabled=True
EndSelect
EndSub
’初始化
SubInitialize()
’隐藏光标
ShowCursor(0)
SetdxMatrixDDSBF=Nothing
SetdxMatrixDDS=Nothing
’通过DX7绘制出效果
SetdxMatrixDraw=dxMatrix.DirectDrawCreate("")
dxMatrixDraw.SetCooperativeLevelfrmMain.hWnd,
DDSCL_FULLSCREENOrDDSCL_EXCLUSIVEOr
DDSCL_ALLOWMODEX
CalldxMatrixDraw.SetDisplayMode(640,480,32,0,DDSDM_DEFAULT)
dxMatrixDDSDESC.lFlags=DDSD_CAPSOr
DDSD_BACKBUFFERCOUNT
dxMatrixDDSDESC.ddsCaps.lCaps=DDSCAPS_PRIMARYSURFACEOrDDSCAPS_COMPLEXOrDDSCAPS_FLIP
dxMatrixDDSDESC.lBackBufferCount=1
SetdxMatrixDDS=dxMatrixDraw.CreateSurface
(dxMatrixDDSDESC)
DimddCapsAsDDSCAPS2
ddCaps.lCaps=DDSCAPS_BACKBUFFER
SetdxMatrixDDSBF=dxMatrixDDS.GetAttachedSurface(ddCaps)
dxMatrixDDSBF.GetSurfaceDescdxMatrixDDSDESCBFEndSub
做屏保的时候,我们将不通过窗体启动程序,而是通过SubMain来启动程序,所以你需要在“Project”->“ProjectProperties...”菜单中把“StartObject”改成“SubMain”。同时,由于程序中用到了DirectX,所以你需要在
“Project”->“References”中添加对“DirectX7forVisual
BasicTypeLibrary”的引用。我们核心的内容完成了,下面剩下的程序是用来绘制下
落的文字的。我们在窗体中,设置Timer控件的Interval为
100,然后双击Timer控件添加下面的代码:
’实现运行效果
PrivateSubtmrMain_Timer()
DimintStartColumnAsInteger,xAsInteger,yAsInteger
IfintTotalColumns<=50AndbolAlternate=TrueThen
Do
intStartColumn=Int(Rnd*79)
LoopUntilintColumn(intStartColumn).bolActive=False
intColumn(intStartColumn).bolActive=True
dxMatrixDDS.SetForeColorvbWhite
CalldxMatrixDDS.DrawText(intStartColumn*8,0,Chr
(intColumn(intStartColumn).Item(0).intCharacter),False)
intColumn(intStartColumn).intCounter=intColumn
(intStartColumn).intCounter 1
intTotalColumns=intTotalColumns 1
bolAlternate=False
Else
bolAlternate=True
EndIf
’做循环,对79个字符进行循环读取
Forx=0To79
IfintColumn(x).bolActive=TrueThen
IfintColumn(x).intCounter<intColumn(x).intLength
Then
IfintColumn(x).bolOffScreen=FalseThen
’通过DX7设置字体颜色,并且动态生成文字
CalldxMatrixDDS.SetForeColor(vbWhite)
CalldxMatrixDDS.DrawText(x*8,intColumn(x).intCounter*12,Chr(intColumn(x).Item(intColumn
(x).intCounter).intCharacter),False)
DoEvents
CalldxMatrixDDS.SetForeColor(RGB(0,0,0))
CalldxMatrixDDS.DrawText(x*8,
(intColumn(x).intCounter-1)*12,"",False)
DoEvents
CalldxMatrixDDS.SetForeColor(RGB(0,
intColumn(x).Item(intColumn(x).intCounter-1).intGreenColour,0))
CalldxMatrixDDS.DrawText(x*8,
(intColumn(x).intCounter-1)*12,Chr(intColumn(x).Item
(intColumn(x).intCounter-1).intCharacter),False)
intColumn(x).intCounter=intColumn(x).intCounter 1
EndIf
IfintColumn(x).bolOffScreen=TrueThen
IfintTotalColumns>20Then
CalldxMatrixDDS.SetForeColor
(vbBlack)
CalldxMatrixDDS.DrawText(x*8,intColumn(x).intCounter*12,Chr(intColumn(x).Item(intColumn
(x).intCounter).intCharacter),False)
intColumn(x).intCounter=intColumn
(x).intCounter 1
IfintColumn(x).intCounter=
intColumn(x).intLengthThen
intColumn(x).bolActive=False
intColumn(x).bolOffScreen=False
intTotalColumns=
intTotalColumns-1
intColumn(x).intCounter=0
EndIf
EndIf
EndIf
IfintColumn(x).intCounter=intColumn(x).intLengthOrintColumn(x).intCounter=41Then
CalldxMatrixDDS.SetForeColor(RGB(0,intColumn(x).Item(intColumn(x).intCounter-1).intGreenColour,0))
CalldxMatrixDDS.DrawText(x*8,
(intColumn(x).intCounter-1)*12,Chr(intColumn(x).Item
(intColumn(x).intCounter-1).intCharacter),False)
intColumn(x).bolOffScreen=True
intColumn(x).intCounter=0
EndIf
EndIf
EndIf
Nextx
EndSub
好了,我们这个屏幕保护就完成了,是不是很简单?好象缺少点什么东西⋯⋯哦,对了,我们的屏保还不能退出,我们还需要响应窗体的Form_KeyDown和Form_MouseMove事件来达到退出屏保的目的:
DimintWaitTimeAsInteger
’按下键盘时退出
PrivateSubForm_KeyDown(KeyCodeAsInteger,ShiftAsInteger)
’按下P键暂停,否则退出
IfKeyCode=vbKeyPThen
IftmrMain.Enabled=FalseThen
tmrMain.Enabled=True
Else
tmrMain.Enabled=False
EndIf
Else
dxMatrixDraw.RestoreDisplayMode
dxMatrixDraw.SetCooperativeLevelfrmMain.hWnd,DDSCL_NORMAL
ShowCursor(1)
UnloadMe
EndIf
EndSub
’鼠标移动时退出
PrivateSubForm_MouseMove(ButtonAsInteger,ShiftAsInteger,xAsSingle,yAsSingle)
’做一个循环来进行延时
intWaitTime=intWaitTime 1
IfintWaitTime>10Then
dxMatrixDraw.RestoreDisplayMode
dxMatrixDraw.SetCooperativeLevelfrmMain.hWnd,DDSCL_NORMAL
ShowCursor(1)
UnloadMe
EndIf
EndSub
这下屏保算是完美的了。别忘了,在编译之前要将启动对象设置为SubMain,同时还可以在生成的命令行参数中加参数/s以便观察。
开始编译吧,记得把后缀名改为scr,然后把它复制到系统的系统目录底下,这样Windows的屏幕保护列表中将会出现你的屏保的名称,选择它,然后进行预览看看。是不是非常美丽呢?
文中程序在WindowsXP、VB6下调试通过。源程序下载地址:http://www.cfan.net.cn/qikan/cfan/source/ 0220wdj.zip。