Active X Controls IconBasic Principles of ActiveX Controls:Active X Controls Icon

ActiveX controls have two modes of operation, design-time and run-time. Design-time occurs when the ActiveX control is placed into a standard Visual Basic project. Usually the control is given the name UserControl11 if it has not been renamed when the control was designed, this process is known as instantiating the control. If another instance of the ActiveX control is added to the standard Visual Basic project it would be called UserControl12, as many instances of these ActiveX controls can be added to a standard Visual Basic project as needed. At this point the ActiveX control can be selected (indicated by the sizing handles) and its properties can be changed in the Property Window of the standard Visual Basic project at design-time hence the name. Run-time for the ActiveX control occurs when the standard Visual Basic program using the ActiveX control is run by clicking the F5 function key or pressing the start button on the toolbar. At this point in time the design-time instance of the ActiveX control is destroyed and a completely new run-time instance of the ActiveX control is created. ActiveX control persistence allows you to pass information from one instance (creation) of a control to the next instance (creation) of the control. For an ActiveX control this persistence usually involves remembering property values while toggling back and forth between the design and run time phases of the control. Persistence is achieved by the use of Property Bags and the ReadProperties and WriteProperties events of the ActiveX control. This is an important concept to grasp in order to understand the necessity of needing the four key ingredients of ActiveX controls for them to work properly; Property Get, Property Let, ReadProperty Method, and WriteProperty Method. The properties of the ActiveX control are stored within a special object in Visual Basic known as the Property Bag. The Get, Let, ReadProperty and WriteProperty are designed to manipulate the contents of the Property Bag. The Initialize event for the ActiveX control is fired when the control is loaded from the toolbox into a new Visual Basic project, or when the new project is run containing the ActiveX control. It is also fired when the project containing the control is stopped initializing the design-time instance of the control, or when a form containing the ActiveX control is selected in the Project Window of a Group project. The Terminate event for the ActiveX control is fired when the project containing it is run terminating the design-time instance of the control. It is also fired if the ActiveX control is deleted from the project containing it or the group project is closed by exiting Visual Basic.

Example using Visual Basic Group: (ActiveX and Standard Visual Basic Projects)

Follow the steps listed below to demonstrate the relationship of these properties and methods between an ActiveX control project and a standard Visual Basic project to test it at design-time and run-time. The code in the ActiveX control project shown below is used to create a new property for the ActiveX control (UserControl1) called NewText which will show in the property window when the ActiveX control is selected after it is placed into a new standard Visual Basic project. This NewText property of the UserControl is mapped to the Text property of the Text1 constituent control contained in the UserControl.

Open Visual Basic, then select New Project from the File menu, select Standard Exe Standard Exe Iconfrom New Project window.

Return to File menu and select Add Project, select ActiveX Control Active X Control Iconfrom the Add project window. The project window should look like the diagram listed below.

Project Group Window VB6 building User Control

Double-click on the text box icon Text Box Toolbox Icon in the toolbox to add a text box control named Text1 to the ActiveX control.

Right-click on the ActiveX control in the project window labeled UserControl1 and select View Code from the short-cut menu. Type in the code listed in the figure listed below.

UserControl Code Sample Diagram

Code explained:

The new NewText property of the ActiveX control is setup using the Property Get procedure of the ActiveX control, the Property Get procedure will allow us to read the value of the new property (NewText) from the Property Bag in the Property Window at design-time. If the Property Get procedure is used without the Property Let procedure for a new property being created within the ActiveX control then the value of the new property can be gotten from the Property Bag but not changed making it effectively a Read-Only property. For the value of NewText property in the Property Window we can enter any string value. A series of message boxes is placed in key events of the ActiveX control to demonstrate how the NewText property works during design-time and run-time.

Close the code window, close the UserControl1 form.

Double-click Form1 in the Project window to select it. Double-click the ActiveX control icon Active X Control Iconin the toolbox to place the ActiveX control on the form.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

The following message boxes will be displayed showing that the ActiveX control called the Property Get procedure to retrieve a value from the Property Bag for the NewText property and was initialized when it was placed on the form. Even though the form is in design mode the ActiveX control is initialized and running. The NewText property has the default value of Text1 because the constituent control Text1 within it has this value. Notice in the Property Window the Property Name of NewText can not be found, this is because the Property Get procedure was used without its corresponding Property Let procedure for the NewText property effectively making it a Read-Only property since its value can not be changed by the user.

The ActiveX control will now appear on Form1 of the test project. Run the project by clicking the F5 function key. The following message boxes will be displayed.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

The instance of the ActiveX control that was running at design-time is being terminated. A new instance or copy of the ActiveX control will be created to be used when Form1 is running. The following message boxes will be displayed creating the run-time instance of the ActiveX control.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

Visual Basic destroyed the design phase instance of the ActiveX control and created a new instance of the ActiveX control for the run-time phase of Form1. Select Text1 inside the control and type in "David" and press the Enter key to attempt to change the value of the NewText property of the control at run-time. Close the form. The following messages boxes for the run-time instance of the ActiveX control message will appear.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

From the message boxes listed above it appears that we are going to be able to change the value of the new property (NewText) of the ActiveX control at run-time.

The following messages boxes for the design-time instance of the ActiveX control message will appear.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

Notice the information did not get saved from the run-time instance to the design-time instance of the ActiveX control. Let's see if we can affect this outcome by adding the Property Let Procedure code to the ActiveX project.

Open the code window for the ActiveX control (UserControl1) listed above, type the code listed below for the Property Let procedure.

Property Let NewText Code Window Example

Code explained:

The Property Let procedure will allow us to change the value in the Property Bag for the new property (NewText) in the Property Window at design-time. The PropertyChanged statement will raise the WriteProperties event of the UserControl once we write the code for this event later on in this tutorial. The ByVal parameter found in the Property Let procedure coding is similar to a Dim statement in that it tells Visual Basic that the argument of the procedure should be passed By value rather then the other possibility By Reference, it allows us to substitute other names for NewValue, it creates only a temporary instance of the parameter every time the Property Let procedure is called.

Close the code window, close the UserControl1 form. The following messages boxes will be displayed, which are setting up the new design mode phase of our ActiveX control reflecting the Code addition.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

Double-click Form1 in the Project window to select it. Select the ActiveX control (UserControl11) on Form1 by clicking it. The following message box will be displayed. Every time the ActiveX control is selected by clicking on it Visual Basic goes to the Property Bag and retrieves a current value for its property by using the Property Get procedure. You might think of this process as refreshing the value of the property. As you will see in the rest of this tutorial, Visual Basic goes into the Property Bag often to perform this refreshing process to insure that the correct value for the property is present.

Message Dialog Box Click the OK Button Icon button

Notice the NewText property name now appears in the Property Window of Form1 with the ActiveX control selected. Type in a value of David for the NewText property found in the Property Window and press the Enter key.. This will activate the Property Let procedure found inside the ActiveX control, to allow you to change the value of the property at design-time. The following message boxes will be displayed.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button Message Dialog Box

Notice how the property value is refreshed using the Property Get procedure during and after the change takes place in the Property Let procedure.

Click the OK Button Icon button. The value in the Property Bag for NewText property has changed from its default value of "Text1" to "David"

Run the project by clicking the F5 function key. The following message boxes will be displayed wrapping up the design-time phase of the control.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

The following message boxes will be displayed setting up up the run-time phase of the control.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

Form1 in run mode will now appear on the screen. Notice the design-time value of "David" for the NewText property did not carry over to the run-time instance of the control. The property value for the property named NewText has no persistence!

Visual Basic destroyed the design phase instance of the ActiveX control and created a new instance of the ActiveX control for the run-time phase of Form1. Select Text1 inside the control and type in "David" and press the Enter key to attempt to change the value of the NewText property of the control at run-time. Close the form. The following messages boxes for the run-time instance of the ActiveX control message will appear.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

From the message boxes listed above it appears that we are going to be able to change the value of the new property (NewText) of the ActiveX control at run-time.

The following messages boxes for the design-time instance of the ActiveX control message will appear.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

Select the ActiveX control (UserControl11) on Form1 by clicking it. The following message box will be displayed.

Message Dialog Box Click the OK Button Icon button

Notice the information did not get saved from the run-time instance to the design-time instance of the ActiveX control. Also notice by checking in the Property Window that the original design-time value of "David" for the NewText property got wiped out in the shuffle between the design-time, run-time, and design-time instances of the control.

Delete the control (UserControl11) from Form1 by pressing the Delete key, and you will see the terminate event fire for the last time.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

All references to this copy of the control are now gone. There is no persistence here.

Adding Persistence to ActiveX Control:

It does not make sense to put values in for the NewText property at design-time and then have to put them in again at run-time. How do we pass this information from the design-time instance of our ActiveX control to the run-time instance of the ActiveX control. This ability to pass the values of the properties of the control as it moves back and forth between its design mode phase and run mode phase is known as persistence. We could write the information to a file somewhere but this method becomes complicated when we have many instances of the ActiveX control present on the same form since we need to uniquely identify each copy of the ActiveX object. Microsoft provides us with an alternative to the file method by providing us with Property Bags (which are designed to hold the ActiveX control property values) and the ReadProperties and WriteProperties events.

Property bags store information for each copy of your control. You don't have to worry about keeping track of which property bag belongs to which copy of your control when using them to store information during the transition from design-time to run-time. Property Bags have two methods, ReadProperty and WriteProperty, and one property Contents.

Property Bag Methods and Property Explained

ReadProperty Method: has two parameters: Property Name and Default Value (optional)

  1. Property Name - unique property name, used to retrieve an item from the Property Bag
  2. Default Value - value method will return if there is no item in the bag with the name used in Property Name parameter. If default value is left out and this item is not in the property bag an error is raised, so it is a good idea to use a default value

WriteProperty Method: has three parameters: Property Name, Property Value, and Default Value (optional)

  1. Property Name - unique property name, used to store an item to the Property Bag
  2. Property Value - the value of the property that will be saved in the Property Bag
  3. Default Value - The default value is compared to the value you are setting the Property Value to, if the values are different an extra line of code is added to your project files. If the values are the same, nothing is written to the project files. Therefore using a default value can make your project files smaller.

Contents Property: - Returns or sets a byte array that represents the contents of the property bag . Can be used to get entire contents of the property bag and save the contents to a file or database. Can also fill the property bag by setting the property to a byte array.

Note: When the ReadProperties and WriteProperties events occur in the ActiveX control code, they will respectively call the ReadProperty and WriteProperty methods of the Property Bag object.

Follow the example listed below to see these events and methods used in Visual Basic to establish persistence.

Persistence Example using Visual Basic Group: (ActiveX and Standard Visual Basic Projects)

Open the code window for the ActiveX control (UserControl1) listed above, select UserControl on the object dropdown list type the code listed below for the ReadProperties, WriteProperties, and InitProperties events.

InitProperties, ReadProperties, and WriteProperties Code Window Example

Code explained:

The InitProperties event of the ActiveX control is called only once, when the control is first placed on Form1 from the toolbox. If there is anything special we have to do the first time the ActiveX control is created, it can be done in the InitProperties event of the control. The first time the control is created there will be no Property Bag to retrieve information. Since there is no property bag, the ReadProperties event is not raised when the control is first created (first placed on Form1). Therefore the only way to set your properties the first time the control is created is by setting them in the InitProperties event. When the control is destroyed (such as when the application is run or the form is closed) the WriteProperty method is called and the information is stored in the Property Bag. From that point on, the ReadProperty method will be called and the values can be retrieved from there. Follow the steps listed below to demonstrate these concepts in a Visual Basic group project.

Close the code window, close the UserControl1 form.

Double-click Form1 in the Project window to select it. Double-click the ActiveX control icon Active-X Control Iconin the toolbox to place the ActiveX control on the form. The following initializing message boxes will be displayed, initializing the ActiveX control in design mode

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

The following message boxes will be displayed.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

This time, we also get something extra - we now see the InitProperties Event message box:

Message Dialog Box Click the OK Button Icon button

Go to the Property Window and notice the value is "Text1" for the NewText property even though we set the Default Value to "David" in the ReadProperties event code. This is because the property bag is not yet active as mentioned above. Go to the Property Window and change the NewName property of the ActiveX control (UserControl11) to Zorro and press the Enter key, this change will fire the WriteProperties event of the ActiveX control and save the value to the Property Bag. The following message boxes will display

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button Message Dialog Box

Click the OK Button Icon button. Press the F5 function key to run the application. The following message boxes should be displayed.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button Message Dialog Box

Click the OK Button Icon button. This time, before the design-time instance of the control was destroyed the WriteProperties event of the ActiveX control was called. This means that the value of the NewText property (Zorro) is now in the Property Bag.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button Message Dialog Box

Click the OK Button Icon button, design mode instance of the ActiveX control is now destroyed. The following messages boxes are setting up the run-time instance of the ActiveX control.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

Notice during the initialization of the ActiveX control that the NewText has a value of Text1. This makes sense since we have not yet reached the point where the ReadProperties event has been called.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button.

We have now entered the ReadProperties event of the ActiveX control and retrieved the correct value (Zorro) from the Property Bag. It is important to realize that these properties were not set during the initialize event as demonstrated in the message boxes above. If you need to do something with property values while the control is loading it must be done during the ReadProperties event. Form1 will now display in run-time mode, double-click "Zorro" in the control and type in "runtime" and press the Enter key to change the value of the NewText property at run-time. Close Form1, the following message boxes will be displayed.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

The run-time phase of the control is now destroyed. The following messages box are setting up the design-time instance of the ActiveX control.

Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button Message Dialog Box

Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button Message Dialog Box Click the OK Button Icon button

Message Dialog Box

Click OK Button Icon to see Form1 at design-time. Select the ActiveX control (UserControl11) by clicking on it. Click OK Button Iconto the Property Get message box. Go to the Property Window and notice that the NewText property of the ActiveX control (UserControl11) is still set to "Zorro" not "runtime". The information did not get saved from the run-time instance to the design-time instance of the ActiveX control, the original design-time value of "Zorro" for the NewText property was restored. What does this mean ? The WriteProperties event of an ActiveX control only saves the values of properties to the Property Bag of the Control in design time mode. You are not allowed to change the values permanently in the Property Bag of an ActiveX control at run-time. The property values of an ActiveX control changed during run-time are temporary, they are not saved to the Property Bag. This make sense if you think about it, what if we had multiple instances of the ActiveX control on the same form, you would not want Visual Basic to change to values to those set at run-time for all the ActiveX controls present on the form based on run-time settings of a single instance of the ActiveX controls.

We have discovered how to use Property Bags to save our information from one instance of our control to the next to maintain persistent information.