在应用程序中,有时需要用户录入些不宜在屏幕上直接显示的内容,如用户口令或机密数据。我们已熟知,在Foxbase/Foxpro中这功能可以用SETCONSOLEOFF命令关闭向屏幕的回显来实现。那么,在Visual Basic for Windows中如何做到这点呢?
个容易想到的方法是利用文本框的Key Press事件,但为了处理用户对文字的编辑(如删除、插入),则还要再用其它变量存放真正输入的内容,而且必须书写大量复杂的控制程序。实践证明,这种方法比较繁琐,不便使用。
大家知道,Windows文本框可以响应许多消息,那么,可不可以利用Windows API函数SendMessage将控制特性的消息传递给文本框呢?如果可行,则可以将使目标以密码形式输出的消息传递给文本框,不就可以制作出不回显文字的文本框了吗?
答案是肯定的。根据以上思路,可以轻松地实现这功能。以下是程序中用到的几个API函数和有关的消息:
getfocus();返回获得输入焦点的目标句柄;
getwindowlong():取得指定目标的信息,第二个参数为GWL_STYLE时将返回目标的“风格”属性;
getwindowlong():把新的属性值赋予指定的目标。该函数的三个参数分别为目标的句柄、属性类型、新属性值;
SendMessage():向目标发送条消息。该函数的四个参数分别为接收消息的目标句柄、消息、消息参数、消息参数二;
GWL_STYLE(程序中简写为STYLE):其值为_16,表示目标的“风格”;
ES_PASSWORD(程序中简写为PASS):其值为&H20,表示目标具有录入口令的属性,即在录入时不回显;
EM_SETPASSWORDCHAR(程序中简写为PASSCHAR):其值为&H41C,表示传递密码特性。用SendMessage向目标传递此消息成功,则目标会将自身的输出信息以指定的密码形式给出。
以下程序,通过SendMessage函数修改文本框Text1的“风格”属性,使其以指定的密码形式输出,不管用户录入的是什么内存,都以相同数量的“*”来显示。用户可以通过单点“Command1”按钮来显示Text1.Text的真正内容。
Declare Function getfocus Lib"user"()As Integer
Declare Function getwindowlong Lib"user"(ByVal hand As Integer,ByVal Lndex As Integer)As Long
Declare Function setwindowlong Lib"user"(ByVal hand As Integer,ByVal Lndex As Integer,ByVal newflag As Long)As Long
Declare Function SendMessage Lib"user"(ByVal hand As Integer,ByVal msg As Integer, ByVal wpara As Integer,ByVal lpara As Integer)As Loog
Const STYLE=16
Const PASS=&H20
Const PASSCHAR=&H41C
Sub Command1_Click()
MsgBox Text1.Text
End Sub
Sub Command2_Click()
End
End Sub
Sub Form_Load()
Show
Text1.SetFocus
hand %=getfocus()
flag&=getwindowlong(hand %,STYLE)Or PASS
flag&=setwindowlong(hand %,STYLE,flag&)
flag&=SendMessage(hand %,PASS_CHAR,Asc("*"),0&)
End Sub