VB问题全功略(下)

来源:岁月联盟 编辑:zhu 时间:2007-02-01
  1.尽量避免使用 Variant 变量。由于VB不能确定 Variant 变量的具体类型,所以它会给该类型变量分配16个字节的空间,而且在用变量进行运算时还要考虑到数据类型的转换。这既占用内存,又影响了速度,会使涉及到复杂运算的程序慢。注意,一个变量的缺省类型就是 Variant,其它类型的变量要用Dim语句单独声明。 

  2.在遇到整型数据时尽量使用Long变量。因为Long变量是32位CPU的本机数据类型,所以处理速度会很快,尤其是在循环体中。 

  3.将控件的常用属性保存在变量中。一般控件存在于DLL或OCX这类的外部程序中。众所周知,调用DLL远比访问内存慢。所以对于那些放在循环体中的常用属性,如果将它们保存在变量中,那么速度将会有成百上千倍提升。  

  我们在编写程序时应注意到,在进行长时间等待操作时,可以做一些动画之类的效果,好让用户知道程序运行正常。下面是几个常用优化方法:  

  (1)使用 Splash 屏幕。也就是我们常见的欢迎窗口。大的应用程序在启动时,往往会主动或被动地载入一大堆DLL,这要花费很长时间。所以我们在启动时可以先显示一个简单的窗口,上面只放一些作者、版权之类的信息,在这个窗口的Form_Load事件中用Load方法读入那些最常用的窗体模块。这样,虽然实际等待的时间延长了,但用户所看到的屏幕总是变化的,所以感觉下程序启动加快了。而且由于常用窗体模块事先已载入内存,以后只需用Show方法来显示它,跳过了载入过程,在程序运行过程中也会很快的。 

  (2)使用Timer控件。由于Timer控件的出现,使得后台作业有了可能。我们可以在每次Timer事件中完成一小部分任务。这样,由于Timer中的事件能够在很短的时间内完成,用户一般查觉不到速度的变化。如果一定要在一个循环内完成某个任务,那么不要忘了用DoEvents来释放用户。 

  (3)使用进度条。要使用进度条,需要事先知道数据量,所以它很适合用于对已知数据的操作,如数据库的排序。 

  总之,优化程序要从自己、从用户等多方面考虑,使程序开发周期短,且高效易用。 

  
    在Windows下编程,经常发现有不少功能Windows系统已经做了,如果能够直接调用,就可省去不少程序的编写,并能提高程序的运行效率。在很多情况下,我们都可以用“Ctrl + X”、“Ctrl + C”、 “Ctrl + V”和“Ctrl + Z”分别进行“剪切”、“复制”、“粘贴”和“撤消”操作,由此想到,如果我们能够在程序中调用系统的这些功能,就无需为如何实现这些操作而操心了。经过不断的探索,终于发现SendMessage和PostMessage能够担此重任,真是如获至宝,于是迫不及待地把它们介绍给各位朋友。

    用VB5的“API浏览器”可以很容易地找到这两个API 函数:

  Declare Function SendMessage Lib “user32” Alias “SendMessageA” _(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _lParam As Any) As Long

  Declare Function PostMessage Lib “user32” Alias “PostMessageA” _(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _ByVal lParam As Long) As Long

    这两个函数的功能几乎是一样的,只是SendMessage是直接调用Windows函数来发送消息,只有这个消息完全被处理后此函数才返回,而PostMessage则给窗体的消息队列增加一个消息,这个消息将在未来某个时候进行正常事件处理时得到处理。以下仅以SendMessage为例。

    函数中虽然有四个参数,但关键的是前两个:hwnd 和wMsg。Hwnd是句柄,Microsoft Windows应用程序中的每个窗体和控件都拥有一个句柄,通过句柄可以指明函数的操作对象;wMsg是一个十六进制数,代表了函数要发送的具体消息。

    下面以具体例子说明如何用SendMessage实现“剪切”、“复制”、“粘贴”、“撤消” 和“删除”功能:

    在窗体中放置一个文本框Text1和五个按钮,分别执行以上五种功能,编写以下程序。

  Option Explicit

  Private Declare Function SendMessage Lib “user32” Alias “SendMessageA” _(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

    Const WM_CUT = &H300

    Const WM_COPY = &H301

    Const WM_PAST = &H302

    Const WM_CLEAR = &H303

    Const WM_UNDO = &H304

    Dim fb As Long    

    Private Sub cmdClear_Click()

     fb = PostMessage(Text1.hwnd, WM_CLEAR, 0, 0)

    End Sub

    Private Sub cmdCopy_Click()

     fb = SendMessage(Text1.hwnd, WM_COPY, 0, 0)

    End Sub

    Private Sub cmdCut_Click()

     fb = SendMessage(Text1.hwnd, WM_CUT, 0, 0)

    End Sub

    Private Sub cmdPast_Click()

     fb=SendMessage(Text1.hwnd, WM_PAST, 0, 0)

    End Sub

    Private Sub cmdUndo_Click()

     fb=SendMessage(Text1.hwnd, WM_UNDO, 0, 0)

    End Sub

    除了TextBox外SendMessage 还可以对RitchTextBox和ComboBox等进行操作,只要相应改变hwnd参数即可。

  
  大型应用系统启动运行的时间需要很长时间,其时间会根据需要初始化的数量和用户系统的速度变化,因此在主窗口显示前,应显示一个初始化窗口,使应用程序看起来更具吸引力,因为当装载程序时不断可以向用户显示一些信息,而且可产生美观的视觉效果。例如vb、delphi在启动时均在主界面前显示一splash窗口.

  ---- 1. 下面是显示闪烁(标语)屏splash的一种简单方法:  

  option explicit

  private sub form_load()

  注释:显示主窗口

  me.show

  注释:显示splash窗口

  frmsplash.show

  doevents

  注释:执行应用程序初始化

  initialize

  注释:关闭splash窗口

  unload spalsh

  end sub  

  ---- 该过程代码应放在应用程序的启动窗体中。第一个show方法可使windows在屏幕上显示主窗体,下一个show方法显示闪烁屏,它是你设计的名为frmsplash的窗体.在利用show方法之后,再利用Doevents函数,以确保闪烁屏窗体的所有元数立即绘制完。Initialize函数执行应用程序在启动时需要执行的费时任务,例如,从文件中装载数据,将窗体装入内存等等。这时一切都准备就绪. 

  ---- 2.闪烁窗体模板

  ---- Visual Basic 中含有许多摸板窗体,其中之一是闪烁屏。要为项目添加Splash screen 窗体,需要从project菜单中选择Add Form.在Add Form 对话框的New标签上选择Splash Screen图标,并单击Open.这样Splash Screen窗体就被添加到项目中. 

  ---- 下列代码显示了如何定制Splash Screen 窗体摸板的实例:

  option explicit

  private sub form_load()

  frmsplash.lbllicenseto=app.legaltrademarks

  frmsplash.lblcompanyproduct=app.productname

  frmsplash.lblplatform="window 98"

  frmsplash.lblcopyright=app.legalcopyright

  frmsplash.lblcompany=app.companyname

  frmsplash.lblwarning="Warning:this program is protected" & _

  "by copyright law,so don注释:t copy "

  frmsplash.show

  doevents

  initialize

  unload frmsplash

  end sub  

  ---- 注意这里使用了app对象,该对象可以访问有关你的应用程序的信息; 

  ---- splash screen 窗体摸板代码模块的代码如下所示: 

  Private Sub Form_keypress(keyascii as integer)

  unload me

  End sub  

  Private sub form_load()

  lblversion.caption="version"&app.major&".

  "app.minor"."app.revision

  lblproductname.caption=app.title

  end sub

  private sub frame1_click()

  unload me

  End Sub

  
   以下状况假设我在 Form_Load 中自动下拉 Combo1.   

  注释:以下声明用于16位

  Const WM_USER = &H400

  Const CB_SHOWDROPDOWN = (WM_USER + 15)

  Private Declare Function SendMessage Lib "User" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Any) As Long   

  注释:以下声明用于32位

  Const CB_SHOWDROPDOWN = &H14F

  Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long  

  Private Sub Form_Load()

  Combo1.AddItem "11111"

  Combo1.AddItem "22222"

  Combo1.AddItem "33333"

  Combo1.AddItem "44444"

  Combo1.AddItem "55555"

  Combo1.AddItem "66666"

  注释:Form_Load 即自动下拉 Combo1

  Dim nret As Long

  nret = SendMessage(Combo1.hwnd, CB_SHOWDROPDOWN, 1, ByVal 0&)

  End Sub  

  如何从您的应程序中结束 Windows 重开机?  

  很多软件在 Setup 完之后都会自动关机重开机,以便让某些设定值可以生效,其实这个功能很简单,只要几行指令就可以做到了! 

  关键就是要使用 ExitWindowsEx 这个 API,这个 API 只有二个参数,第一个参数是一个 Flag,目的是要告诉 Windows 要以什么方式关机,在下面的声明中会列出可用的 Flag 常数值,至于第二个参数则是一个保留值,只要设定成 0 就可以了。  

  很重要的一点是:如果您想要让关机动作更顺利,记得要 Unload 您的程序!  

  注释:在声明区中 (Bas Module / Form Module) 加入以下声明:  

  Public Const EWX_LOGOFF = 0 注释:这四个常数值可以并用

  Public Const EWX_SHUTDOWN = 1

  Public Const EWX_REBOOT = 2

  Public Const EWX_FORCE = 4  

  Declare Function ExitWindowsEx Lib "user32" Alias "ExitWindowsEx" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long  

  注释:实例:如果您想强迫关机重开机,程序码如下: 

  ret = ExitWindowsEx(EWX_FORCE OR EWX_REBOOT, 0)