资源描述
屏幕保护程序
设计思路:设计好窗体,使得窗体运行时全屏幕占有及显示在最顶层。运行时消除光标,退出时响应键盘、鼠标并显示光标。设定好定时器,每隔0.5秒出现一次圆图像,当到达次数时清除画面,并调用画圆程序。把画圆程序设置好,使其能每次随机出现圆个数,并每个圆能有许多同心圆,颜色随机生成。
屏幕保护程序需要几点:1、窗体覆盖整个屏幕 move,和保持窗口定位在屏幕的最前端SetWindowsPos。2、去除/显示光标 ShowCursor。3、画圆函数 Circle。
1、 窗体在屏幕的最前端是
Move 0,0,screen.width,screen.height
窗口在屏幕的最前端,用windows的API函数——SetWindowsPos ,当使用API函数时可以在VB6.0 API文本浏览器里查找,然后复制粘贴在“一般模块”里。
Move指令用法是确定一个方格在form中的位置,其坐标是从(0,0)开始的。
Command1.Move H1 * 0.5, H1 * 0.5, H1 * 7, H1 * 2
Command2.Move H1 * 8, H1 * 0.5, H1 * 7, H1 * 2
Command3.Move H1 * 16, H1 * 0.5, H1 * 7, H1 * 2
这里H1代表一个常数的话,方格就从H1 * 0.5, H1 * 0.5中知道第一点(原始点),然后H1 * 7(宽), H1 * 2(高)知道第二点(扩展点),然后以x、y轴方向连接这两点,就形成了扩展。
下面是设置窗口窗体位置的做法:
(1)、在“一般模块”新增代码命令
Option Explicit
'常数定义
Public Const HWND_TOPMOST = -1
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOSIZE = &H1
'API 函数声明
Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hwndinserafter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Setwindowpos 函数所使用的参数如表:
Hwnd
要处理的窗口
HWndInserAfter
Hwnd窗口将插放在zorder顺序的hwndinserafter 窗口之后(zorder 是指窗口叠放的顺序)
x、y
窗口坐标位
cx、cy
窗口宽度及高度
Wflags
窗口显示的标志状态。例如将设置窗口标志为SWP_NOMOVE(不可移动)及SWP_NOSIZE(不可改变大小)
注意:h 是类型描述,表示句柄, Wnd 是变量对象描述,表示窗口,所以hWnd 表示窗口句柄。通俗地说,如果把一个到处跑的人当作指针的话,那么HWND就是该人的身份证----我想应该是身份证号码
程序中调用setwindowspos 函数
Temp=setwindowpos(hwnd,HWND TOPMOST,0,0,0,0,SWP NOMOVE or SWP NOSIZE)
Setwindowpos(要处理的窗口,窗口叠放顺序,窗口坐标位,窗口宽度及高度,窗口显示的标志状态)
HWND_TOPMOST:将窗口置于所有非顶层窗口之上。即使窗口未被激活窗口也将保持顶级位置。
2、 去除/显示光标
在屏幕保护程序打开时,必须去除光标,而且在结束屏幕保护功能之后,也必须恢复显示光标。可通过API函数——showcursor完成。
函数声明(查API文本浏览器)
Public Declare Function ShowCursor Lib "user32" Alias "ShowCursor" (ByVal bShow As Long) As Long
名称
功能
Showcursor
函数会设置一个内部计数器,当计数器大于等于零时,才显示光标
Bshow
当bshow为TRUE,则内部计数器加1,当bshow为FALSE,则内部计数器减1
备注:该函数设置了一个内部显示计数器以确定光标是否显示,仅当显示计数器的值大于或等于0时,光标才显示,如果安装了鼠标,则显示计数的初始值为0。如果没有安装鼠标,显示计数是C1。
消除光标:
DO
Loop until showcursor(False)<-5
借助D0-loop循环,不断递减showcursor的内部计数值至小于-5,从而windows系统自动消除光标。
同理,显示光标
Do
Loop until showcursor(True)>5
3、 画圆:circle
【对象名】.circle [step] (x,y),radius,[color]
Step
目前坐标点为相对参考原点
(x,y)
圆心坐标
Radius
半径
color
颜色
过程的分类:
1、 事件过程:当发生某个事件时,对该事件作出响应的程序段。
如 Public Event Click()
2、函数过程(Function):函数过程用来完成特定的功能并返回相应的结果。在事件或其它过程中可按名称调用函数。函数过程能够返回接受参数,并且总是以该函数名返回一个值。这类过程一般用于完成计算任务。
如 Public Function click()
End Function
3、子过程(sub):子过程是没有返回值的函数。在事件过程或其它过程中可按名称调用子过程。子过程能接收到参数,并可用于完成过程中的任务且返回一些数值。但是,与函数过程不同,子过程不返回与其特定子过程名相关联的值。子过程一般用于接收或处理输入数据、显示输出或者设置属性。
子过程就是用来接收函数完成一个大任务的,用的最多。函数过程就是用来完成特定单一任务并返回一个与函数名相关的值,事件过程不返回值,只是对事件触发的响应。
Step1、窗体设计
在窗体中添加定时器,并把timser1的Interbal属性定为500,即每500/1000=0.5秒,触发事件一次。这里注意定时器是默认单位是1/1000秒触发的。修改窗体的borderstyle=0使其失去标题栏。修改窗体底色(backcolor)为黑色。
Step2 :
Option Explicit
Dim cout As Integer 定义变量,用来记录画圆次数
Step3:
Private Sub Form_Load() 程序初始化的动作结果,就是将窗体显示在屏幕最前端、放大窗体窗口至整个屏幕,画圆次数初始值为0,消除光标。
Dim temp
temp = SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
'将窗体置于屏幕显示的最前端,而且不接受移动或改变大小
Move 0, 0, Screen.Width, Screen.Height
'将窗体覆盖整个屏幕
cout = 0
'画圆次数初始值
Do 消除光标
Loop Until ShowCursor(False) < -5
End Sub
Step4:在“一般模块”中输入setwindowpos、showcursor两个函数的声明与设定。
Option Explicit
'常数定义
Public Const HWND_TOPMOST = -1
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOSIZE = &H1
'API 函数声明
Public Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hwndinserafter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public Declare Function ShowCursor Lib "user32" (ByVal bShow As Long) As Long
Step5:使用Unload命令,结束屏幕保护程序。这是希望屏幕保护程序运行后,计算机接受键盘或鼠标操作,结束程序运行。
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Unload Me 键盘按下触发
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
Unload Me 鼠标按下触发,me代表目前操作的窗体对象
End Sub
Step6:程序若运行unload me,将触发form_unload事件,该事件使得窗体将发生移除动作。所以我们要把显示光标的命令放置这个事件程序里,讲使屏幕保护的窗体移除时,恢复显示光标。
Private Sub Form_Unload(Cancel As Integer)
'显示光标
Do
Loop Until ShowCursor(True) > 5
End Sub
Step7:在timer1_timer事件程序中输入程序,使得定时器每隔0.5,秒引发定时事件,来进行绘图动作。
Private Sub Timer1_Timer() 0.5秒出现绘一次圆(多个)
If cout = 10 Then '画圆次数至10次,重新清除屏幕画面
cout = 0 从新计数
Cls '清除画面图形
Else
cout = cout + 1 '不够十次,画圆次数加1
End If
painting Me '调用画圆副程序
End Sub
Step8:在“一般模块”中输入画圆函数。
Public Sub painting(desk As Object) '画圆
Dim i, j, num, rad, x, y, r, g, b As Integer
num = Int(Rnd * 10 + 1) 生成1~10的随机个圆,表示屏幕出现圆的个数
For i = 1 To num 每个圆出现的位置即半径
rad = Int(Rnd * 1000 + 30) '半径
x = Int(Rnd * Screen.Height) '圆心
y = Int(Rnd * Screen.Width) '圆心
For j = 20 To rad Step 30 在每一个圆出现后,都有同心圆出现 以大圆的半径为基准,20到rad,步长递增30来确定有几个同心圆
r = Int(Rnd * 256) 原色 红 随机生成0~255
g = Int(Rnd * 256) 原色 绿
b = Int(Rnd * 256) 原色 蓝
desk.Circle (x, y), j, RGB(r, g, b) 两个for循环,当外for一次时,画一个大圆,循环依据是随机生成圆个数。如随机生成5个大圆,则循环五次,每次在内for里都生成同心圆,这也是屏幕出现的圆的个数。内for是用来给这个大圆画许多同心圆的。其循环依据是大圆的半径。desk.Circle (x, y), j, RGB(r, g, b)就可以表示出这些同心圆包括那个大圆在内。
Next
Next
进阶设计:
Step1:在“一般模块”状态下输入main程序内容,判断窗体是否存在和进行窗体加载。使用API函数里的findwindow函数,确认窗体存在与否。
一个窗口有2个部分组成,1个是窗口的类名,一个是窗口的窗口名称。通常情况下,我们自己做的窗口类名和窗口名称都是知道的,因为是自己给它们加上去的。但对于模板窗口,我们一般是不知道它的类名的,但它的窗口名称是可以知道的,就是显示在标题栏中的标题,就是它的窗口名称。
当有2个窗口在桌面上时,一个窗口有个编辑框,而另一个没有编辑框。当我们想要用那个有编辑框的窗口时,必须先得到那个窗口的句柄,FindWindow就是帮助我们取得这个窗口句柄。
我们可以任意指定FindWindow中两个参数的其中一个,或同时2个都指定来找到那个带有编辑框的窗口,然后FindWindow就会返回这个窗口的句柄(hwnd)。
窗口类名好比人的小名,窗口标题名称好比是人的大名。
我们一般知道一个人的大名,但不太清楚他的小名如对话框的类名#32776。FindWindow给了我们两个参数,以便我们在不知道一个人小名的情况下,可以通过大名来找到该人。
vbNullString可以指定为NULL/0.变量名怎么会取这样的名字?难道是从VB里挖来的代码?可VB又不是这样的语法!
P.S.大名一样的人肯能会有不至一个,小名也如此,这个时候还会涉及到路径算法。
Public Sub Main()
If unique("form1") = False Then
Exit Sub
End If
form1.Show
End Sub
Public Function unique(FormCap As String)
Dim HWin As Long
HWin = FindWindow(vbNullString, FormCap) '窗体是否存在
If HWin = 0 Then
unique = True '不存在
Else
unique = False '不存在
End If
End Function
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
名称
作用
lpClassName
窗口类别名称,若不知道,可以填入代表空字符串的vbnullstring
lpWindowName
窗体的标题
展开阅读全文