VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 用Visual Basic设计Windows门禁程序
发表评论(0)作者:李刚, 平台:VB6.0+Win98, 阅读:11972, 日期:2002-02-06
  用过98的朋友都知道98自带了一个身份验证的程序,但它对不联网的计算机的安全不起什么保护作用。按一下"Esc"或者点击"取消",就可以进入系统。基于这点本程序将做到:

  1) 如果用户不能正确输入用户信息将不能进入系统。
 
  2) 屏蔽Ctrl+Alt+Del组合键,避免用户利用"结束任务"关闭程序。
 
  3) 程序窗体上不能有关闭按钮。

  4) 限制用户输入信息的次数,超过三次就关闭计算机。

  5)避免程序进行非法操作,否则, 呵呵,Windows可会通过一个非法操作对话框自动结束程序的。

  明确了注意事项,我们就可以开始了。

  首先进入VB界面,启动一个"标准EXE"程序。

  建立下面这个窗体 


         图 1

  具体步骤是:

  鼠标单击Form1窗体。在属性框(Properties)(如图2)中设置窗体的"名称"为frmMain,接下来程序中就用这个名字代替这个窗体了,把属性列表最下边的Windowstate属性设置为"2-Maximized"。BorderStyle 属性设置为 0-None,去掉窗体上边的按钮。程序中每个窗体和控件都有自己的属性集合,用鼠标选中它们属性窗口中都会显示出被选中物体的属性集。注意,因为本程序要求用户输入密码,为了防止别人看到密码,我们可以修改textbox控件的password属性,随便设置一个字符就可以,包括空格。




      图2 


  在VB界面的右下角有一个叫做"窗体布局"的窗体,在其中可以看到一个"显示器"和代表程序窗体的图形,通过拖动该图形移动可以改变窗体运行时窗体在实际屏幕中的位置。一般把它设在屏幕中间偏上的位置。如图3所示:

  VB带有很多图标(.ICO格式的),它们都位于\Microsoft Visual Studio\Common\Graphic\Icon\目录。Picture box控件中的笑脸图片来自那里。窗体中"用户名"及"口令"的后边设置快捷键的方法是在相应Label的caption属性中输入"名称(&字母)",比如窗体中"用户名(U)"标签的Caption属性应设置为"用户名(&U)"。这样按"Alt+字母"就可以直接写那部分信息了。写入汉字之后,如果绘制的Label比输入的信息的空间大,你会发现输入的字都在标签的左边,如果你不想这样,单击"用户名"标签,在"属性"窗口中的"名称"下边找到"Alignment"属性,它的属性控制字符在容器中的位置,其中的英语标出了它的三种状态。按照你的喜好挑选就行了。

  现在添加其他的窗体,选中图4中"工程资源管理器"窗体中的frmMain,



      图4

  用鼠标右键点击它(开始时"窗体"中只有frmMain),出现一个弹出的菜单,在依次选择"添加"-〉"添加窗体",选择"新建"-〉"窗体",点击"确定"。在"属性"中设置它的"名称"为frmAdduser,最后结果如图5所示


    图5

  在添加窗体的时候,我们也可以在出现的选择窗体类型的窗体中选择那些系统预制的窗体。比如我们可以选择其中的"登录对话框"作为修改用户信息前的身份验证窗体。按照上述步骤添加该窗体。选择预制的窗体的好处是很多属性不用设置,比较适合像我这样的懒人。添加后的窗体如图6所示



      图6 

依次添入其他两个窗体,分别命名为frmBoard(图7)和frmAbout(图8)



     图7

 
     图8

  窗体建完了。我们可以开始编写程序了。

  为了屏蔽Ctrl+Alt+Del组合键,须调用一个Windows API(Application Programming Interface,应用程序接口)函数。该函数的声明最好放在模块(module)中,那样每个窗体的程序中都可以调用它。

  在工程中添加一个模块(module),具体步骤与添加窗体类似。编程时读者自己实践一下就知道了。先添加一个模块,然后在VB界面的主菜单中单击"外接程序"选择"外接程序管理器"在出现的窗口中选择"VB 6 API Viewer"并双击它。在它的后边会出现"加载"。单击"确定"关闭窗口。这时"外接程序"中出现"API 浏览器"选项,选择它,屏幕上会出现"API浏览器"的窗口,单击"文件"-〉"加载文本文件"-〉win32api.txt,在可用项中选择SystemParametersInfo(屏蔽Ctrl+Alt+Del的函数),单击"添加",之后单击"插入",将SystemParametersInfo函数的声明部分加入到模块中,按同样的步骤添加函数 ExitWindowsEx函数(调用它可以关闭计算机)。Api函数调用后,要给它的常数付值,比如ExitWindowsEx的常数EWX_FORCE和EWX_SHUTDOWN都要付值,否则函数无效。模块部分的具体代码如下:


Const SPI_SETSCREENSAVEACTIVE = 97
' 声明一个常量
Const EWX_FORCE = 4
Const EWX_SHUTDOWN = 1
Public Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal_ dwReserved As Long) As Long
Public Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA"_ (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As_ Long) As Long
Public Sub Disable(Disable As Boolean) '定义一个函数屏蔽 Ctrl+Alt+Del 组合键,因为是
'用Public定义的,所以程序中可以直接调用函数。用语句 call disable(statement) 就可以完成调用了
Dim x As Long
x = SystemParametersInfo (SPI_SETSCREENSAVEACTIVE, Disable, CStr (1), 0)
End Sub
' 这个函数也适用于NT和2000,但在那里完成本功能还需要获得相应的权限。

  下面就可以开始编写代码了。在"工程资源管理器"中选中frmMain,双击之后,这个窗体就会出现在界面的中间。双击"确定"按钮,出现代码窗口,显示如下两行:

Private Sub Command1_Click ()
End sub

  表示现在要对Command1(命令按钮)控件的Click(单击)事件编写代码,当程序运行时单击Command1控件后,计算机就执行这段代码。有关Command1的事件有很多,在代码窗口的上方有两个下拉菜单,第一个显示当前窗体中的控件列表,第二个显示当前控件的事件列表。要对哪个控件的哪个事件编写代码可以在列表中直接选择,之后代码窗口中会自动添加代码的起始和结束标记。就像上边的command1.click一样。

  因为我们的程序允许用户添加和修改用户信息,所以要把这些信息储存在文件中。这就要涉及到文件操作。VB有十分强大的文件操作能力,它的基本语句是OPEN语句,语法:

Open pathname For mode [Access access] [lock] As [#] filenumber [Len=reclength]

  Mode, 必要。关键字,指定文件方式,有 Append、Binary、Input、Output、或 Random 方式。如果未指定方式,则以 Random 访问方式打开文件。

  Filenumber, 必要。一个有效的文件号,范围在 1 到 511 之间。使用 FreeFile 函数可得到下一个可用的文件号。

  对文件做任何 I/O 操作之前都必须先打开文件。如果 pathname 指定的文件不存在,那么,在用 Append、Binary、Output、或 Random 方式打开文件时,可以建立这一文件。

  如果文件已由其它进程打开,而且不允许指定的访问类型,则 Open 操作失败,而且会有错误发生。

  在 Binary、Input 和 Random 方式下可以用不同的文件号打开同一文件,而不必先将该文件关闭。在 Append 和 Output 方式下,如果要用不同的文件号打开同一文件,则必须在打开文件之前先关闭该文件。

  一般我们使用时用 Open pathname for mode as # filenumber 就够了。

  在这里我们选用较简单的顺序存储文件进行操作。Append和Output的区别是Append用于追加文件内容,Output用于改写文件内容。比如,现在要对文件c:\a.txt进行操作,在a.txt中现存若干用户信息,当执行语句 Open "c:\a.txt"for Append as #1 Write #1,username,password Close #1 把username和password的内容追加到文件中。如果第一条语句换作 Open "c:\a.txt" for output as #1 文件原存的信息全部丢失,改为username和password中的信息
Input 语句的语法是: Input #filenumber ,[变量名1],[变量名2],… 用这个语句可以有一个以上的变量,在本例中,文件中存放的信息是 用户名和密码 两项,所以用两个变量就可以把他们读出来。如果只用了一个变量,那就只能读出用户名。这里有一点需要注意的是 用户名和密码之间应该有一个逗号,且两个变量在相同的输出区,否则要出错。

  向顺序文件中输出信息使用语句write和 print, write 的语法是: Write #filenumber,expressions, print 的语法是: print #filenumber,expressions. 它们都可以输出多个变量。Print 表达式间以逗号分隔时,输出的多个变量分别在不同的输出区中,输出区的长度默认值为14字节,变量间没有逗号。如果以分号间隔,各变量间无间隙,以紧凑格式输出。

  Write语句把多变量输出在同一个输出区中,变量间有逗号,并且每个变量在写入文件后都以外加引号的形式出现。

  对文件的操作我们先介绍到这里,下面我们边看代码边分析,这是主窗体的源代码。VB中解释程序不处理单引号后的部分。



frmMain
'首先是变量声明部分
'***************************************************
Dim x As Boolean
' 声明一个布尔型的变量x,布尔型变量的值只能是 true 和false
Dim i As Integer
'声明一个整型变量i,整型变量的取值范围在-32768~32767之间
Dim ext as Long
'声明一个长整型的变量,用来记录ExitWindowsEx函数的返回值。
'整型变量的取值范围-2,147,483,648 到 2,147,483,647
'如果变量值超出了所属变量类型的取值范围,会因为溢出而引起系统出错,中断程序执行
Dim username, password as String
声明两个字符型变量,分别代表用户名和密码
'****************************************************
'不用循环语句但还想让程序循环的运行,可以靠事件的驱动
'****************************************************
Private Sub Command1_Click()
' Private说明子程序sub是"私有"的,即作用范围仅限于这个窗体(frmMain)
' Command1.click表示command1控件的click事件。整个一句的意思是在窗体frmMain
' 中用鼠标单击(click)command1控件会引发下面的程序。
On Error Resume Next
' 这句是出错处理,意思是执行下边的代码时忽略非法操作,继续执行下面的每一条指令
' 如果没有这句,那么如果程序执行时有非法操作,将停止执行。
If i < 3 Then ' i 是计数器,整型变量系统默认的初值为0
Open "c:\windows\use.txt" For Input As #1
'打开文件
Input #1, user, password
'读取数据
If Text1.Text <> user Or Text2.Text <> password Then
' Or 表示逻辑"或"运算,意思是两个条件中只要有一个满足,就执行下边的程序。
i = i + 1
' 当输入的信息不正确的时候i自动加1
Picture1.Picture = LoadPicture ("d:\program files\Microsoft visual studio\common\graphics\icons\misc\face01.ico")
MsgBox "不要妄图进入系统!", vbExclamation + vbOKOnly, ""
Text1.Text = "" ' 当用户输入的信息不正确时,清空文本框中的信息准备下次输入
Text2.Text = ""
Text1.SetFocus
End If
' 每种编程语言的条件语句和循环语句开始和结束都有标志,并且成对出现。End if 就是
' VB中if 语句的结束标志,它结束的是离它最近的if。
Else
' 输入信息三次出错之后,执行下列程序
Picture1.Picture = LoadPicture ("d:\program files\Microsoft visual studio\common\graphics\icons\misc\face04.ico")
' 改变卡通的表情
MsgBox "用户非法!", vbExclamation, ""
' 显示 "用户非法"
ext = ExitWindowsEx(EWX_SHUTDOWN, 0)
' 调用模块中声明的API函数,关闭计算机。
End If
If user = Text1.Text And password = Text2.Text Then
'用户输入了正确的信息
Call Disable(False)
End
' 程序运行结束
End If
Close #1
' 关闭文件
End Sub
'****************************************************
' "取消"按钮
Private Sub Command2_Click()
Text1.Text = ""
Text2.Text = ""
' 点击Command2(取消)后清空文本框。系统等待用户重新输入信息
End Sub
'****************************************************
' "退出"按钮
Private Sub Command3_Click()
ext = ExitWindowsEx(EWX_SHUTDOWN, 0)
' 点击这个按钮之后直接关闭计算机
End Sub
'****************************************************
' "修改"按钮
Private Sub Command4_Click()
frmmain.Hide
frmLogin.Show
' 点击这个键隐藏主程序窗体,显示验证身份程序窗体
End Sub
'****************************************************
' "关于"按钮
Private Sub Command5_Click()
frmAbout.Show
frmmain.Hide
' 跟Command4的Click事件一样,它的作用是启动其他窗体。
End Sub

'***************************************************
' frmMain窗体被装入内存时执行下列程序
Private Sub Form_Load()      '
Call Disable(True)
' 屏蔽Ctrl+Alt+Del 组合键
If Dir$("c:\windows\use.txt") = "" Then
' 如果 "c:\windows\use.txt"文件不存在,说明本程序在这台机器上没有被运行过
MsgBox "这时本程序第一次运行,请您先输入用户名和密码", vbInformation + vbOKOnly, "感谢您使用门禁系统"
' 出现提示框,通知用户输入用户名和密码
frmBoard.Show
' 显示添加新用户窗口
frmMain.Hide
' 隐藏当前窗口
End If
' 结束 if 条件语句
End Sub
Private Sub Picture1_Click()
Beep
' 点击Picture box控件时 发出"嘟嘟"声
End Sub
'**************************************************
'在text1文本框中按下回车键所触发的事件
Private Sub Text1_KeyPress(KeyAscii As Integer)
If KeyAscii = 13 Then
' 如果按下的键是回车键。回车键的Ascii 码是13,
Text2.SetFocus
' 光标移动到Text2文本框中,这样可以简便用户的操作
End If
End Sub
'*************************************************
' 跟上边Text1的一样,只是这次的焦点移动到"确定"按钮上
Private Sub Text2_KeyPress (KeyAscii As Integer)
If KeyAscii = 13 Then
Command1.SetFocus
End If
End Sub


  frmMain窗体的程序编写完了,有兴趣的读者可以自己编写其他几个窗体的程序,其他的几部分程序跟上面介绍的主程序有很多相似之处。可以根据上边列出的各模块功能编写,也可以自己另行设计。关键在于参与,程序不编是肯定不行的,别太不自信,其实不很难的。

  VB中可以不定义变量,而由程序自动定义为Variant类型。但建议你在编程序的时候主动定义变量,这样有助于在程序出错时加以更正,也便于程序的快速执行。为此你可以在标题栏的"工具"-〉"选项"-〉"编辑器"中选择"要求变量定义"。定义变量可以使用 Dim,Static,Public,Private等语句。需要注意的是变量的作用范围,由于本文的目的是介绍编程的经验就不做多的解释了。一般的书上都可以看到。