重拾VB613:创建自己的类

来自MSDN-2001-OCT: Visual Tools and Languages/Visual Studio 6.0 Documentation/Visual Basic Documentation/Using Visual Basic/Programmer’s Guide/Part 2: What Can You Do With Visual Basic/Programming with Objects/Creating Your Own Classes/

一、定制窗体类

(1)Visual Basic 为每一个窗体类创建了一个隐藏的全局对象变量。看起来就象 Visual Basic 向工程添加了下列声明:Public Form1 As New Form1

当选择 Form1 作为启动对象时,或者在代码中键入 Form1.Show,就引用了这个隐藏的全局对象变量。因为它被声明为“As New”,因此当代码中第一次使用这个预先声明的变量时,将创建 Form1 类的一个实例。

隐藏该声明的理由是每次更改窗体的 Name 属性时,Visual Basic 都要改变它。通过这种方法,隐藏的变量总是与窗体类有同样的名字。

提示 在一个窗体卸载后,总是必须将对该窗体的任何引用设置为“Nothing”,以便释放其所使用的内存和资源。最经常被忽略的引用是这个隐藏的全局窗体变量。

(2)Visual Basic 保持一个名为 Forms 的特殊的集合,该 Forms 集合包含了对工程中每一个已被装载的窗体的引用,所以即使原始的变量退出可见范围,并且被设置为“Nothing”,仍然可以找到和控制它们。当然,自己设计的类将不会有隐藏的全局变量或全局集合来跟踪它们- 这些是窗体类的特定功能。

(3)把控件放到窗体上的实质就是向窗体类添加成员属性,这个属性是只读的、而且是WithEvents的。在改变窗体中任何控件的 Name 属性时,Visual Basic 悄悄地改变了只读属性的名称以使二者匹配。

(4)把控件放到窗体上不是向窗体类添加成员的唯一方法。还可以在建立新变量和过程时添加定制的属性、方法和事件。

设置其它窗体的属性和调用其它窗体的方法是一项非常有用的技术。例如,一个 MDIForm 在打开一个新的子窗口时可以通过设置其属性、调用其方法来对它初始化。还可将此技术用于在窗体之间传递信息。

这个帖子13楼和21楼的代码及57楼、62楼、64楼的解释比较好的诠释了全局隐藏变量和Forms集合的概念。

在多实例的情况下要避免使用这个全局隐藏变量,会带来不必要的隐患。可看这个帖子69楼的例子和80楼的解释。

二、Terminate

(1)应特别记住使用 End 按钮终止应用程序或在代码中用 End 语句立即退出应用程序,并不能运行任何对象的 Terminate 事件。最好能通过卸载所有的窗体来关闭应用程序。

(2)当不存在对对象的任何引用时,对象的terminate过程会被自动调用。

三、Break in Class Module

(1)Debugging class modules differs slightly from debugging ordinary programs. This is because an error in a property or method of a class module always acts like a handled error.

(2)For example,suppose the class module Class1 contains the following code:

Public Sub Oops()
Dim intOops As Integer
intOops = intOops / 0
End Sub

Now suppose a procedure in another class module,form,or standard module calls the member Oops:

Private Sub Command1_Click()
Dim c1 As New Class1
c1 . Oops
End Sub

If the error trapping option is set to Break on Unhandled Errors,execution will not stop on the zero divide. Instead,the error will be raised in the calling procedure,Command1_Click. Execution will stop on the call to the Oops method.

(3)Break in Class Module is a compromise setting: Execution will not stop on class module code for which you've written an error handler; Execution only stops on an error that's unhandled in the class module,and therefore would be returned to the caller of the method; When the Visual Basic development environment is started,it defaults to Break in Class Module; If there are no class modules involved,Break in Class Module is exactly the same as Break on Unhandled Errors.

(4)When you hit a break point using Break in Class Module or Break on All Errors,you can step or run past the error — into your error handling code or into the code that called procedure in which the error occurred — by pressing ALT+F8 or ALT+F5.

四、Life Cycle of Visual Basic Forms

(1)A form will not close just because you've released all your references to it. Visual Basic maintains a global collection of all forms in your project,and only removes a form from that collection when you unload the form.

In similar fashion,Visual Basic maintains a collection of controls on each form. You can load and unload controls from control arrays,but simply releasing all references to a control is not sufficient to destroy it.

(2)A Visual Basic form normally passes through four states in its lifetime: Created,but not loaded; Loaded,but not shown; Shown; Memory and resources completely reclaimed.

There's a fifth state a form can get into under certain circumstances: Unloaded and unreferenced while a control is still referenced

(3)Created,But Not Loaded: The beginning of this state is marked by the Initialize event.

For example,if you execute Form1.Show,the form will be created,and Form_Initialize will execute; as soon as Form_Initialize is complete,the form will be loaded,which is the next state.

A form specified as the Startup Object is created as soon as the project starts,and is then immediately loaded and shown.

Note You can cause your form to load from within Form_Initialize,by calling its Show method or by invoking its built-in properties and methods

(4)Remaining Created,But Not Loaded: You can execute as many custom properties and methods as you like without forcing the form to load.

Public Sub ANewMethod()
Debug . Print "Executing ANewMethod"
End Sub

Dim frm As Form1
Set frm = New Form1

Dim frm As New Form1
frm . ANewMethod

Because frm is declared As New,the form is not created until the first time the variable is used in code — in this case,when ANewMethod is invoked. After the code above is executed,the form remains created,but not loaded.

Note Executing Form1.ANewMethod,without declaring a form variable,has the same effect as the example above. As explained in "Customizing Form Classes," Visual Basic creates a hidden global variable for each form class. This variable has the same name as the class; it's as though Visual Basic had declared Public Form1 As New Form1.

Note You may find it helpful to think of a form as having two parts,a code part and a visual part. Before the form is loaded,only the code part is in memory. You can call as many procedures as you like in the code part without loading the visual part of the form.

Created,But Not Loaded is the only state all forms pass through.

Dim frm As New Form1
frm . ANewMethod
Set frm = Nothing ' Form is destroyed.

(5)Loaded,But Not Shown: The event that marks the beginning of this state is the familiar Load event.

When the Form_Load event procedure begins,the controls on the form have all been created and loaded,and the form has a window — complete with window handle (hWnd) and device context (hDC) — although that window has not yet been shown.

Any form that becomes visible must first be loaded.

A form will be loaded automatically if:

a) The form has been specified as the Startup Object,on the General tab of the Project Properties dialog box.

b) The Show method is the first property or method of the form to be invoked,as for example Form1.Show.

c) The first property or method of the form to be invoked is one of the form's built-in members,as for example the Move method.

Note This case includes any controls on the form,because each control defines a property of the form; that is,in order to access the Caption property of Command1,you must go through the form's Command1 property: Command1.Caption.

d) The Load statement is used to load the form,without first using New or As New to create the form

(6)Forms That Are Never Shown: It has long been common coding practice in Visual Basic to load a form but never show it. This might be done for several reasons:

  • To use the Timer control to generate timed events.
  • To use controls for their functionality,rather than their user interface — for example,for serial communications or access to the file system.
  • To execute DDE transactions.
  • NOTE You can create ActiveX components (formerly called OLE servers),which are often better at providing code-only functionality than controls are.

    (7)Forms return from the visible state to the loaded state whenever they're hidden. Returning to the loaded state does not re-execute the Load event,however. Form_Load is executed only once in a form's life.

    (8)Preparing to Unload: The last event the form gets before unloading is the Unload event. Before this event occurs,however,you get a very important event called QueryUnload. Setting the Cancel argument of the QueryUnload to True will stop the form from unloading,negating an Unload statement.

    One of most powerful features of this event is that it tells you how the impending unload was caused: By the user clicking the Close button; by your program executing the Unload statement; by the application closing; or by Windows closing. Thus QueryUnload allows you to offer the user a chance to cancel closing the form,while still letting you close the form from code when you need to.

    Important Under certain circumstances,a form will not receive a QueryUnload event: If you use the End statement to terminate your program,or if you click the End button (or select End from the Run menu) in the development environment.

    (9)Returning to the Created,But Not Loaded State: When the form is unloaded,Visual Basic removes it from the Forms collection. Unless you've kept a variable around with a reference to the form in it,the form will be destroyed,and its memory and resources will be reclaimed by Visual Basic.

    If you kept a reference to the form in a variable somewhere,such as the hidden global variable described in "Customizing Form Classes," then the form returns to the Created,But Not Loaded state. The form no longer has a window,and its controls no longer exist.

    The object is still holding on to resources and memory. All of the data in the module-level variables in the form's code part are still there. (Static variables in event procedures,are gone.)

    (10)Memory and Resources Completely Reclaimed: The only way to release all memory and resources is to unload the form and then set all references to Nothing.

    The reference most commonly overlooked when doing this is the hidden global variable mentioned earlier. If at any time you have referred to the form by its class name,you've used the hidden global variable. To free the form's memory,you must set this variable to Nothing. For example: Set Form1 = Nothing Your form will receive its Terminate event just before it is destroyed.

    Tip Many professional programmers avoid the use of the hidden global variable,preferring to declare their own form variables (for example,Dim dlgAbout As New frmAboutBox) to manage form lifetime.

    Note Executing the End statement unloads all forms and sets all object variables in your program to Nothing. However,this is a very abrupt way to terminate your program. None of your forms will get their QueryUnload,Unload,or Terminate events,and objects you've created will not get their Terminate events.

    (11)Unloaded and Unreferenced,But a Control Is Still Referenced:

    Dim frm As New Form1
    Dim obj As Object
    frm . Show vbModal
    ' When the modal form is dismissed,save a
    ' reference to one of its controls.
    Set obj = frm . Command1
    Unload frm
    Set frm = Nothing

    The form has been unloaded,and all references to it released. However,you still have a reference to one of its controls,and this will keep the code part of the form from releasing the memory it's using. If you invoke any of the properties or methods of this control,the form will be reloaded: obj.Caption = "Back to life" The values in module-level variables will still be preserved,but the property values of all the controls will be set back to their defaults,as if the form were being loaded for the first time. Form_Load will execute.

  • 这个帖子里讨论了一个Initialize事件和Load事件顺序的有趣例子,代码在4楼,答案在7楼。

    五、Class Modules vs. Standard Modules

    (1)Important Avoid making the code in your classes dependent on global data — that is,public variables in standard modules. It violates the object-oriented programming concept of encapsulation,because objects created from such a class do not contain all their data.

    (2)You cannot implement true static class data in a Visual Basic class module. However,you can simulate it by using Property procedures to set and return the value of a Public data member in a standard module,as in the following code fragment:

  • ' Read-only property returning the application name.
    Property Get CommonString() As String
    ' The variable gstrVisibleEverywhere is stored in a
    ' standard module,and declared Public.
    CommonString = gstrVisibleEverywhere
    End Property

    (3)Note You cannot use the Static keyword for module-level variables in a class module. The Static keyword can only be used within procedures.

    相关文章

    Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强...
    VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办...
    在项目中添加如下代码:新建窗口来显示异常信息。 Namespace...
    转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用...
    Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选...
      窗体代码 1 Private Sub Text1_OLEDragDrop(Data As Dat...