编程不可我行我素

IT商界

  程序编程是一个十分复杂的工作,它既要符合编写者的要求,还依赖于计算机硬件本身。今天我们就讨论由于受计算机硬件约束而容易产生的编程错误,以及受开发平台或操作系统平台的影响而产生的编程上的错误!

  能定时10毫秒

  有些编程初学者在使用时间控件Timer时,把时间间隔设为10毫秒,但又怀疑会不会太长。下面让我们先认识一下Timer控件:在VB中Timer控件主要有Interval和Enable属性。Interval是计时器最重要的属性,若把Interval属性值设为1000,则表示每秒钟(1000毫秒)产生一个Timer事件。若希望每秒钟发生n个事件,则Interval属性值为1000/n。但受到系统硬件能力的限制,在笔者所试的电脑上计时器每秒钟最多只能产生18个事件,即两个事件的最小时间间隔为1000/18(约56)毫秒。所以若将Interval属性值设定为小于56,则不会有什么效果。如果Interval属性值设为0表示计时器无效。所以时间设为10毫秒与设成56毫秒是一样的效果;下面我们就对这个问题编个实例说明。

  打开VB新建工程加入Form1,加入三个时间控件分别为Timer1、Timer2、Timer3,程序界面很简单(如图1)。其中Interval属性值分别设为 10、50、1000。大家都知道,本来Timer1、Timer2间的计数速度应该是5倍关系但事实又如何呢。用Timer3实现1秒定时,然后得出Timer1、Timer2运行计数结果。

  程序清单:

  Dim time1 As Integer ' 保存Timer1的计数

  Dim time2 As Integer ' 保存Timer2的计数

  Private Sub Form_Load() ' 初始化两个计数值和窗体

  time1 = 0

  time2 = 0

  End Sub

  Private Sub Timer1_Timer() ' Timer1定时到的操作把time1值加1

  time1 = time1 + 1

  End Sub

  Private Sub Timer2_Timer() ' Timer2定时到的操作把time2值加1

  time2 = time2 + 1

  End Sub

  Private Sub Timer3_Timer() ' Timer3定时1秒到

  Timer1.Enabled = False  ' Timer1暂停

  Timer2.Enabled = False  ' Timer2暂停

  Timer3.Enabled = False  ' Timer3暂停

  ' 在窗体上输出两个计数值

  Print

  Print

  Print "Timer1计数为" + Str(time1) + "次"

  Print "Timer2计数为" + Str(time2) + "次"

  End Sub

  程序运行结果如图2所示。从运行的结果可以看出计数值结果并非我们所希望的。并且Timer1的计数并非是1000/10=100而是19,Timer2的计数与1000/50也有点出入。经笔者测试,要是Interval属性值设置得很小(比如1),那么得出的计数值是很难预料的,你可以试试看。

  有先有后

  在你的VB编程中也许会遇到Form窗体的一些事件操作。例如,Form的加载和释放几个事件的顺序也许你还不很清楚,Form的这些时间有:Form_Initialize、Form_Load、Form_Resize、Form_Activate、Form_GotFocus、Form_Paint、Form_Unload、Form_Terminate;它们的事件顺序怎样,窗体是如何加载和释放等。下面让我们编个实例慢慢来说明它们的发生顺序。步骤如下:

  第一步:新建工程,打开代码编辑器,在编辑器中输入程序清单,注意先把Form1的AutoRedraw属性值设为Flase,程序运行结果如图3所示。由运行结果可以很清楚地看出各个事件发生的顺序,把窗体拉大、缩小、移动,看看结果有何不同。

  第二步:再把Form1的AutoRedraw属性值设为True,结果又是如何呢?再把窗体拉大、缩小、移动,看看结果有何不同,结果如图4所示。从两个运行结果可以看出:Form_Paint事件跟Form1的AutoRedraw属性有关:Form1的AutoRedraw属性值为True时没有Form_Paint事件发生;而把Form1的AutoRedraw属性值设为Flase时有Form_ Paint事件发生,这在编程中要特别注意和利用。

  第三步:下面我们点击窗体的退出按钮,先出来如图5所示的结果。再点击确定(如图6)。从这两个结果可以得出Form_Unload事件先于Form_Terminate事件发生,并且发生时窗体并没有在内存中释放;当Form_Terminate事件发生后,整个应用程序在内存中释放。

  从以上实例中我们可以得出结论:它们那些事件发生的先后顺序为Form_Initialize、Form_Load、Form_Resize、 Form_Activa te、Form_GotFocus、Form_Paint、 Form_Unload、Form_Terminate。这对以后的编程有帮助,也应该特别注意。

  程序清单:

  Dim str As String '定义全体字符变量

  Private Sub Form_Activate()

  str = str + Chr(13) + Chr(10) + "Form_Activate事件发生" 'Form_Activate事件发生

  Print str

  End Sub

  Private Sub Form_GotFocus()

  str = str + Chr(13) + Chr(10) + "Form_GotFocus事件发生" 'Form_GotFocus事件发生

  Print str

  End Sub

  Private Sub Form_Initialize()

  str = str + Chr(13) + Chr(10) + "Form_Initialize事件发生" 'Form_Initialize事件发生

  End Sub

  Private Sub Form_Load()

  str = str + Chr(13) + Chr(10) + "Form_Load事件发生" 'Form_Load事件发生

  Print str

  End Sub

  Private Sub Form_Paint()

  str = str + Chr(13) + Chr(10) + "Form_Paint事件发生" 'Form_Paint事件发生

  Print str

  End Sub

  Private Sub Form_Resize()

  str = str + Chr(13) + Chr(10) + "Form_Resize事件发生" 'Form_Resize事件发生

  Print str

  End Sub

  Private Sub Form_Terminate()

  MsgBox "Form_Terminate事件发生" 'Form_Terminate事件发生

  End Sub

  Private Sub Form_Unload(Cancel As Integer)

  MsgBox "Form_Unload事件发生" 'Form_Unload事件发生

  End Sub

  结 论

  程序编写是一个十分复杂的工作,它既要按照编写者的要求编制,又要依赖于计算机硬件本身。编写者不仅要了解系统硬件性能的影响,还应该了解操作系统平台软件性能的影响,因为这两个常常约束着软件编程和软件开发。(注:文中程序源代码在Windows 98+VB6.0下测试通过)