Wednesday, November 4, 2009

Common Properties

At first glance, it might seem that Visual Basic 6 supports countless properties for various objects. Fortunately, there's a set of properties many objects of different classes share. In this section, we'll examine these common properties.

All visible objects—forms and controls—expose these properties, which affect the object's position and size. These values are always relative to the object's container—that is, the screen for a form and the parent form for a control. A control can also be contained in another control, which is said to be its container: In this case, Top and Left properties are relative to such a container control. By default, these properties are measured in twips, a unit that lets you create resolution-independent user interfaces, but you can switch to another unit, for example, pixels or inches, by setting the container's ScaleMode property. But you can't change the unit used for forms because they have no container: Left, Top, Width, and Height properties for forms are always measured in twips. For more information about the twip measurement unit, see the section "The ScaleMode Property" later in this chapter.

While you can enter numeric values for these properties right in the Properties window at design time, you often set them in a visual manner by moving and resizing the control on its parent form. Keep in mind that Visual Basic also offers many interactive commands in the Format menu that let you resize, align, and space multiple controls in one operation. You can also access and modify these properties through code to move or resize objects at run time:

' Double a form's width, and move it to the
' upper left corner of the screen.
Form1.Width = Form1.Width * 2
Form1.Left = 0
Form1.Top = 0

Note that while all controls—even invisible ones—expose these four properties at design time in the Properties window, controls that are inherently invisible—Timer controls, for example—don't support these properties at run time, and you can't therefore read or modify them through code.

CAUTION:


Controls don't necessarily have to support all four properties in a uniform manner. For example, ComboBox controls' Height property can be read but not written to, both at design time and run time. As far as I know, this is the only example of a property that appears in the Properties window but can't be modified at design time. This happens because the height of a ComboBox control depends on the control's Font attributes. Remember this exception when writing code that modifies the Height property for all the controls in a form.

The ForeColor and BackColor Properties

Most visible objects expose ForeColor and BackColor properties, which affect the color of the text and the color of the background, respectively. The colors of a few controls—scroll bars, for example—are dictated by Microsoft Windows, however, and you won't find ForeColor and BackColor entries in the Properties window. In other cases, the effect of these properties depends on other properties: for example, setting the BackColor property of a Label control has no effect if you set the BackStyle property of that Label to 0-Transparent. CommandButton controls are peculiar in that they expose a BackColor property but not a ForeColor property, and the background color is active only if you also set the Style property to 1-Graphical. (Because the default value for the Style property is 0-Standard, it might take you a while until you understand why the BackColor property doesn't affect the background color in the usual manner.)

When you're setting one of these two properties in the Properties window, you can select either a standard Windows color or a custom color using the System tab in the first case and the Palette tab in the second, as you can see in Figure 2-1. My first suggestion is always use a standard color value unless you have a very good reason to use a custom color. System colors display well on any Windows machine, are likely to conform to your customers' tastes, and contribute to making your application look well integrated in the system. My second suggestion is if you want to use custom colors, develop a consistent color scheme and use it throughout your application. I also have a third suggestion: Never mix standard and custom colors on the same form, and don't use a standard color for the ForeColor property and a custom color for the BackColor property of the same control (or vice versa), because the user might change the system palette in a way that makes the control completely unreadable.

You can choose from several ways to assign a color in code. Visual Basic provides a set of symbolic constants that correspond to all the colors that appear in the System tab in the Properties window at design time:

' Make Label1 appear in a selected state.
Label1.ForeColor = vbHighlightText
Label1.BackColor = vbHighlight

All the symbolic constants are shown in Table 2-1, but you can also browse them in the Object Browser window, after clicking the SystemColorConstants item in the leftmost list box. (If you don't see it, first select or VBRUN in the top ComboBox control). Note that all the values of these constants are negative.



















Figure 2-1. Two different ways to set the ForeColor and BackColor properties at design time.

Table 2-1. Visual Basic constants for system colors.

Constant Hex Value Description
vb3DDKShadow &H80000015 Darkest shadow
vb3Dface &H8000000F Dark shadow color for 3-D display elements
vb3Dhighlight &H80000014 Highlight color for 3-D display elements
vb3Dlight &H80000016 Second lightest of the 3-D colors after vb3Dhighlight
vb3Dshadow &H80000010 Color of automatic window shadows
vbActiveBorder &H8000000A Active window border color
vbActiveTitleBar &H80000002 Active window caption color
vbActiveTitleBarText &H80000009 Text color in active caption, size box, scroll bar arrow box
vbApplicationWorkspace &H8000000C Background color of multiple-document interface (MDI) applications
vbButtonFace &H8000000F Face shading on command buttons
vbButtonShadow &H80000010 Edge shading on command buttons
vbButtonText &H80000012 Text color on push buttons
vbDesktop &H80000001 Desktop color
vbGrayText &H80000011 Grayed (disabled) text
vbHighlight &H8000000D Background color of items selected in a control
vbHighlightText &H8000000E Text color of items selected in a control
vbInactiveBorder &H8000000B Inactive window border color
vbInactiveCaptionText &H80000013 Color of text in an inactive caption
vbInactiveTitleBar &H80000003 Inactive window caption color
vbInactiveTitleBarText &H80000013 Text color in inactive window caption, size box, scroll bar arrow box
vbInfoBackground &H80000018 Background color of ToolTips
vbInfoText &H80000017 Color of text in ToolTips
vbMenuBar &H80000004 Menu background color
vbMenuText &H80000007 Text color in menus
vbScrollBars &H80000000 Scroll bar gray area color
vbTitleBarText &H80000009 Text color in active caption, size box, scroll bar arrow box
vbWindowBackground &H80000005 Window background color
vbWindowFrame &H80000006 Window frame color
vbWindowText &H80000008 Text color in windows

When you're assigning a custom color, you can use one of the symbolic constants that Visual Basic defines for the most common colors (vbBlack, vbBlue, vbCyan, vbGreen, vbMagenta, vbRed, vbWhite, and vbYellow), or you can use a numeric decimal or hexadecimal constant:

' These statements are equivalent.
Text1.BackColor = vbCyan
Text1.BackColor = 16776960
Text1.BackColor = &HFFFF00

You can also use an RGB function to build a color value composed of its red, green, and blue components. Finally, to ease the porting of existing QuickBasic applications, Visual Basic supports the QBColor function:

' These statements are equivalent to the ones above.
Text1.BackColor = RGB(0, 255, 255) ' red, green, blue values
Text1.BackColor = QBColor(11)

The Font Property

Forms and those controls that can display strings of characters expose the Font property. At design time, you set font attributes using a common dialog box, which you can see in Figure 2-2. Dealing with fonts at run time, however, is less simple because you must account for the fact that Font is a compound object, and you must assign its properties separately. Font objects expose the Name, Size, Bold, Italic, Underline, and Strikethrough properties.

Text1.Font.Name = "Tahoma"
Text1.Font.Size = 12
Text1.Font.Bold = True
Text1.Font.Underline = True




















Figure 2-2. At design time the Font dialog box lets you modify all font attributes at once and preview the result.

TIP
You can use the Set command to assign whole Font objects to controls (thus avoiding having to set individual font attributes for each control), as you can see in the following code fragment:

' Assign to Text2 the same font as used by Text1.
Set Text2.Font = Text1.Font

It should be made clear, however, that the preceding code actually assigns the same Font objects to both controls. This means that if you later change Text1's font attributes, the appearance of Text2 will also be affected. This behavior is perfectly consistent with the Font object's nature, even though the reasons for it will become clear only later in Chapter 6. You can take advantage of this approach—for example, if all the controls in your form always use the same font—but you should absolutely avoid it when the controls in question are supposed to have independent font attributes.

Visual Basic 6 still supports old-style Font properties such as FontName, FontSize, FontBold, FontItalic, FontUnderline, and FontStrikethru, but you can modify them only through code because they don't appear in the Properties window at design time. You can use the syntax that you like most because the two forms are perfectly interchangeable. In this book, however, I mostly follow the newer object-oriented syntax.

The Font.Size property (or the equivalent FontSize property) is peculiar because in general you can't be sure that Visual Basic is able to create a font of that particular size, especially if you aren't working with a TrueType font. The short code snippet below proves this.

Text1.Font.Name = "Courier"
Text1.Font.Size = 22
Print Text1.Font.Size ' Prints 19.5

Note that no error is raised if you specify a font size that isn't actually available.

CAUTION
In general, Visual Basic doesn't raise errors when you try to assign invalid font names. In this case, the effect is somewhat unpredictable. For example, try the following code:

' Warning: you may get different results on your system.
Print Font.Name ' Displays "Ms Sans Serif"
Font.Name = "xyz"
Print Font.Name ' Displays "Arial"

The Caption and Text Properties

The Caption property is a string of characters that appears inside a control (or in the title bar of a form) and that the user can't directly modify. Conversely, the Text property corresponds to the "contents" of a control and is usually editable by the end user. No intrinsic control exposes both a Caption and a Text property, so in practice a look at the Properties window can resolve your doubts as to what you're working with. Label, CommandButton, CheckBox, OptionButton, Data, and Frame controls expose the Caption property, whereas TextBox, ListBox, and ComboBox controls expose the Text property.

The Caption property is special in that it can include an ampersand (&) character to associate a hot key with the control. The Text property, when present, is always the default property for the control, which means that it can be omitted in code:

' These statements are equivalent.
Text2.Text = Text1.Text
Text2 = Text1
NOTE
Specifying or omitting the name of the default property in code is mostly a matter of personal taste. I always try to specify the name of all the properties referenced in code because doing so tends to make the code more readable. However, if you have long lines of code, specifying all the default properties can sometimes make the code less readable and can force you to horizontally scroll through the code window. This consideration has been followed in this book: Most of the time, I specify the default property, but don't be surprised if I sometimes omit it, especially in longer listings.

While we are on this topic, note that many programmers mistakenly believe that using default properties can make their code run faster. This is a leftover notion from Visual Basic 3 days, but it hasn't been true since Visual Basic 4 changed the internal implementation of controls.

In general, if a control exposes the Text property it also supports the SelText, SelStart, and SelLength properties, which return information about the portion of text that's currently selected in the control.

The Parent and Container Properties

The Parent property is a run time_only property (that is, you don't see it in the Properties window), which returns a reference to the form that hosts the control. The Container property is also a run time_only property, which returns a reference to the container of the control. These two properties are correlated, in that they return the same object—the parent form—when a control is placed directly on the form surface.

While you can't move a control from one form to another using the Parent property (which is read-only), you can move a control to another container by assigning a different value to its Container property (which is a read-write property). Because you're assigning objects and not plain values, you must use the Set keyword:

' Move Text1 into the Picture1 container.
Set Text1.Container = Picture1
' Move it back on the form's surface.
Set Text1.Container = Form1

The Enabled and Visible Properties

By default, all controls and forms are both visible and enabled at run time. For a number of reasons, however, you might want to hide them or show them in a disabled state. For example, you might use a hidden DriveListBox control simply to enumerate all the drives in the system. In this case, you set the Visible property of the DriveListBox control to False in the Properties window at design time. More frequently, however, you change these properties at run time:

' Enable or disable the Text1 control when
' the user clicks on the Check1 CheckBox control.
Private Sub Check1_Click()
Text1.Enabled = (Check1.Value = vbChecked)
End Sub

Disabled controls don't react to user's actions, but otherwise they're fully functional and can be manipulated through code. Invisible controls are automatically disabled, so you never need to set both these properties to False. All mouse events for disabled or invisible controls are passed to the underlying container or to the form itself.

If an object works as a container for other objects—for instance, a Form is a container for its controls and a Frame control can be a container for a group of OptionButton controls—setting its Visible or Enabled properties indirectly affects the state of its contained objects. This feature can often be exploited to reduce the amount of code you write to enable or disable a group of related controls.

TIP
Most controls change their appearance when they're disabled. Generally speaking, this is a useful practice because the user can understand at first glance which controls he or she can act on. If you have a good reason to disable a control but still display it in an active state, you can place the control inside a container (a Frame or a PictureBox, for example) and then set the container's Enabled property to False. Visual Basic will disable all contained controls, but they will continue to appear in an enabled state. This trick works better if you also set the container's BorderStyle property to 0-None.

Some programmers set the Enabled properties to False for TextBox or ComboBox controls that must work in a read-only mode. This is reminiscent of the way things worked under Visual Basic 3 and previous versions. But these controls now expose a Locked property that, if True, makes the controls completely functional, except that users can't modify their Text property. This means that users can scroll through their content but can't accidentally modify it.

The hWnd Property

The hWnd property doesn't appear in the Properties window because its value is available only at run time. Moreover, it's a read-only property, and therefore you can't assign a value to it. The hWnd property returns the 32-bit integer value that Windows uses internally to identify a control. This value is absolutely meaningless in standard Visual Basic programming and only becomes useful if you invoke Windows API routines (which I'll cover in Appendix A). Even if you're not going to use this property in your code, it's good for you to know that not all controls support it and it's important to understand why.

Visual Basic controls—both intrinsic controls and external Microsoft ActiveX controls—can be grouped in two categories: standard controls and windowless (or lightweight) controls. To grasp the difference between the two groups, let's compare the PictureBox control (a standard control) and the Image control (a windowless control). Even though they appear similar at a first glance, behind the scenes they are completely different.

When you place a standard control on the form, Visual Basic asks the operating system to create an instance of that control's class, and in return Windows passes back to Visual Basic the internal handle to that control, which the language then exposes to the programmer through the hWnd property. All subsequent operations that Visual Basic performs on that control—resizing, font setting, and so on—are actually delegated to Windows. When the application raises an event (such as resizing), Visual Basic runtime calls an internal Windows API function and passes it the handle so that Windows knows which control is to be affected.

Lightweight controls such as Image controls, on the other hand, don't correspond to any Windows object and are entirely managed by Visual Basic itself. In a sense, Visual Basic just simulates the existence of that control: It keeps track of all the lightweight controls and redraws them each time the form is refreshed. For this reason, lightweight controls don't expose an hWnd property because there aren't any Windows handles associated with them. Windows doesn't even know a control is there.

From a practical point of view, the distinction between standard and lightweight controls is that the former consume system resources and memory while the latter don't. For this reason, you should always try to replace standard controls with lightweight controls. For example, use an Image control instead of a PictureBox control unless you really need some of PictureBox's specific features. To give you an idea of what this means in practice, a form with 100 PictureBox controls loads 10 times slower than a form with 100 Image controls.

To understand whether a control is lightweight, see whether it supports the hWnd property. If it does, it surely is a standard control. A trip to the Object Browser reveals that the TextBox, CommandButton, OptionButton, CheckBox, Frame, ComboBox, and OLE controls, as well as both scroll bar controls and the ListBox control and all its variations, are standard controls. The Label, Shape, Line, Image, and Timer controls don't expose the hWnd property and should be therefore considered lightweight controls. But note that a missing hWnd property in an external ActiveX control doesn't necessarily mean that the control is windowless because the control's creator might decide not to expose the window's handle to the outside. For more information about standard and windowless controls, see the description of the ZOrder method later in this chapter.

The TabStop and TabIndex Properties

If a control is able to receive the input focus, it exposes the TabStop property. Most intrinsic controls support this property, including TextBox, OptionButton, CheckBox, CommandButton, OLE, ComboBox, both types of scroll bars, the ListBox control, and all its variations. In general, intrinsic lightweight controls don't support this property because they can never receive the input focus. The default value for this property is True, but you can set it to False either at design time or run time.

If a control supports the TabStop property, it also supports the TabIndex property, which affects the Tab order sequence—that is, the sequence in which the controls are visited when the user presses the Tab key repeatedly. (See the section "Setting the Tab Order" in Chapter 1.) The TabIndex property is also supported by Label and Frame controls, but since these two controls don't support the TabStop property, the resulting effect is that when the user clicks on a Label or a Frame control (or presses the hot key specified in the Label or Frame Caption property), the input focus goes to the control that follows in the Tab order sequence. You can exploit this feature to use Label and Frame controls to provide hot keys to other controls:

' Let the user press the Alt+N hot key
' to move the input focus on the Text1 control.
Label1.Caption = "&Name"
Text1.TabIndex = Label1.TabIndex + 1

The MousePointer and MouseIcon Properties

These properties affect the shape of the mouse cursor when it hovers over a control. Windows permits a very flexible mouse cursor management in that each form and each control can display a different cursor, and you can also set an application-wide mouse cursor using the Screen global object. Nevertheless, the rules that affect the actual cursor used aren't straightforward:

  • If the Screen.MousePointer property is set to a value different from 0-vbDefault, the mouse cursor reflects this value and no other properties are considered. But when the mouse floats over a different application (or the desktop), the cursor appearance depends on that application's current state, not yours.
  • If Screen.MousePointer is 0 and the mouse cursor is over a control, Visual Basic checks that control's MousePointer property; if this value is different from 0-vbDefault, the mouse cursor is set to this value.
  • If Screen.MousePointer is 0 and the mouse is over a form's surface or it's over a control whose MousePointer property is 0, Visual Basic uses the value stored in the form's MousePointer property.

If you want to show an hourglass cursor, wherever the user moves the mouse, use this code:

' A lengthy routine
Screen.MousePointer = vbHourglass
...
' Do your stuff here
...
' but remember to restore default pointer.
Screen.MousePointer = vbDefault

Here's another example:

' Show a crosshair cursor when the mouse is over the Picture1
' control and an hourglass elsewhere on the parent form.
Picture1.MousePointer = vbCrosshair
MousePointer = vbHourglass

The MouseIcon property is used to display a custom, user-defined mouse cursor. In this case, you must set the MousePointer to the special value 99-vbCustom and then assign an icon to the MouseIcon property:

' Display a red Stop sign mouse cursor. The actual path may differ,
' depending on the main directory where you installed Visual Basic.
MousePointer = vbCustom
MouseIcon = LoadPicture("d:\vb6\graphics\icons\computer\msgbox01.ico")

You don't need to load a custom mouse cursor at run time using the LoadPicture command. For example, you can assign it to the MouseIcon property at design time in the Properties window, as you can see in Figure 2-3, and activate it only when needed by setting the MousePointer property to 99-vbCustom. If you need to alternate among multiple cursors for the same control but don't want to distribute additional files, you can load additional ICO files in hidden Image controls and switch among them at run time.




















Figure 2-3. Visual Basic 6 comes with a lot of ready-to-go custom cursors, icons, and bitmaps in the \GRAPHICS subdirectory.

The Tag Property

All controls support the Tag property, without exception. This is true even for ActiveX controls, including any third-party controls. How can I be so certain that all controls support this property? The reason is that the property is provided by Visual Basic itself, not by the control. Tag isn't the only property provided by Visual Basic to any control: Index, Visible, TabStop, TabIndex, ToolTipText, HelpContextID, and WhatsThisHelpID properties all belong to the same category. These properties are collectively known as extender properties. Note that a few extender properties are available only under certain conditions. For example, TabStop is present only if the control can actually receive the focus. The Tag property is distinctive because it's guaranteed to be always available, and you can reference it in code without any risk of raising a run-time error.

The Tag property has no particular meaning to Visual Basic: It's simply a container for any data related to the control that you want to store. For example, you might use it to store the initial value displayed in a control so that you can easily restore it if the user wants to undo his or her changes.

Other Properties

The Value property is common to several intrinsic controls, namely CheckBox, OptionButton, CommandButton, and scroll bar controls, as well as to many external ActiveX controls. The meaning of this property varies from control to control, but in all cases it's a numerical or Boolean property.

The Index property is the key to building control arrays, a nifty Visual Basic feature that helps you create more versatile programs. (I explain control arrays more fully in Chapter 3.) If you don't want to create a control array, just leave this property blank in the Properties window at design time. Note that this property is read-only at run time for controls that belong to a control array. Note that Visual Basic raises an error if you reference the Index property of a control that doesn't belong to a control array.

Most intrinsic controls support the Appearance property, which can be assigned at design time only and is read-only at run time. By default, Visual Basic creates controls with a three-dimensional aspect, unless you modify the value of this property to 0-Flat. You might decide to do so for visual consistency with older programs. For all your new applications, you should simply forget about the Appearance property and leave it at its default value (1-3D).

You can have Visual Basic automatically attach a control to the border of its parent window by setting its Align property to a non-Null value. Only two intrinsic controls support this property—PictureBox and Data controls—but several external ActiveX controls can be aligned in this way. Possible values for this property are 0-None, 1-Align Top, 2-Align Bottom, 3-Align Left, and 4-Align Right.

The BorderStyle property is supported by a few intrinsic controls, namely the TextBox, Label, Frame, PictureBox, Image, and OLE controls. You can set this property to 0-None to suppress a border around the controller to 1-Fixed Single to draw it. Forms also support this property, but they allow different settings (as you'll see later in this chapter).

ToolTips are those tiny, usually yellow windows that appear in most Windows applications when you move the mouse over a control or an icon and keep the mouse pointer still for a second or two. (Figure 2-4 shows you helpful advice from a ToolTip.) Until Visual Basic 4, developers had to create special routines or buy third-party tools to add this functionality to their programs. In Visual Basic 5 and 6, you only have to assign a string to the ToolTipText property of the control. Unfortunately, form objects don't support this property. Note that you have no control over the position or size of ToolTip windows and can modify their foreground and background color only on a systemwide basis. (Open the Control Panel window, double-click on the Display icon, and then move to the Appearance tab of the Display Properties dialog box where you can change the font and the background color of your ToolTips.)







Figure 2-4. A tiny ToolTip tells you to enter your name.

The DragMode and DragIcon properties (as well as the Drag method) were used to drag controls on the form, but they have been superseded by the OLExxxx methods and properties. The old properties are still included for backward compatibility, but you shouldn't use them if you want to make your application conform to Windows 95 standards. OLE Drag and Drop properties, methods, and events are described in the "Using Drag-and-Drop" section of Chapter 9.

You use LinkMode, LinkTopic, LinkItem, and LinkTimeout properties (as well as LinkPoke, LinkExecute, LinkRequest, and LinkSend methods) to enable a control or form to communicate through DDE (Dynamic Data Exchange) protocol with other controls or forms, possibly in another application. Before the advent of OLE and COM, Dynamic Data Exchange was the preferred way for two Windows programs to communicate. These days, you shouldn't use this technique because these properties have been maintained only for backward compatibility with applications written in previous versions of Visual Basic. I won't cover DDE in this book.

Just as there are many properties that most objects share, they also have many methods in common. In this section, we examine these methods.

If a control supports Left, Top, Width, and Height properties, it also supports the Move method, through which you can change some or all four properties in a single operation. The following example changes three properties: Left, Top, and Width.

' Double a form's width, and move it to the upper left corner of the screen.
' Syntax is: Move Left, Top, Width, Height.
Form1.Move 0, 0, Form1.Width * 2

Note that all arguments but the first one are optional, but you can't omit any of them in the middle of the command. For example, you can't pass the Height argument if you omit the Width argument. As I mentioned in the description of individual properties, you should be aware that the Height property is read-only for the ComboBox control.

TIP
The Move method should always be preferred to individual property assignment for at least two reasons: This operation is two to three times faster than four distinct assignments, and if you're modifying the Width and Height properties of a form, each individual property assignments would fire a separate Resize event, thus adding a lot of overhead to your code.

The Refresh Method

The Refresh method causes the control to be redrawn. You normally don't need to explicitly call this method because Visual Basic automatically refreshes the control's appearance when it has a chance (usually when no user code is running and Visual Basic is in an idle state). But you can explicitly invoke this method when you modify a control's property and you want the user interface to be immediately updated:

For n = 1000 To 1 Step -1
Label1.Caption = CStr(i)
Label1.Refresh ' Update the label immediately.
Next
CAUTION
You can also refresh a form using the DoEvents command because it yields the control to Visual Basic, and the Visual Basic form engine exploits this opportunity to update the user interface. But you should be aware that DoEvents performs additional processing as well—for example, it checks whether any button has been clicked and if so it executes its Click procedure. Therefore, the two techniques aren't always equivalent. In general, using the Refresh method on the only control that has been modified delivers better performance than executing a DoEvents command. It also avoids reentrancy problems that can occur, for example, when the user clicks again on the same button before the previous Click procedure has completed its processing. If you want to update all the controls on a form but you don't want the end user to interact with the program, just execute the Refresh method of the parent form.

The SetFocus Method

The SetFocus method moves the input focus on the specified control. You need to call this method only if you want to modify the default Tab order sequence that you implicitly create at design time by setting the TabIndex property of the controls on the form, as we saw in Chapter 1. The control whose TabIndex property is set to 0 receives the focus when the form loads.

A potential problem with the SetFocus method is that it fails and raises a run-time error if the control is currently disabled or invisible. For this reason, avoid using this method in the Form_Load event (when all controls aren't yet visible) and you should either ensure that the control is ready to receive the focus or protect the method with an On Error statement. Here's the code for the former approach:

' Move the focus to Text1.
If Text1.Visible And Text1.Enabled Then
Text1.SetFocus
End If

And here's the code for the other possible approach, using the On Error statement:

' Move the focus to Text1.
On Error Resume Next
Text1.SetFocus
TIP
The SetFocus method is often used in the Form_Load event procedure to programmatically set which control on the form should receive the focus when the form initially appears. Because you can't use SetFocus on invisible controls, you're forced to make the form visible first:

Private Sub Form_Load()
Show ' Make the form visible.
Text1.SetFocus
End Sub

Here's another possible solution:

Private Sub Form_Load()
Text1.TabIndex = 0
End Sub

Note that if Text1 isn't able to receive the input focus (for example, its TabStop property is set to False), Visual Basic automatically moves the focus on the next control in the Tab order sequence, without raising any error. The drawback of this second approach is that it affects the Tab order of all other controls on the form.

The ZOrder Method

The ZOrder method affects the visibility of the control with respect to other overlapping controls. You just execute this method without any argument if you want to position the control in front of other controls; or you can pass 1 as an argument to move the control behind other controls:

' Move a control behind any other control on the form.
Text1.ZOrder 1
Text1.ZOrder ' Move it in front.

Note that you can set the relative z-order of controls at design time using the commands in the Order submenu of the Format menu, and you can also use the Ctrl+J key combination to bring the selected control to the front or the Ctrl+K key combination to move it behind other controls.

The actual behavior of the ZOrder method depends on whether the control is standard or lightweight. In fact, lightweight controls can never appear in front of standard controls. In other words, the two types of controls—standard and lightweight—are located on distinct z-order layers, with the layer of standard controls in front of the layer of lightweight controls. This means that the ZOrder method can change the relative z-order of a control only within the layer it belongs to. For example, you can't place a Label (lightweight) control in front of a TextBox (standard) control. However, if the standard control can behave like a container control—a PictureBox or a Frame control, for example—you can make a lightweight control appear in front of the standard control if you place the lightweight control inside that container control, as you can see in Figure 2-5.

The ZOrder method also applies to forms. You can send a form behind all other forms in the same Visual Basic application, or you can bring it in front of them. You can't use this method, however, to control the relative position of your forms with respect to windows belonging to other applications.










Figure 2-5. Relative z-order of controls.

No comments:

Post a Comment