\[Editor's Note: VB Solutions is about using Visual Basic (VB) to build a variety of solutions to specific business problems. This column doesn't teach you how to write VB, but how to use VB as a tool to provide quick, easy-to-implement solutions that you can use right away.\]
Each VB Solutions column presents a different utility, but the programs in three VB Solutions columns ("Building a Network Security Monitor," November 1996, "Managing SQL Server with VB," December 1996, and "Exporting Data from SQL Server," January 1997) contained one common element: Each program displayed a specific subset of networked systems in a drop-down combo box. Instead of rewriting the code to retrieve the networked system names in each of these programs, why not create a custom control from Visual Basic's (VB's) toolbox? Then you can simply drag the control to each VB project--and to other projects--in which you need to select from a list of networked systems. You can design the custom control to appear as a combo box automatically filled with a set of networked system names. Better still, if the control is an ActiveX control, you can use it with other Object Linking and Embedding (OLE)-compliant applications, such as Access or Excel.
Unfortunately, VB 4.0 doesn't come with any built-in controls that have the ability to query the network, and you cannot use VB 4.0 to develop ActiveX controls. However, the newest version of VB, VB 5.0 Control Creation Edition (VB5CCE), changes everything: Now you can write ActiveX controls using VB.
As of press time, you can download the VB5CCE beta from Microsoft's Web site at http://www.microsoft.com/vbasic. The VB5CCE beta can give you a good indication of what the general release version of VB 5.0 is like. VB5CCE delivers a substantially revised development environment. More important, VB5CCE addresses one of VB's primary limitations--the inability to create ActiveX controls. The sidebar, "A Brief Preview of the Visual Basic 5.0 Development Environment ," page 162, provides additional information about VB5CCE.
An Overview of the Network Systems Control
In this month's column, I'll demonstrate how to use VB5CCE to create a Network Systems ActiveX control that automatically retrieves a specific set of networked system names and displays them in a combo box. You can regulate what type of names the combo box displays by setting the System Type property in the Network Systems ActiveX control. You can list all NT systems, all NT Server systems, all Primary Domain Controllers (PDCs), or all SQL Servers on your network. You can snap the Network Systems ActiveX control into other VB projects or into any OLE-compliant applications to instantly get a combo box that displays a list of networked systems--without additional coding. Screen 1, page 163, shows a very simple VB5CCE example program that uses the Network Systems ActiveX control.
Building the Network Systems ActiveX Control
You can build OLE controls with VB5CCE three ways: You can use the controls included in the VB toolbox (easy), you can subclass a control from one of the standard Windows controls (more difficult), or you can manually create and draw the control using VB code (most difficult). Because this column focuses on expedient solutions, let's build the Network Systems ActiveX control using the combo box control provided in VB5CCE's toolbox.
When VB5CCE first starts, it presents a project wizard that lets you select the type of application to create. You can choose an ActiveX Control project, a Standard EXE project, or a CTLGROUP project. ("A Brief Preview of the Visual Basic 5.0 Development Environment," describes the basic VB5CCE development environment.) As you might expect, you can use the ActiveX Control project wizard to create an ActiveX Control and the Standard EXE project to create a standard Win32 program. The CTLGROUP project is a concept new to VB5CCE that lets you combine one or more ActiveX Control projects and a Standard EXE project. The CTLGROUP project is quite useful for testing ActiveX controls because you typically run them from another application.
To begin building the Network Systems ActiveX control, select the ActiveX Project, which displays a design Window that contains the UserControl1 ActiveX control template. From a design perspective, UserControl1 is similar to a VB 4.0 form: You drag controls from the toolbox to a window in the design environment. The difference is that VB5CCE calls the window UserControl1, instead of Form1. Double-click the combo box icon in the VB5CCE toolbox to put the combo box control in the UserControl1 window.
Reposition the control to the upper left corner of the UserControl1 window, and resize the control, as shown in Screen 2. Next, resize the UserControl1 window to fit the combo box. You need to resize the window because it can cover other controls or interface objects if it remains larger than the standard combo box control it contains. Because the purpose of this control is to display just a combo box, you don't want the interface to show anything other than the combo box.
Next, rename the ActiveX project by changing the Name property in VB5CCE's Project window from Project1 (the default name) to NetworkSystems. Changing the project name identifies the ActiveX control as NetworkSystems.ocx. That's all you have to do to create the basic interface for the Network Systems control.
Adding a Custom Property
After creating the user interface, the next step is to add custom properties, methods, and events. The simple Network Systems control uses only one custom property, SystemType. The SystemType property specifies the type of networked systems to be displayed in the Network Systems combo box. The SystemType property lets you use the Network Systems control in a variety of network applications without changing any of the code. For instance, you can set the SystemType property to retrieve all NT systems on the network, just NT Server systems on the network, or only SQL Server systems on the network. This flexibility lets you use the Network Systems control for many different purposes.
To add the custom SystemType property, run the ActiveX Control Interface Wizard from VBCCE's Add-Ins menu. The ActiveX Control Interface Wizard lets you interactively define the ActiveX control's properties, methods, and events. First, you select the desired properties from a list of default ActiveX properties. Then you can add the custom properties that you want. Screen 3 shows the VB5CCE ActiveX Control Interface Wizard dialog box to add the SystemType property. When the ActiveX Control Interface Wizard finishes, it automatically adds the underlying VB code that supports the custom properties, events, and methods.
Although the ActiveX Interface Wizard simplifies specifying default properties and adding custom properties, the beta version that I used didn't provide support for enumerated properties (which let the user select the desired property value from a list of valid values). By default, the ActiveX Control Interface Wizard made the custom SystemType property a variant data type. A variant data type property accepts any kind of data the user enters, but it does not display a list of valid properties in the design environment. The ActiveX Control Interface Wizard lets you select several other data types (e.g., Long, String), but none of these data types support an enumerated list.
To add support for an enumerated list, I had to manually add the enumeration and change the Get and Let methods the ActiveX Control Interface Wizard automatically generated. Listing 1 shows the SystemTypes Enum data type I added, and Listing 2 shows the modified Get and Let methods that let me use the SystemTypes Enum datatype as a property.
Oddly, after manually adding the enumeration and modifying the Get and Let subroutines, the ActiveX Control Interface Wizard displayed the SystemTypes Enum data type. Perhaps Microsoft will fix this after-the-fact definition problem by the time it releases the final version of VB5CCE.
Calling the Network API
The next step in creating the Network Systems ActiveX control is adding the Network API code to retrieve the list of network names and add them to the combo box. I added the same NetAPI.BAS file that I used in the other VB Solutions programs.
To add the NetAPI.BAS file, I selected Add Module from the VB5CCE Project menu. Next, I copied the GetServerInfo subroutine from my November Network Monitor column into the Network Systems project and called the subroutine from the UserControl_Show subroutine. Listing 3 shows the code for the UserControl_Show subroutine.
The UserControl_Show subroutine is a standard VB5CCE subroutine you usually call just before you want to display the control. Placing the call to the GetServerInfo subroutine in the UserControl_Show subroutine ensures that the Network Systems control's combo box will contain the list of networked names just before the user sees the control.
Because the UserControl_Show subroutine is called both at design time and at runtime, the subroutine must determine what to do for each event. For example, I didn't want the Network Systems control to query the network when I used the ActiveX control in the VB design environment because queries add unnecessary overhead and slow down the design environment.
The VB5CCE built-in Ambient Object contains a UserMode property that signals whether the control is being used in design time or runtime. In Listing 3, you can see the code that checks the UserMode of the Ambient Object to determine whether the control is in design mode or run mode. If the UserMode is true, the Network Systems control is in run mode and UserControl_Show calls the GetServerInfo subroutine to query the network for the connected system names.
Listing 4 presents the GetServerInfo subroutine. I explained the GetServerInfo subroutine in the November VB Solutions column, so in this column I won't detail how the NetServerEnum API works. Instead, let's look at what I had to change in GetServerInfo to use it as part of an ActiveX control.
In the original version of this code, I set the server type via a global constant. For greater flexibility, the Network Systems ActiveX control uses the SystemType property instead of a constant. Either you set the SystemType property in design mode, or program code sets it at runtime and passes the property to the Network API.
At callout A in Listing 4, you can see where the subroutine calls the GetHexServerType function to retrieve the server type from the SystemType property, and places the information in the lServerType variable. The seventh parameter of the NetServerEnum API uses the lServerType variable to specify the type of network systems the NetServerEnum API returns. The NetServerEnum API requires a hexadecimal value for the lServerType parameter. The GetHexServerType function, shown in Listing 5, converts the user-friendly values the SystemType property displays to the hexadecimal values the NetServersEnum API requires.
Finally, the GetServerInfo subroutine must load the list of network system names returned by the NetServerEnum API into the combo box control. You can see that section of code at B in Listing 4. Although this combo box is part of an ActiveX control, the VB code to work with the combo box is nothing unusual. You still use the VB AddItem method to add the system names to the combo box.
After I added the code to retrieve the names of the networked systems, I closed the design window, which automatically added the new Network Systems control to the VB5CCE toolbox. As you can see, incorporating existing VB code into a VB5CCE ActiveX control requires only minor changes. Learning about the new VB5CCE development environment and its paradigm for building ActiveX controls took more time than moving the code from the original VB 4.0 project to the new VB5CCE project.
Creating a Test Program for the Network Systems Control
You can use VB5CCE to create more than just ActiveX controls. You can also use VB5CCE to create standard Win32 programs.
VB5CCE's new CTLGROUP project feature can combine both ActiveX projects and Standard EXE projects, so testing the ActiveX controls you create is easy. I put together the simple test program shown in Screen 1 to test the Network Systems ActiveX control.
To create the test program, I selected Add Project from the File menu to display the VB project wizard. From the project wizard, I selected a Standard EXE project. The project wizard displayed a standard VB form in the design window and added a Standard EXE project into VB's project window.
After creating this new project, I changed the Name property to Test Network Systems Control. I double-clicked the Network Systems control in the VB5CCE toolbox to add the Network Systems control to the VB Form.
Next, I changed the SystemType properties to show all NT systems. Then I added the other text box and button controls to help me test the control. Finally, I clicked the Run icon on the VB5CCE toolbar to run the test program and the new Network Systems control.
Adding the New Control to Your VB 4.0 Projects
Once you create the Network Systems control, you can add it to any of your VB projects to display a combo box that lists your networked systems. You add an ActiveX control the same way you add any other custom control--you use the Custom Controls option from VB 4.0's Tools menu.
However, I built the Network Systems control using VB5CCE, so the VB5CCE runtime program, msvbvm50.dll, must be present for an application program to use this control. You must use caution when you deploy programs and controls created with beta products because the development platform can change.
Although I haven't experienced any problems with the Network Systems control, you need to remember that beta products have not yet completed the quality assurance and testing procedures that released products have completed.
As you can see, the new VB5CCE makes building an ActiveX control almost as easy as building a typical VB program. In addition, the new development environment's use of project groups lets you easily build test containers for your VB5CCE ActiveX controls.