1、屏幕保护程序 设计思路:设计好窗体,使得窗体运行时全屏幕占有及显示在最顶层。运行时消除光标,退出时响应键盘、鼠标并显示光标。设定好定时器,每隔0.5秒出现一次圆图像,当到达次数时清除画面,并调用画圆程序。把画圆程序设置好,使其能每次随机出现圆个数,并每个圆能有许多同心圆,颜色随机生成。 屏幕保护程序需要几点:1、窗体覆盖整个屏幕 move,和保持窗口定位在屏幕的最前端SetWindowsPos。2、去除/显示光标 ShowCursor。3、画圆函数 Circle。 1、 窗体在屏幕的最前端是 Move 0,0,screen.width,screen.height 窗口在屏幕的最前
2、端,用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.
3、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 "user3
4、2" (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 窗口宽度及高度 Wfl
5、ags 窗口显示的标志状态。例如将设置窗口标志为SWP_NOMOVE(不可移动)及SWP_NOSIZE(不可改变大小) 注意:h 是类型描述,表示句柄, Wnd 是变量对象描述,表示窗口,所以hWnd 表示窗口句柄。通俗地说,如果把一个到处跑的人当作指针的话,那么HWND就是该人的身份证----我想应该是身份证号码 程序中调用setwindowspos 函数 Temp=setwindowpos(hwnd,HWND TOPMOST,0,0,0,0,SWP NOMOVE or SWP NOSIZE) Setwindowpos(要处理的窗口,窗口叠放顺序,窗口坐标位,窗口宽度及高度,窗口
6、显示的标志状态) HWND_TOPMOST:将窗口置于所有非顶层窗口之上。即使窗口未被激活窗口也将保持顶级位置。 2、 去除/显示光标 在屏幕保护程序打开时,必须去除光标,而且在结束屏幕保护功能之后,也必须恢复显示光标。可通过API函数——showcursor完成。 函数声明(查API文本浏览器) Public Declare Function ShowCursor Lib "user32" Alias "ShowCursor" (ByVal bShow As Long) As Long 名称 功能 Showcursor 函数会设置一个内部计数器,当计数器大于等于零时,
7、才显示光标 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、
8、 画圆:circle 【对象名】.circle [step] (x,y),radius,[color] Step 目前坐标点为相对参考原点 (x,y) 圆心坐标 Radius 半径 color 颜色 过程的分类: 1、 事件过程:当发生某个事件时,对该事件作出响应的程序段。 如 Public Event Click() 2、函数过程(Function):函数过程用来完成特定的功能并返回相应的结果。在事件或其它过程中可按名称调用函数。函数过程能够返回接受参数,并且总是以该函数名返回一个值。这类过程一般用于完成计算任务。 如 Public Functio
9、n click() End Function 3、子过程(sub):子过程是没有返回值的函数。在事件过程或其它过程中可按名称调用子过程。子过程能接收到参数,并可用于完成过程中的任务且返回一些数值。但是,与函数过程不同,子过程不返回与其特定子过程名相关联的值。子过程一般用于接收或处理输入数据、显示输出或者设置属性。 子过程就是用来接收函数完成一个大任务的,用的最多。函数过程就是用来完成特定单一任务并返回一个与函数名相关的值,事件过程不返回值,只是对事件触发的响应。 Step1、窗体设计 在窗体中添加定时器,并把timser1的Interbal属性定为5
10、00,即每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
11、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
12、'常数定义 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 L
13、ong) 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,
14、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:
15、在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 paintin
16、g(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 r
17、ad 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是
18、用来给这个大圆画许多同心圆的。其循环依据是大圆的半径。desk.Circle (x, y), j, RGB(r, g, b)就可以表示出这些同心圆包括那个大圆在内。 Next Next 进阶设计: Step1:在“一般模块”状态下输入main程序内容,判断窗体是否存在和进行窗体加载。使用API函数里的findwindow函数,确认窗体存在与否。 一个窗口有2个部分组成,1个是窗口的类名,一个是窗口的窗口名称。通常情况下,我们自己做的窗口类名和窗口名称都是知道的,因为是自己给它们加上去的。但对于模板窗口,我们一般是不知道它的类名的,但它的窗口名称是可以知道的,就是显示在标题栏中
19、的标题,就是它的窗口名称。 当有2个窗口在桌面上时,一个窗口有个编辑框,而另一个没有编辑框。当我们想要用那个有编辑框的窗口时,必须先得到那个窗口的句柄,FindWindow就是帮助我们取得这个窗口句柄。 我们可以任意指定FindWindow中两个参数的其中一个,或同时2个都指定来找到那个带有编辑框的窗口,然后FindWindow就会返回这个窗口的句柄(hwnd)。 窗口类名好比人的小名,窗口标题名称好比是人的大名。 我们一般知道一个人的大名,但不太清楚他的小名如对话框的类名#32776。FindWindow给了我们两个参数,以便我们在不知道一个人小名的情况下,可以通过大名来找到
20、该人。 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(vbNul
21、lString, 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 窗体的标题






