Visual Basic 开发技巧

总结了一些Visual Basic的应用与操作技巧,并对其强大的程序调试功能进行了介绍,用于读者在案例开发过程中参考。
在程序编写过程中,即使是最出色的设计人员,也难免会被这样或那样的问题所困扰,本节以FAQ的形式列举了一些在使用Visual Basic过程中的常见问题,以期为读者释疑解惑。
(1)  编程中经常碰到API,请问API的意义是什么?
答: API是Application Programming Interface(应用编程接口)的缩写,也就是应用程序调用系统功能的接口。Windows API主要包括由Windows系统定义的函数、消息及与之相关的数据类型。使用各种开发工具归根结底都是和API打交道。但是API本身比较难掌握,所 以Visual Basic提供了可视的面向对象的控件,初学者即使不太了解API,也可以编写Windows程序。但是Visual Basic提供的控件毕竟是有限的,不可能包括API的所有方面,所以一些复杂的功能仍然需要调用API来实现。
(2)  问要在VB的主窗体中装入一幅事先选好的图片,程序运行后可以在图片上进行修改并保存它,以备以后调用。请问怎样办?
答 :可以把Form或PictureBox的AutoDraw属性设为True,进行修改后使用VB的SavePicture语句进行存盘。 如:SavePicture Picture1.Picture, “c:\test.bmp”这种存盘的文件为.bmp文件,颜色数与当前屏幕的色彩数相同。如果你的存盘要求很高,希望控制存盘格式,只能借助于其他控 件,比如ImageMan(http://www.data -tech.com下载)、Lead Tools(http://www.leadtools.com 下载)等。
(3)  问:若在一个窗体中设置了两个命令按钮Command1和Command2。Commamd1执行一个费时的操作,包括调用多个过程和函数;而Command2则是终止/暂停Command1的运行,不是退出该程序。不知用VB如何解决?
答:你可以采用一种变通的方法,在程序中定义一个Boolean变量,在执行command1中的程序时监视该变量,如果为False退出程序;在command2中加入代码,只要点击command2就将该变量设置为False。下面是示例程序。
 Dim bMark As Boolean
 Private Sub Command1_Click( )
 bMark = True
 For I = 1 To 150000    ' Start loop.
 DoEvents       ' Yield to operating system.
 Text1.Text = Str(I)
 If Not bMark Then
 Exit Sub
 End If
 Next I        ' Increment loop counter
 End Sub

 Private Sub Command2_Click( )
 bMark = False
 End Sub

(4)  问 :我在为一数组赋值时出现如下错误:“实时错误9——下标越界”。出错的代码如下:
 Dim inputdata( ) As Single
 inputdata(0) = Text2(0).Text / Text2(1).Text    '注释:入学率
请问为何会出现这种错误?
答: VB在使用数组前必须指定数组的大小。一种办法是在定义时确定大小,如:Dim InputData(10) As Single,另一种是采用动态数组。对于你的程序,数组声明部分可以不用修改,而在出错语句前加一句:ReDim InputData(10) As Single
(5)  问 :在按下右上角的关闭键后,怎样避免当前窗口被关闭?
答: 在按下关闭键后,会发生Form_Unload和Form_QueryUnload事件。这两个事件都有个Cancel参数,如果在事件处理过程中将其设 为True就可以避免窗口被关闭。对于你的问题,Form_QueryUnload事件可能更好些,因为它有一个UnloadMode参数可以区分关闭窗 口的指令是用户做出的,还是系统做出的,或者是本程序代码产生的。
(6)  问 :我是第一次编写ActiveX DLL程序,在DLL中,我只在类模块中写了一个函数CARD,编译成DLL后,在另外一个程序中调用,在模块中声明:
Public Declare Function card_config Lib "c:\test\card.dll" (ByVal address As Integer, ByVal intermit As Integer)
在一个按钮中写如下代码:
c = card_config(12,12)
运行后出现错误;编译Activex DLL后,调用时出现错误:“实时错误453,找不到DLL入口点”。
答: Declare语句只能用来调用标准DLL,而不能用于调用ActiveX DLL,这是你程序出错的原因。VB无法生成标准DLL,只能生成ActiveX DLL。要调用ActiveX DLL,一般通过CreateObject语句调用,或在集成环境中选择菜单“工程”→“引用”,在对话框中选择你要调用的ActiveX DLL。这样你就可以在程序中使用ActiveX DLL中定义的对象或函数。
(7)  问: 怎样在VB中启动其他Windows应用程序,例如记事本?
答: 你可以使用VB的Shell函数调用其他应用程序。如:
    Shell“Notepad.exe c:\autoexec.bat”
(8)  问 :如何打印 MSChart 控件中的内容?
答: MSChart本身没有打印功能,所以必须先用EditCopy将图像放在剪贴板中,然后再打印,如:
 MSChart1.EditCopy
 Printer.Print ″ ″
 Printer.PaintPicture Clipboard.GetData(), 0, 0
 Printer.EndDoc
(9) 问 :VB中的进制转换是怎样的?
答:用函数Oct()将十进制位数 转换为八进制,用Hex()将十进制位数转换为十六进制,不过值得注意的是,转换后数字型变为字符型。如果是一个变量可以用如下代码完成十 进制向其他进制转换的目的。
dim Anum as long
Anum=& 010   '&0是八进制的,表示符号Anum自行转换为8
Anum=&HA   '&H是十六进制的,表示符号Anum自行转换为10
如果有一个字符变量Astring 为八进制的或十六进制的,用Anum=” &0” + Astring和Anum=“&H”+Astring 能将它转换为十进制。
VB中用如下代码可以实现十进制到二进 制的转换:

Option Explicit
Ptivate FunctiOn TenturnTwo (ByVal varNum As Long)
Dim returnString As String,ModNum As Integer
DO While varNum>0
ModNum=varNum Mod 2
varNum=varNum\2
returnString=Trim(Str (ModNum))+returnString
Loop
TenturnTwo=returnString
End Function
Private Function TwoturnTen (ByVal varString As String)
Dim Slen As Long,I As Long,
returnNum As Long
Slen=Len(varString)
For I=o To Slen-1
returmNum=returnNum +Val(Mid (varString,I+1,1))*(2^(Slen-I-1))
Next
TWoturnTen=returnNum
End Function

(10) 问:如何让文本框只接受数字?
答:使用如下代码,在文本框的按键事件中加入:

Private Sub Textl_KeyPress(KeyAscii As Integer)
   If keyAscii>=33 Then
     If KeyAscii<=vbkey9 And KeyAscii>=vbKey0 Then
      Else '把KeyAscii设为0就是取消输 入。
     KeyAscii=0
     MsgBox ”不要输入数字!”
    End If
   End If
End Sub

注意:KeyAscii键值与KeyCode 相同,可以查看KeyCode值,不过有些KeyCode键值必须在 KeyDown和KeyUp中才有效,在 KeyPress的KeyAscii中没用。利用 KeyAscii=0的方式在KeyPress中有用,但在KeyDown中让KeyCode=0 就不行了。
(11) 在VB5.0下,如何用程序改变中文与英文的输入方式?
答:VB5.0在可以输入文字的地方(如TextBox,ListBox,ComBox... 等)有一个输入法切换属性IMEMode。们可以先用ImeStatus函数来检测当前的输入状态,并用IMEMode来控制其输入状态。 下面是IMEMode的属性值。
Text1.IMEMode=0(预定值)
Text1.IMEMode=l(切换为中文输 入)
Text1.IMEMde=2(切换为英文输 入)
Text1.IMEMde=3(关闭中文输入 的功能,也就是只能做英文输入)
(12) 问:如何编程使文本框中文本的某一特定字符或字符串同时高亮显示?
答: 由于普通TextBox控件不支持不连续字符串的同时高亮显示,所以选择RichTextBox控件。 新建一工程,在窗体上添加一个RichTextBox控件和两个Command(按钮)控件,都采用系统默认的Name属性值;设置 RichTextBox的Text属性值为空,Command1和Command2的Caption属性值分别设为“输入文本”和“选择字符串”。最后, 添加如下VB代码:
   Private Sub Command1—Click( )
   Dim str As String
   Dim Text As String
   str=″输入文本″
   Text=InputBox(str)
   RichTextBox1.Text=Text
End Sub

    Private Sub Command2—Click( )
Dim str As String
    Dim Text As String
    Dim Position As Integer
    Dim Lenth As Integer
    str=″输入要高亮显示的字符串″
    Text=InputBox(str)
    If Text 〈〉 ″ ″ Then
     Position=InStr(RichTextBox1.Text, Text)-1
    Lenth=Len(Text)
     RichTextBox1.SelStart=Position
     RichTextBox1.SelLength=Lenth
     RichTextBox1.SelColor=RGB(255,0,0)
       Do While InStr(Position+Lenth+1, RichTextBox1.Text, Text) 〈〉 0
        Position=InStr(Position+Lenth+1, RichTextBox1.Text, Text)-1
        RichTextBox1.SelStart=Position
        RichTextBox1.SelLength=Lenth
        RichTextBox1.SelColor=RGB(255,0,0)
       Loop
    End If
   End Sub
 按 F5执行程序,单击“输入文本”按钮,在弹出的对话框中输入一些文本,确定后,刚刚输入的文本将显示在RichTextBox中;再单击“选择字符串”按 钮,在弹出的对话框中输入你希望高亮显示的字符串,确定后,RichTextBox中相应的字符串将以红色高亮显示。
(13) 问:如何把数据文件输出到Text控件中?如果数据量比较大,窗体满屏也不够大,怎么解决?
答: 有一个比较简单的方法,就是把数据放到一个文本框(Text)里,并在其中加上水平和垂直滚动条。具体实现步骤为:先在窗体(Form)里加入一个文本 框,采用默认名Text1;然后,设置文本框Text1的属性:Text属性设置为空,MultiLine属性设置为True,ScrollBars属性 设置为3-Both;接着添加如下VB代码:

  Private Sub Form—Load()
   Dim Handle As Integer
   Dim FileName As String
  On Error GoTo ErrExit
   begin:
   ′输入要显示的数据文件的名称
   FileName=InputBox$(″Input Filename″,
   ″Open File″)
   On Error GoTo FileErr
   Handle=FreeFile
   Open FileName For Input As #Handle
   ′把数据文件中的数据输出到文本框中
   Text1.Text=Input$(LOF(Handle), Handle)
   Close #Handle
   Exit Sub
   FileErr:
   Dim ErrNum As Integer
   If Err.Number=53 Then
    ErrNum=MsgBox(″File not exist″, vbOKCancel, ″Error Information″)
    If ErrNum=1 Then
      GoTo begin
    Else
      Exit Sub
    End If
   End If
   MsgBox Err.Description, , ″file open failed″
   ErrExit:
   Exit Sub
   End Sub
   ′使文本框充满整个窗体

   Private Sub Form—Resize()
   Text1.Left=0
   Text1.Top=0
   Text1.Width=Form1.Width-100
   Text1.Height=Form1.Height-400
   End Sub

通过这样的处理,不仅能解决问题,而且用户还可以在文本框中对数据进行编辑。
(14) 问:想做一个对话窗体,包含驱动器列表框、目录列表框和文件列表框,并能实现三者的同步操作,怎么做?
答:在实际应用中,经常会遇到上述问题,在VB中解决这个问题非常简单,可以通过Path属性的改变引发Change事件来实现。例如:
  Sub Dir1—Change( ) 
     File1.Path=Dir1.Path
   End Sub
该事件过程使窗体上的目录列表框Dir1和文件列表框File1产生同步。因为目录列表框Path属性的改变将产生Change事件,所以在Dir1的Change事件过程中,把Dir1.Path赋给File1.Path,就可以产生同步效果。
类似地,增加下面的事件过程,就可以使三种列表框同步操作:
   Sub Drive1—Change( )
     Dir1.Path=Drive1.Drive
   End Sub
该过程使驱动器列表框和目录列表框同步,前面的过程使目录列表框和文件列表框同步,从而使三种列表框同步,问题即可解决。
(15) 问:怎样在VB中实现动画窗口?
答:下面就来看一下动画窗口的实现步骤。其中hwnd是指定产生动画窗口的句柄。dwTime指定动画持续的时间,以毫秒为单位。DwFlags指定动画类型,这个参数可以是一个或多个下列标志的组合。
标志描述:
 AW_SLIDE:值为&H40000,使用滑动类型。当使用AW_CENTER标志时,这个标志被忽略。
 AW_BLEND:值为&H80000,使用淡出淡入,Windows 2000中使用。只有当hWnd为顶层窗口的时候才可以使用此标志。程序只需一个窗体即可

窗体的代码
  Private Declare Function AnimateWindow Lib "user32" (ByVal hwnd As Long, ByVal dwTime As
  Long, ByVal dwFlags As Long) As Boolean
 Private Const AW_HOR_POSITIVE = &H1 '自左向右显示窗口
 Private Const AW_HOR_NEGATIVE = &H2
 '自右向左显示窗口
 Private Const AW_VER_POSITIVE = &H4
 '自上而下显示窗口。
 Private Const AW_VER_NEGATIVE = &H8
 '自下向上显示窗口。
 Private Const AW_CENTER = &H10
 Private Const AW_BLEND = &H80000

 Private Sub Form_Load()
 Randomize Timer
 x = Int(6 * Rnd + 1)  '取随机整数
 Select Case x    '根据随机数选择相应的动画过程
 Case 1
 flag = AW_HOR_NEGATIVE
 Case 2
 flag = AW_HOR_POSITIVE
 Case 3
 flag = AW_VER_NEGATIVE
 Case 4
 flag = AW_VER_POSITIVE
 Case 5
 flag = AW_CENTER
 Case 6
 flag = AW_BLEND   '只在Windows 2000中起作用
 End Select
 AnimateWindow Form1.hwnd, 200, flag
 Me.Refresh
 End Sub
 注意:在Windows 98中动画过程会使动画的窗口出现杂乱图形,Windows 2000中会出现黑色的窗口,用Refresh清除。
(16) 问:如何用VB做一个聊天的程序?
答:所谓“聊天”是指两个程序能够发送数据给对方。这个程序涉及到数据通信的知识,仿佛很复杂,不过,由于VB给我们提供了一个winsock控件,问题就变得很简单了。
首 先编写“聊天(主机)”程序。在窗体里添加winsock控件,并设置其protocol属性为1-sckudpprotocol,其他属性为默认值。接 着添加两个标签和两个文本框,设置两个标签的标题属性分别为“接收窗”和“发送窗”;两个文本框的标题属性为空。最后编写代码:
(1)“聊天(主机)”
  private sub form—load()
 ′设置网络地址
 winsock1.localport=1024
 winsock1.remotehost="202.96.6.1"
 winsock1.remoteport=1999
 end sub
 private sub text1—change()
 ′发送用户输入的内容
 winsock1.senddata text1.text
 end sub
 private sub winsock1—dataarrival(byval bytestotal as long)
 dim rec as string
 ′接收对方数据并在文本框内显示
 winsock1.getdata rec, vb string
 text2.text=rec
 end sub
 
 (2) “聊天(副机)”
 private sub form_load()
 ′设置网络地址
 winsock1.localport=1999
 winsock1.remotehost="202.96.6.1"
 winsock1.remoteport=1024
 其他部分程序与(主机)相同。最后将两个程序存盘,并编译成可执行文件。现在就可以使用这个程序进行对话了。
(17) 问:如何关于关闭程序?
答: 也许大家会说关闭程序不是很简单吗,用end语句即可。事实上,用end语句关闭程序并不是一个很好的方法,end语句虽然可以结束程序,但并不能把窗体 完全从内存中移走,造成的结果是窗体还占用着部分资源;完全释放所占资源的方法还是使用unload语句,然后使用 set form = nothing 语句。如果程序中窗体较多,可以使用下面的方法一次将所有窗体移走:
 sub unloadallforms( )
 dim form as form
 for each form in forms
 unload form
 set form = nothing
 next form
 end sub
 上面这个函数采用窗体对象的方法,不需要一个一个地使用unload语句,在程序结束按钮中调用它即可。
(18) 问:如何使一副小的图片填充整个窗体的背景?
答:有很多种方法可以实现。 下面就讲两种最常用的方式:
l 用窗体自己的(PaintPicture)方法
l 用 Windows 的 API 函数 BitBlt
下面是这两种方法的示例:
l 程序需要一个窗体、一个图片(Image)控件
 Private Sub Form_Paint( )
 Dim X As Long, Y As Long
 Me.ScaleMode = 3
 Picture1.BorderStyle = 0
 Picture1.ScaleMode = 3
 Picture1.AutoRedraw = True
 With Me
 .AutoRedraw = True
     For X = 0 To .ScaleWidth \ Picture1.Width
       For Y = 0 To .ScaleHeight \ Picture1.Height
 Call Me.PaintPicture(Picture1.Picture, X * Picture1.Width, Y *
 Picture1.Height)
       Next
     Next
 End With
 Picture1.Visible = False
 End Sub
 

 Private Sub Form_Resize( )
 Form_Paint
 End Sub

l 第二种方法
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
 Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source

 Private Sub Form_Paint()
 Dim X As Long, Y As Long
 Me.ScaleMode = 3
 Picture1.BorderStyle = 0
 Picture1.ScaleMode = 3
 Picture1.AutoRedraw = True
 With Me
 .AutoRedraw = True
     For X = 0 To .ScaleWidth \ Picture1.Width
        For Y = 0 To .ScaleHeight \ Picture1.Height
 BitBlt Me.hDC, X * Picture1.Width, Y * Picture1.Height, Picture1.Width,
 Picture1.Height,
 Picture1.hDC, 0, 0, SRCCOPY
        Next
     Next
 End With
 Picture1.Visible = False
 End Sub

 Private Sub Form_Resize( )
 Form_Paint
 End Sub
以上两种方法可任选一种。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值