|
使用枚举变量
VB5 引入枚举变量,使用它,我们可以显著地改变应用程序的易读性:
Public Enum TimeOfDay
Morning = 0
Afternoon = 1
Evening = 2
End Enum
Sub Main()
Dim RightNow As TimeOfDay
If Time >= #12:00:00 AM# And Time < #12:00:00 PM# Then
RightNow = Morning
ElseIf Time >= #12:00:00 PM# And Time < #6:00:00 PM# Then
RightNow = Afternoon
ElseIf Time >= #6:00:00 PM# Then
RightNow = Evening
End If
End Sub
返回
修改安装向导生成的缺省安装目录
使用安装向导生成程序, 缺省安装目录是在 Program File 下的,
要修改该缺省安装目录, 只要打开已经生成的安装文件 Setup.1st:
[Setup] 中的:
DefaultDir=$(ProgramFiles)\XXXXXX
把 $(ProgramFiles) 换成 $(WinSysPath)或自定义的目录。
返回
自动开始上次关机时关闭的应用
两点关键:
1 检测是 Windows 关闭引起的 QueryUnload 事件。
2 改写 Software\Microsoft\Windows\CurrentVersion\RunOnce
声明:
Declare Function RegCloseKey Lib "advapi32.dll" Alias "RegCloseKey"
(ByVal hKey As Long) As Long
Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA"
(ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA"
(ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long,
ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long ' Note
that if you declare the lpData parameter as String, you must pass it By
Value.
在主 Form 中增加:
Public Const REG_SZ = 1
Public Const HKEY_CURRENT_USER = &H80000001
Private Sub Form_QueryUnload (Cancel as Integer, UnloadMode as Integer)
Dim hKey As Long
Dim strRunCmd As String
If UnloadMode = vbAppWindows Then
strRunCmd = App.Path & "\" & App.EXEName & ".EXE"
Call RegCreateKey(HKEY_CURRENT_USER, "Software\Microsoft\Windows\CurrentVersion\RunOnce",
hKey)
Call RegSetValueEx(hKey, "MyApp", 0&, REG_SZ, ByVal strRunCmd,
Len(strRunCmd)+1)
Call RegCloseKey(hKey)
Endif
End Sub
返回
安装向导生成程序组并建立多个程序项
1 在使用安装向导时,加入相应的文件:如Readme, 帮助文件等。
2 生成安装程序后,修改 Setup.lst 文件中的[Files], 例如要把 File1 放到程序组中, 修改 File1 的最后两项:
File1 = .... "","" 改为 ->
File1 = .... "程序项名称","应用全路径"
例如:
File1 = .... "工程说明","$(AppPath)\Readme.hlp"
3 [Setup] 中的 DefProgramGroup 为组名。
注意:如果只有一个 File 要求安装,不会建立程序组。
返回
防止打开同个VB应用多个实例
使用 App 对象的 PrevInstance 属性,可以阻止用户打开程序的多个实例。
If App.PrevInstance Then
MsgBox "该程序已经运行!"
Unload me
End If
用该种方法也可阻止多用户使用单用户的应用。
以下代码可以直接打开已经存在的应用。(在最小化时好象有问题。)
If App.PrevInstance Then
sAppTitle = App.Title
App.Title = "DUMMY_"
AppActivate sAppTitle
SendKeys "%{ }{Enter}", True
End If
返回
无关联程序时开启“打开方式”窗口
在使用资源管理器时, 双击一个未建立关联的文件, 就会出现一个 打开方式窗口。 而在程序中使用 ShellExecute 打开文件时, 如果没有关联程序,
也可以打开该窗口。
声明:
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function ShellExecute Lib _
"shell32.dll" Alias "ShellExecuteA" _
(ByVal hWnd As Long, ByVal lpOperation _
As String, ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
Declare Function GetSystemDirectory Lib _
"kernel32" Alias "GetSystemDirectoryA" _
(ByVal lpBuffer As String, ByVal nSize _
As Long) As Long
Private Const SE_ERR_NOASSOC = 31
函数:
Public Sub ShellDoc(strFile As String)
Dim lngRet As Long
Dim strDir As String
lngRet = ShellExecute(GetDesktopWindow, _
"open", strFile, _
vbNullString, vbNullString, vbNormalFocus)
If lngRet = SE_ERR_NOASSOC Then
' 没有关联的程序
strDir = Space(260)
lngRet = GetSystemDirectory(strDir, _
Len(strDir))
strDir = Left(strDir, lngRet)
' 显示打开方式窗口
Call ShellExecute(GetDesktopWindow, _
vbNullString, "RUNDLL32.EXE", _
"shell32.dll,OpenAs_RunDLL " & _
strFile, strDir, vbNormalFocus)
End If
End Sub
使用:
OpenDoc "c:\aa.log"
返回
VB 中调用 Word 拼写检查
Function CheckSpell(IncorrectText as string) as string
Dim Word As Object, retText$
On Error Resume Next
' 建立对象并打开 WORD
Set Word = CreateObject("Word.Basic")
' 把需要检查的 STRING 放到 WORD
Word.AppShow
Word.FileNew
Word.Insert IncorrectText
' 运行 WORD 拼写检查
Word.ToolsSpelling
Word.EditSelectAll
' 取返回值
retText = Word.Selection$()
CheckSpell = Left$(retText, Len(retText) - 1)
'关闭文件并回到 VB 应用
Word.FileClose 2
Show
Set Word = Nothing
End Function
返回
在 VB 中控制 Word
Word 提供了一个 Word 对象, 通过在 “引用” 中的该对象, 可以实现对 Word 的控制。 以下的代码演示了执行 WordBasic
语句,该段代码是动态引用对象, 无须在工程中引用Word 对象。
Dim wd As Object
Set wd = CreateObject ("Word.Basic")
wd.FileNewDefault
wd.FontSize 20
wd.Insert "Hello, World"
wd.FileSaveAs "Hello.Doc"
wd.FileClose
Set wd = Nothing
执行后,将产生一个 Hello.Doc 。 一个种办法是在 Word 中调试好 WordBasic 语句后, 再发布到 VB 中。类似的处理应该也可以用在
Execl 中。
返回
判断是否在 VB5 环境下运行
声明:
Private Declare Function GetModuleFileName Lib "kernel32" Alias
_ "GetModuleFileNameA" (ByVal hModule As Long, ByVal lpFileName
As _ String, ByVal nSize As Long) As Long
函数:
' True 表示在 VB5 环境下运行
Function IsRunUnderVB5() As Boolean
Dim S As String, Length
Length = 256
S = String(Length, 0)
Call GetModuleFileName(0, S, Length)
S = Left(S, InStr(S, Chr(0)) - 1)
IsRunUnderVB5 = UCase(Right(S, 7)) = "VB5.EXE"
End Function
返回
不用 API ,直接调用关联的程序
有时候,我们会忘记简单的方法:
' Notepad:
Result = Shell("start.exe notepad", vbHide)
' E-mail:
nResult = Shell("start.exe mailto:kenj@163.net", vbHide)
' Internet:
nResult = Shell("start.exe http://vbtt.yeah.net", vbHide)
' Word
nResult = Shell("start.exe myfile.doc", vbHide)
' Picture Viewer
nResult = Shell("start.exe myfile.jpg", vbHide)
返回
运行其他程序,并等待执行完毕
在程序中,我们可能要打开一个程序,如:Notepad,并要求在该程序结束后,才继续其他的操作。以下的代码完成这样的要求。
声明:
Const SYNCHRONIZE = &H100000
Const INFINITE = &HFFFFFFFF
Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess
As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As
Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle
As Long, ByVal dwMilliseconds As Long) As Long
例子:(以 Notepad 为例)
Dim pId As Long, pHnd As Long
pId = Shell("Notepad", vbNormalFocus)
pHnd = OpenProcess(SYNCHRONIZE, 0, pId) ' 取得 Process Handle
If pHnd <> 0 Then
Call WaitForSingleObject(pHnd, INFINITE) ' 等待程序结束
Call CloseHandle(pHnd)
End If
返回
打开和关闭其他应用
Declare Function FindWindow Lib "user32" Alias "FindWindowA"
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function SendMessage Lib "user32" Alias "SendMessageA"
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam
As Long) As Long
打开应用:
Private Sub Command1_Click()
Shell "Calc.exe", vbNormalFocus
End Sub
关闭应用:
Private Sub Command2_Click()
Dim lpClassName As String
Dim lpCaption As String
Dim Handle As Long
Const NILL = 0&
Const WM_SYSCOMMAND = &H112
Const SC_CLOSE = &HF060&
lpClassName = "SciCalc"
lpCaption = "Calculator"
'* Determine the handle to the Calculator window.
Handle = FindWindow(lpClassName$, lpCaption$)
'* Post a message to Calc to end its existence.
Handle = SendMessage(Handle, WM_SYSCOMMAND, SC_CLOSE, NILL)
End Sub
返回
在最小化状态时提供提示
如果你的程序在最小化状态时执行任务,你可以通过改变图标的办法来传送信息。
建立一个form 包含一个 timer 和 imagelist.
设置 timer 的 Interval属性到 2000,
在 ImageList 控件中加入三个图标.
最后, 在 Timer 事件中加入下面的代码:
Private Sub Timer1_Timer()
Static ilmage As Integer
ilmage = ilmage + 1
If ilmage > 3 Then ilmage = 1
Me.Icon = ImageList1.ListImages(ilmage).Picture
EndSub
返回
延时函数
定义函数:
Public Function Delay(Mins%, Secs%, Optional ByRef StopFlag) As Long
Dim EndOfDelay
EndOfDelay = DateAdd("n", Mins, Now)
EndOfDelay = DateAdd("s", Secs, EndOfDelay)
Delay = 0
Do While (Now < EndOfDelay)
DoEvents
If Not IsMissing(StopFlag) Then
If StopFlag Then
Delay = 1
StopFlag = False
Exit Do
End If
End If
Loop
End Function
使用例子:
Dim StopTheTimer As Boolean
Private Sub Command1_Click() '开始延时
Dim lRetval&
lRetval = Delay(1, 5, StopTheTimer)
If lRetval = 0 Then
MsgBox "时间到!"
Else
MsgBox "取消延时!"
End If
End Sub
Private Sub Command2_Click() '取消延时
StopTheTimer = True
End Sub
返回
使用 IIF 和 SWITCH 以精减代码
在很多地方你都可以使用一个更紧凑的 IIf 函数来代替 If...Else...Endif 的结构:
例:返回两个值中较大的一个
maxValue = IIf(first >= second, first, second)
Switch 则是一个很少使用的函数,可是在很多方面它都提供比 If...ElesIf 结构更好的
例:判断 "x" 是正、负还是 null?
Print Switch(x<0,"负",x>0,"正", True, "Null")
返回
设置新增控件的缺省字体
修改每个加入控件的字体是乏味的。只要把 Form 的字体设置好, 新加入该 Form 的控件都是这种字体啦。
在 IDE 里隐藏某个工程相关的所有窗口
在同时编辑多个工程时, 一大堆的窗口很碍事。 其实只要在 “工程” 窗口中, 双击某个工程项, 该工程所有相关的窗口都将隐藏。 再双击,由回来啦。
返回
启动时禁止装入 Add-Ins
启动VB时, Add-Ins 将加载。如果Add-Ins中有错误的话,每次都可能产生错误。
为了启动时禁止装入 Add-Ins, 在启动VB前,编辑 Windows 目录中的 VBAddin.INI 文件。找到以下的语句:
AppWizard.Wizard=1
将 1 改为 0 。
返回
快速查找属性
在属性窗口中,在打入字符时,按住 [Ctrl]+[Shift]。
属性窗口将自动翻滚到以该字符开头的地方。
返回
代码块注释和块取消注释
VB5 的新功能,你可以成块地将代码注释或取消注释,在调试时特别有用。请使用 注释块/取消注释块 命令对。
“注释块”和“取消注释块”命令可以在“编辑”工具栏中找到。使用这些命令使多行代码成为注释块,或从一块代码中删除注释字符:
1. 添加“编辑”工具栏。在“编辑”菜单上选择“工具栏”命令,然后选择“编辑”;或将光标放在工具栏上,按右鼠标键,然后选择“编辑”。
2. 打开代码模块,并且突出显示希望创建注释块的代码,或希望从中删除注释字符的代码。
3. 按“编辑”工具栏上的“注释块”或“取消注释块”按钮。
或者代码将移入一个块,并且添加了注释字符;或者被分离成独立的代码片段,并且从中删除了注释字符。
返回
VB5 未公开的函数
ObjPtr:返回对象实例私有域的地址。
StrPtr:返回字符串第一个字的地址。
VarPtr:返回变量的地址。
使用对象浏览器(Object Browser),你可以发现更多其他对象未公开的细节。
返回
Use the Assert Method
for Debugging
SUMMARY
=======
Microsoft Visual Basic 5.0 introduces a new debugging method for
applications. The Assert method of the Debug object allows monitoring
of
an expression for failure conditions.
MORE INFORMATION
================
The following syntax is used for the Assert method:
Debug.Assert (expression)
The Assert method syntax has the following object qualifier and part:
Part Description
---- -----------
Debug Required. The Assert method only applies to the
Debug object.
expression Required. Any logical expression.
The Assert method forces a design-time break at the Assert statement when
the expression evaluates to False. If the expression evaluates as True,
program operation continues. For example:
Function myFunction (x as Long,y as Long, z as Long) as Long
Debug.Assert (x<>0 And y<>0 And z<>0)
myFunction = 1/x + 1/y + 1/z
End Function
If you call myFunction as:
q = myFunction (1,2,3)
the program continues as normal. However, passing a zero as any one of
the
parameters forces a break. The following example breaks at the Assert
statement:
q = myFunction (1,0,3)
The above example allows testing for inappropriate parameters to protect
against a division by zero error. If a break occurs at the Assert
statement, you can check the locals window to determine which value is
inappropriate. This is especially useful when the argument values come
from
other functions:
q = myFunction ( calcX(), calcY(), calcZ() )
The Assert method is only used for debugging. During compiling, Microsoft
Visual Basic 5.0 always removes Assert statements from the final code.
There is no workaround for this behavior.
返回
编译时不要自动使用 快速代码优化
如果你第一次使用 VB 的本地代码优化选项,你可能会立即尝试选择“优化代码选项”。可是,你知道吗?这样做并不一定保证使你的程序得到最佳性能。
除非你拥有大量内存,不然程序的性能优化一般不会运行很快。因为这将导致程序装载速度缓慢,在内存不足的机器上特别明显,这样“优化代码选项”就可能让你的用户觉得好象比“优化大小选项”还慢。
基于以上原因,你可以考虑用 P 代码编译你的程序,特别是大型的、UI 和数据库加强的程序。本地“优化代码选项”所获得的性能并不一定可以弥补程序增长大小后带来的问题。
要决定你到底适合那种编译方式,请使用 VB 企业版上的 Application Performance Explorer (APE) 。
返回
VB中打开文件对话框出现乱码
如果你的系统中同时安装了VB和IE5的繁体中文,则当在VB中的诸如打开文件对话框、控件列表框中的中文会变成乱码。这时只要将IE5的繁体中文支持删除掉就可以了。不过这样你的IE就不能正确显示繁体中文了。
返回
Keeping track of VB
source code builds
Keeping track of source code builds in VB can be easy, if you use the
Version Numbering feature provided in EXE creations. Click on the options
button when creating an EXE file. Then turn on the "Auto Increment"
checkbox.
Versioning supports a three-segment version number: Major, Minor and
Revision. The Auto Increment feature, if selected, will automatically
increase the Revision number by one each time you run the Make Project
command for this project.
Typically, build information will go on an About form. Just add a label
called, "lblVersion" and add the following code to your form:
lblVersion.Caption = "Version: " & App.Major & "."
& App.Minor & "."
& App.Revision
If my Major version number is 2, the Minor number is 1 and the Revision
is
12, the label will display: "Version: 2.1.12"
返回
闰年判定程序
下面的程序判定某一年是否为闰年,如果是,则返回True
Public Function IsLeapYear(iYear As Integer)
'-- Check for leap year
If (iYear Mod 4 = 0) And _
((iYear Mod 100 <> 0) Or (iYear Mod 400 = 0)) Then
IsLeapYear = True
Else
IsLeapYear = False
End If
End Function
返回
Back to top
|