DHTML Application

DHTML (Dynamic HTML) is a new concept introduced by Microsoft, where developers can dynamically change style and attributes of elements in HTML page after the page is loaded. Dynamic HTML allows you to break HTML page into various elements and program individual elements. That means you can treat a line of text as an element and change its attributes such as foreground color, background color etc, at run time using the code. You can also write code for events of elements.

DHTML is a new way of creating a Web page and it is made available to Visual Basic 6.0 programmer through DHTML application.

Note: To run DHTML application, you must have Internet Explorer 4.x or higher.


What is a DHTML application?
A DHTML application is a collection of HTML pages and Visual Basic code. DHTML application resides on the client machine and runs in Web Browser (Internet Explorer). The code written in Visual Basic responds to event such as user clicking on a button, mouse moving over an element etc.

Structure of DHTML application
A DHTML application is consisting of the following pieces:

• One or more HTML pages
• Visual Basic code to handle events that occurs in browser when user is viewing HTML pages.

Form-based application vs. DHTML application
Unlike a normal Visual Basic application, in DHTML application, the user interface consists of a collection of HTML pages. When user runs the application in Web browser, the user interacts with HTML pages and not Forms.

An HTML page can contain control just like a form. HTML page is stored with extension .htm, which is similar to .frm of a Form.

The following table will highlight the differences between form-based application and DHTML application.

Item Form-based Application DHTML application
User Interface Forms HTML pages
User interface elements such as buttons, text boxes. Controls Elements
File format .frm .htm
Creator Developer Developer or Web Designer.
Run time Visual Basic run time DLL, msvbvm60.dll Web browser control with msvbvm60.dll.
Table 31.1: Comparing Form-based application with DHTML application.




Features of Dynamic HTML
Dynamic HTML is relatively new concept. It takes some time for it to settle down. The following are the key features of Dynamic HTML. For detailed information regarding each of these features, please see on-line documentation.

• Allows you to create more interactive user interface through dynamic styles and dynamic content. Dynamic styles allow you to change the style of element at run time. Dynamic content allows you to customize (adding new elements, removing existing elements and modifying elements) the web page without browser submitting the request to server. This reduces time taken for customization.
• Allows you to place any element at the required position by using x and y coordinates.
• When an event occurs on a child object, the event can travel up the chain of hierarchy within the page until it encounters an event handler to process the event. This process is called event bubbling.

Developing a DHTML Application
Developing a DHTML application is not much different from a form-based application. The following are the steps involved in the process:

• Start a new project and select DHTML Application as the project type.
• From the Project Explorer window, open DHTML page designer by double clicking on the page.
• If you are designing your user interface from scratch, add HTML elements and ActiveX controls to your page and arrange them as desired.
• If you want to edit an existing page, use the Properties dialog box to refer an external HTML file, then make any necessary changes to the page's contents and appearance.
• Add code for any elements on the page for which you want to handle user actions.
• If necessary, add other pages to the project, add elements to them, and write code.
• Test and debug the application by running the project and viewing the document in Internet Explorer 4.01 or later.
• Compile the project.
• Deploy the application using the Package and Deployment Wizard.

Saving a DHTML page
You can save DHTML page in either of two ways:

Save it within designer file - saves the page as part of your application. No external .htm file is created. The .dsr file contains the page. This method is good when you want to move your application from one machine to another. But it doesn’t allow you to edit .htm file using external editor.

Save the page to a location on your computer - the page is saved to an external file, whose absolute path is given using Sourcefile property. This allows you to use external editor to edit .htm file. But it becomes difficult to move all external files when you move your application.


Writing code for Dynamic HTML
When you are working with DHTML application in Visual Basic, you use Dynamic HTML object model to access and manipulate HTML element on the page. You can modify appearance and behavior using properties and method of the elements.

Dynamic HTML object model
The following are the main objects in object model.

Basewindow - is a reference to the browser that displays the page. This is the topmost object in the hierarchy of Dynamic HTML object model.

Document – represents HTML page that you view in browser.

Events in Dynamic HTML
Most of the events of Dynamic HTML are same as events in Visual Basic. However the names of the event slightly differ. For example, Click event in Visual Basic programming model will be OnClick in Dynamic HTML object model.

Note: All events in Dynamic HTML are preceded by word “on”.

Also note that there are certain new event in Dynamic HTML that are not available in Visual Basic and some of the Visual Basic events are not available in Dynamic HTML.

Visual Basic events vs. Dynamic HTML events
The following tables list events in Visual Basic and corresponding events in Dynamic HTML in various categories.

Keyboard Events
Keyboard events in Dynamic HTML correspond very closely to keyboard events in Visual Basic. The following table lists the common Visual Basic keyboard events and their Dynamic HTML counterparts:

Visual Basic Event DHTML Event Comments
keydown onkeydown Fires when a key is pressed.
keypress onkeypress Fires when a user's keyboard input is translated to a character.
keyup onkeyup Fires when a user releases a key.
Table 31.2: Comparing Visual Basic form events with DHTML events.

When a keyboard event occurs, the keycode property of Dynamic HTML's event object contains the Unicode keycode of the corresponding key. The altKey, ctrlKey, and shiftKey properties specify the state of the ALT, CTRL, and SHIFT keys.

You can change which key is associated with the event by either changing the value of the keycode property or returning an integer value.

Note: You can cancel the event by returning zero or false.
Mouse Events
Mouse events in Dynamic HTML correspond closely to mouse events in Visual Basic. The following table lists the common Visual Basic mouse events and their Dynamic HTML counterparts:

Visual Basic Event DHTML Equivalent Comments
click onclick In addition to occurring when a user clicks on an element, this event also fires when the user presses ENTER on an element that can receive focus, such as a button.
doubleclick ondblclick This event works similarly to its Visual Basic counterpart.
mousedown, mouseup, mousemove onmouseout, onmousedown, onmouseup, onmousemove, onmouseover When moving between elements, the onmouseout event fires first to indicate that the mouse has left the original element. Next the onmousemove event fires, indicating that the mouse has moved. Finally, onmouseover fires to indicate that the mouse has entered the new element.
Table 31.3: Comparing Visual Basic Events with DHTML events.

When a mouse event occurs, the button property of the event object identifies which mouse button (if any) is down. The x and y properties specify the location of the mouse at the time of the event. For onmouseover and onmouseout events, the toElement and fromElement properties specify the elements the mouse is moving to and from.

Focus and Selection Events
Focus and selection events in Dynamic HTML differ slightly from their Visual Basic counterparts. In particular, focus events are called only from certain elements, and selection and dragging are handled differently.

The following table lists the common Visual Basic focus and selection events and their Dynamic HTML counterparts:

Visual Basic Event DHTML Equivalent Comments
gotfocus onfocus Fires when the user moves to an element capable of receiving input, such as a button or form element.
lostfocus onblur Fires when you move out of an element that is capable of receiving input.
selchange onselectstart
onselect The onselectstart event fires when a selection is first initiated — for example, when the user clicks a character or object in the document. Onselect fires when the user changes the selection — for example, by moving the mouse over a portion of the document while holding down the mouse button.
dragdrop, dragover ondragstart Fires when the user first begins to drag the selection. The default action is to prepare the selection to be copied to another element.
Table 31.4: Focus events comparison.

Note: Onblur and onfocus fire whether you move between elements in the page, between frames, or even between applications on the desktop. For example, if a page element has focus and the user switches to another application, the onblur event fires for that element. When the user switches back, onfocus fires.

Other Events
The following are the events that do not belong to any of the categories discussed so far.

Visual Basic Event DHTML Equivalent Comments
change onchange Onchange fires when the user tabs off or presses ENTER on an element, moving out of it. In Visual Basic, the change event fires as soon as the user performs any action within the control.
close Not Available No direct equivalent exists for this event.
error Onerror Fires when an error occurs loading an image or other element, or when a scripting error occurs.
initialize Onready
statechange Fires when the page changes from initializing to interactive, and from interactive to loaded. A page is interactive as soon as the user can interact with it by scrolling or clicking on anchors or elements. A page is loaded when all the content has been downloaded.
load Onload Fires after the document is loaded and all the elements on the page have been completely downloaded.
paint Not Available No direct equivalent exists for this event.
resize onresize This Dynamic HTML event functions similarly to its Visual Basic counterpart; however, you do not need to write code to handle resizing of an HTML page as you do a Visual Basic form. Resize in HTML happens automatically.
scroll onscroll Fires whenever the scroll box for the page or any element within it is repositioned.
terminate Not Available No direct equivalent exists for this event. You can perform terminate-type actions in the onunload event. A terminate event does exist for the DHTMLPage object. This object is not part of the DHTML object model, and is unique to Visual Basic.
unload onunload Fires immediately prior to the document being unloaded (when navigating to another document).
Table 31.5 : Comparing miscellaneous events.

Events Unique to Dynamic HTML
In addition, there are some events in Dynamic HTML that do not have equivalents in Visual Basic. A few of the more interesting of these are shown in the following table:
DHTML Event
Usage
Onabort Fires when the user aborts the download of an image or page element by pressing the Stop button.
Onreset Fires when the user selects a Reset button on a form.
Onsubmit Fires when the user selects a Submit button on a form. Can be used to perform validation of data on the client before sending it to the server.

Making Elements programmable
You can programmatically handle elements on HTML page in DHTML application. That means you can write code for events of the elements and the code is executed whenever the event occurs on the element. You can also change property of the elements dynamically.

To make an element programmable, the element must be assigned an ID. Some elements are by default assigned and ID. Whereas for some other elements you have to provide ID.

To makes an element programmable:

1. Select element in Designer.
2. Invoke properties for the element
3. Change ID property to a unique ID.
4. Refer to the element in the program using ID that you assigned in previous step.

Note: All IDs on a page must be unique. If you have a duplicate ID then at the end of ID Visual Basic adds a number to make it unique.

Enabling the default action
Many event of elements have default action. For example, when you click on a Hyperlink to invoke the specified page, the click event by default will take you to the required page. But if programmer writes code then programmer has to let the default action take place.

To let default action take place, return True from the event and returning False (default) doesn’t perform the default action.

Common Styles for HTML Elements
The style properties you use to set the physical appearance of an HTML element are named differently than their corresponding properties in Visual Basic.

The following table lists a few of the more frequently used styles and explains their use.

DHTML Style
Purpose
backgroundcolor Setting the background color of all elements except the Document object, which represents the body of the page. For the page itself, the property is called bgcolor.
border Setting a border around any element. All elements on an HTML page can have a border, including paragraphs of text.
color Setting the foreground color for all elements except the Document object, which represents the body of the page. For the page itself, the property is called fgcolor.
Font Setting the font for the element. A series of related properties (fontfamily, fontsize, fontstyle, etc.) are used to fine-tune the appearance of the font.
Margin Controlling the distance between the border of the element and the edge of the page. This property can be set to control all of the element's margins, or you can set the top, bottom, left, and right margins independently through a series of related properties.
padding Controlling the distance between the inner text of the element and its border. This property can be set to control the padding space on all sides of the elements, or you can set the padding of the top, bottom, left, and right sides independently through a series of related properties.
textdecoration Formatting text within an element. You use this property to make the text blink, or to display it with a strikethrough, underline, or overline.
Table 31.6: Common style of DHTML elements.

Creating sample DHTML application
We have seen a lot of DHMTL theory. Now let us put that to practice by developing a simple application. The application is creation of three web pages that contain the information regarding P.Srikanth (author). The application contains three pages - Home page, Experience page and Courses offered page. The first page is called as home page and contains links to other pages. Experience page displays the experience in various divisions. And last page is the most interesting of all. It takes the details of courses offered by Srikanth from a database and displays details based on the course selected by user.

I should admit, through this sample application, I can cover only a part of DHTML application’s ability. If you are interested in developing more application using DHTML applications, then I strongly suggest you read everything about Dynamic HTML in on-line documentation.

To create sample application:

1. Start a new project and select DHTML application as the type of the project.
2. Visual Basic creates a new project with two components – code module, modDHTML, and DHTML page, DHTMLPage1.

Double click on DHTMLPage1 to invoke designer and to load DHTML page into it.

Understanding TreeView pane and Detail pane
In DHTML page designer we have two portions. Left side pane is called as Treeview and right side pane is called as Detail pane.

Treeview Pane
TreeView pane displays hierarchical representation of the element within HTML page. Some of the element contains ID by default. And for elements that do not have id by default you can assign Id using Id property.

All elements in the treeview are children of the Body element and the Document object

Note: When you are working with DHTML page designer you get a different tool box containing element related to DHTML page.

The treeview provides three valuable shortcuts:

• When you select an item in the treeview, Visual Basic highlights the appropriate item in the detail panel and in the Properties window. This can help you determine at a glance the correspondence between elements in the treeview and on the page. Note that this works in reverse as well: When you select an element on the detail panel or in the Properties window, Visual Basic highlights the corresponding element in the treeview and scrolls the treeview accordingly.
• You can double-click an element in the treeview to open the Code Editor window for that element. The system selects the default event for the element.
• For ActiveX controls that do not have a visible user interface at run time (such as the common dialog control), the treeview is the only way you can select and manipulate these elements after adding them to your page.

Detail Pane

Presents a drawing surface on which you can create a new page or edit the contents of an existing page. You can add HTML elements to the page, position elements, and set properties that control their physical appearance.

Creating first HTML page
Now let us concentrate on creating first page. This page contains two hyperlinks to the other two pages of this application. This page also contains some text and an image.

Let us understand how to create all these elements.

1. Invoke properties by pressing F4 and select IDHTMLPageDesigner using dropdown listbox at the top and change Name and Id properties to homepage.
2. First go to the top of the page and type “Home Page of P.Srikanth” and change its format to heading1 using dropdown list box on the upper-left corner.
3. Place a HorizontalRule below the text so that it works as the divider.
4. Place two paras of text
5. Place first of two hyperlinks and change text on the hyperlink to “Experience”.
6. When the hyperlink element is selected press F4 to invoke properties and change the href property to skwebsite_experience.html. In hyperlink reference, skwebsite is the name of the application, and experience.html is the name of the html file that will be created for second HTML page.
7. Place second hyperlink and change text on the hyperlink to “Courses”
8. Change href property of second hyperlink to skwebsite_courses.html. When user clicks on this hyperlink, page containing course details is displayed.
9. Place an image on the right of title
10. Invoke properties of image element and change Image source property to the name of the file in which you have required image. In this example the complete path is C:/Books/VB60/programs/me.bmp.
With that designing part of first page is complete.

Note: In case you want to write code for any of the paras, change ID property and use the given id in your program to refer to the element.
Creating second page (Experience)
Second DHTML page contains the information regarding experience. This page is simplest of all three pages. Apply the following procedure to create and design second page.

1. Select Project -> Add DHTML page to add a new DHTML page to project.
Visual Basic displays a dialog box asking whether you want to save HTML of the page to be saved as part of project or it is to be saved in an external file. S
2. Leave it to default setting (saving as part of project) and click on Ok.
3. Invoke properties and change Id and Name properties of IDHTMLPageDesigner to Experience.
4. Enter text Placing the text on the page is done by straightaway getting to the required position and typing the text.

That’s all you have in experience page.

Now if you want to test how it works, run the project using F5. When VB prompts you to specify the first page, select homepage as the startup page. And accept homepage as the startup page. When you click on experience hyperlink, you should enter into experience page.
Creating Third page (courses)
This page has a lot of process. Because, this page takes the list of courses from database and displays the list in a list element to user. And when user selects a course from the list, it displays the details of the selected course. The total process is handled using ADO. The database is COURSE.MDB and the table is subjects.

This page contains a list element and a few textfields. List element is used to display the list of available subject (each subject is treated as a course). The list is populated using Load event of the page. And when user selects an option (course) in the list then we will display the details of the course. These details come from subjects table. For this we use OnClick event of the list element.

The following are the steps required to create third page.

1. Add a new DHTML page to project using Project -> Add DHTML Page
Select Save HTML with Visual Basic project options.
2. Invoke properties windows using F4 and change Name and Id properties of IDHTMLPageDesigner to courses.
3. Place elements
4. Change the Value property of all four textfields to empty string.
5. Change ReadOnly property of all four textfields to True. Because textfields are used to display the information only. User is not supposed to change the data.
6. For List element, by default one option is added. Invoke property page of list element and delete all the options in the list element using Delete button.
7. Change size to 5 lines.

As we are going to use ADO, load Microsoft ActiveX Data Objects 2.0 library using Project->References.

And finally write the following code.

General/Declarations

Dim rs As New ADODB.Recordset
Dim con As New ADODB.Connection

Private Sub DHTMLPage_Load()

Dim elmnt As HTMLOptionElement

' connect to database and get the details of the courses offered
con.Open "Provider=Microsoft.jet.oledb.3.51;data source=c:\books\vb60\programs\course.mdb"
rs.Open "select scode,sdesc from subjects", con

' load data into list box


Do Until rs.EOF ‘add one element at a time
Set elmnt = Document.createElement("OPTION")
With elmnt
.Text = rs("sdesc")
.Value = rs("Scode")
End With
List1.Options.Add elmnt
Set elmnt = Nothing
rs.MoveNext
Loop
rs.Close
Set rs = Nothing

End Sub

‘ Returns second value if first value is null
Public Function Nvl(av As Variant, rv As Variant) As Variant

If IsNull(av) Then
nvl = rv
Else
nvl = v
End If

End Function

Private Function List1_onclick() As Boolean
' get the details of the selected subject
Dim scode As String
Dim rs As New ADODB.Recordset

scode = List1.Value
qry = "select version, duration, prerequsite,coursefee from subjects where scode = '" & scode & "'"
rs.Open qry, con

txtduration.Value = nvl(rs("duration"), "")
txtprerequisite.Value = nvl(rs("prerequsite"), "")
txtversion.Value = nvl(rs("version"), "")
txtcoursefee.Value = nvl(rs("coursefee"), "")
rs.Close
Set rs = Nothing

End Function
Listing 31.1: Code for third DHTML page.
Test run
Run the application and check whether all features are working. Take the following steps.

1. Run the application using F5. Visual Basic displays home page.
2. Click on Experience hyperlink (it will be underlined)
Internet Explorer displays Experience page.
3. Click on Back icon in Internet Explorer.
4. Click on Courses hyperlink.
5. Select one of the subjects listed in the list element. The details of the selected page are displayed in text box elements.
6. Quit the application by terminating Internet Explorer.

ActiveX Control Related Objects and Property pages

Objects related to ActiveX control
The following are the objects that are involved in the process of creating an ActiveX control.

• UserControl object
• AmbientProperties object
• Extender object
• Constituent control objects

UserControl Object
This is the object used to create a single ActiveX control. Every ActiveX control is consisting of one UserControl object and a set of constituent controls. Just like a From, a UserControl object also has a designer, which allows you to place intrinsic control on the UserControl object.

You have properties, methods, and events for UserControl object. They are discussed later in this chapter.

AmbientProperties Object
This is used to get information from container of ActiveX control. The properties of AmbientProperties object are the ambient properties of the control. These properties are read-only. These properties allow you to determine how you adapt your control according to the capabilities of the container.

Not all ambient properties are standard. Some of them are specific to only a particular container.

AmbientChanged event occurs whenever any of the ambient properties (properties in container) changes. This enables programmer to change control according to the container.

AmbientProperties object is not available in Initialize event.

The following is the list of standard ambient properties.


Property Meaning Default value if property is not supported by Container.
BackColor Color that contains the suggested interior color of the contained control. &H80000005
DisplayAsDefault Returns True if the control is the default control otherwise false. false
DisplayName The name that the control assigned by developer. "".
Font Contains the suggested font information of the contained control. MS Sans Serif 8.
ForeColor Suggested foreground color of the contained control. 0x80000008: the system color for window text.
LocaleID Specifies the language and country of the user System locale ID.
Palette Picture object whose palette specifies the suggested palette for the contained control.
RightToLeft Indicates the text display direction and control visual appearance on a bi-directional system. False.
ScaleUnits The name of the coordinate units being used by the container. ""
TextAlign Specifies how text is to be aligned. 0 - General Align.
UserMode Specifies if the environment is in design mode or end user mode True.
Table 28.1: Ambient properties of a UserControl.

The following code changes the background color of the text box to the background color of the container whenever background color of the container is changed.

Private Sub UserControl_AmbientChanged(PropertyName As String)
If PropertyName = "BackColor" Then
txtNumber.BackColor = Ambient.BackColor
End If
End Sub
Listing 28.1: Changing BackColor property of text box to BackColor property of user Control.

AmbientChanged event of the UserControl object occurs whenever any of the ambient properties is changed. Ambient object provides access to values of ambient properties.

PropertyName parameter of the AmbientChanged event contains the name of the properties that has been changed in the container.

Extender Object
This object holds properties of the control that are actually controlled by the container of the control rather than by the control itself

The properties, methods, and events of Extender object are provided by the container. So there is no guarantee that all these are supported in all platforms.

You can access extender properties using Extender property of UserControl.

The following is the list of extender properties.

Property Meaning
Name Contains the user-defined name of the control.
Visible Specifies if the control is visible or not.
Parent Represents the container of the control, such as a form in Visual Basic.
Cancel Indicates that the control is the Cancel button for the container.
Default Indicates that the control is the default button for the container.
Container Represents the visual container of the control.
DragIcon Picture that specifies the icon to use when the control is dragged.
DragMode Specifies if the control will automatically drag, or if the user of the control must call the Drag method.
Enabled Specifies if the control is enabled. This is not present unless the control also has an Enabled property.
Height Specifies the height of the control in the container’s scale units.
HelpContextID Specifies the context ID to use when F1 key is pressed being in the control.
Index Specifies the position in a control array that this instance of the control occupies.
Left Specifies the position of the left edge of the control to the left edge of the container, specified in the container’s scale units.
TabIndex Specifies the position of the control in the tab order of the controls in the container.
TabStop Specifies if Tab will stop on the control.
Tag Contains a user-defined value.
ToolTipText Contains the text to be displayed when the cursor stays on the control for more than a second.
Top Specifies the position of the top edge of the control to the top edge of the container, specified in the container’s scale units.
WhatThisHelpID Specifies the context ID to use when the What’s This pop-up is used on the control.
Width Specifies the width of the control in the container’s scale units.

Table 28.2: Extender properties.

The following are the methods provided by Extender object.

• Drag
• Move
• SetFocus
• ShowWhatsThis
• Zorder

The following are the events provided by Extender object

• DragOver
• DragDrop
• GotFocus
• LostFocus

Properties of UserControl object
The following are the properties that are specific to user control object.

Property Meaning
AccessKey Returns or sets a string that contains the keys that will act as the access keys (or hot keys) for the control.
Ambient Returns an AmbientProperties object holding the ambient properties of the container.
ContainedControls Returns a collection of the controls that were added to the control.
EditAtDesignTime Returns or sets a value determining if a control can become active during the developer design time
EventsFrozen If it is set to true, then events of usercontrol are ignored by container
Extender Returns the Extender object for this control that holds the properties of the control that are kept track of by the container.
ParentControls Returns a collection containing other controls in parent container.
PropertyPages Is a string array containing the names of the property pages in the project that are associated with this control.
ContainerHwnd Returns the window handle (hWnd) of a UserControl’s container.
Parent Returns a reference to the container object on which the control is sited.
CanGetFocus Determines whether focus should move to this control or not.
Table 28.3: Properties of User Control.

UserControl Events
The following are the various events of usercontrol object and their description.

Event When does it occur?
AccessKeyPress Occurs when user presses one of the accesskeys for the control. It passes the key that is pressed by user.
AmbientChanged Occurs when an ambient property’s value changes. This passes the name of the property as the only parameter
EnterFocus This event occurs whenever a constituent control receives focus.
ExitFocus Occurs whenever focus leaves the control.
GotFocus Occurs in the constituent control when focus enters it. The EnterFocus event is raised before the GotFocus event.
Hide Occurs when the object’s Visible property changes to False.
InitProperties Occurs when a new instance of an object is created.
This allows programmer to initialize new control when it is placed on the form.
ReadProperties Occurs when loading an old instance of an object that has a saved state. This is used to read the values of the properties. Used for property persistence.
Show Occurs when the object’s Visible property changes
WriteProperties Occurs when an instance of an object is to be saved. This is used to save the values of properties.
AsyncReadProgress Occurs when more data is available as a result of an AsyncRead method.
AsyncReadComplete Occurs when the container has completed an asynchronous read request.
HitTest Occurs when the user moves the mouse over a UserControl object. Only occurs when the Windowless property of the UserControl is set to True and the BackStyle property is set to Transparent.
Initialize Occurs when an application creates an instance of a user control.
Terminate Occurs when the instance of the control is about to be destroyed.
Table 28.4: Events of user control object.

Property Pages
Before we started creating ActiveX Control, we had already used a few ActiveX controls. All of them have Property pages that allow you to change properties of the control. Now let us create two property pages for our Number control. First one contains a text box to take number from user and changes Value property, Second one contains two text boxes Maximum Length and Minimum Length properties. A developer using Number ActiveX Control can invoke property pages and change properties.

The best way of creating a property page is using Property Page Wizard. Now having decided how many property pages to have and what to have in each of these property pages, we are ready to use Property Page Wizard.

To invoke property page wizard:

1. First make Property Page Wizard available to Visual Basic project by selecting Add-Ins menu and then select Add-In Manager option.
2. In Add-In Manager dialog box double click on VB 6 Property Page Wizard. You should see Loaded message in Load Behavior column.
3. Click on Ok.
4. Then select Add-Ins menu and Property Page Wizard. You will see a series of windows prompting for required information.

The following are the steps to create two property pages and to place Value property in first property page and MinLength and MaxLength properties on the second property page.

1. When Property Page Wizard is displayed, it first displays Introduction screen.
2. Click on Next button to move to select the Property Pages page.
3. Click on Add button.
4. Enter ppValue as the name of the page.
5. Click on Add button again and enter ppLength as the name of second property page.
6. Click on Next button to move to Add Properties page.
7. Available Properties list contains the list of available properties.
8. Make sure ppValue tab is selected in Available Property Pages.
9. Select Value property and click on > to move the property to ppValue property.
10. In the same way select ppLength tab and click on >> to place MinLength and MaxLength properties on ppLength property page.
11. Click on Finish button to start building property pages.
12. Invoke ppValue property page and change Caption property to “Value”
13. Invoke ppLength property page and change Caption property to “Length”.

Property Page Wizard has created two property pages ( ppValue and ppLength)

The code that Property Page Wizard has written for ppValue property page is as follows.

Private Sub txtValue_Change()
Changed = True
End Sub

Private Sub PropertyPage_ApplyChanges()
SelectedControls(0).Value = txtValue.Text
End Sub

Private Sub PropertyPage_SelectionChanged()
txtValue.Text = SelectedControls(0).Value
End Sub
Listing 28.1: Code written by property page wizard.
Property page containing text boxes for MaxLength and MinLength properties.

Let us understand the code written by Property Page Wizard. But before we try to do that, we have to understand properties, events of property page.

Changed Property
When this property is set to true, Apply button in the property page will be enabled. In addition to that, setting it to true calls ApplyChanges event whenever you click on Ok button or move to a different property page.

SelectedControls property
This is a collection that contains the controls that are currently selected on the form. SelectedControls (0) references the control that is currently selected. This is used to get the values for properties of the currently selected instance of the ActiveX control for which property page belongs.

The code written by Property Page Wizard, uses SelectedControls (0) (first selected control) only. If you want to handle all selected controls, you have to modify the code written by wizard.

SelectionChanged Event
This is fired whenever an instance of the ActiveX control is selected for editing properties through property pages. This event is used to get the values of the properties from selected control (SelectedControls (0)) and assign those values to controls in property pages to enable user to change them.

ApplyChanges Event
This event is fired whenever user is selecting Apply button, selecting Ok button, closing page or shifting to a different page.

The event occurs only when Changed property is set to true,

Now, if you look at the code written by Property Page Wizard, you should be able to understand the code. The code uses all the properties and events that we have discussed. The following is the summary of the code.

• Sets Changed property to True, whenever user changes values in txtValue text box, which is meant for Value property.
• SelectionChanged event is used to get the value of Value property of the currently selected control (SelectedControls(0)) and put that value in txtValue textbox.
• ApplyChanges event is used to write value entered in txtValue textbox into Value property of the currently selected control (SelectedControls (0)).

Code for ppLength property page
The code written by Property Page Wizard for ppLength property page is as follows.

Private Sub txtMaxLength_Change()
Changed = True
End Sub

Private Sub txtMinLength_Change()
Changed = True
End Sub

Private Sub PropertyPage_ApplyChanges()
SelectedControls(0).MaxLength = txtMaxLength.Text
SelectedControls(0).MinLength = txtMinLength.Text
End Sub

Private Sub PropertyPage_SelectionChanged()
txtMaxLength.Text = SelectedControls(0).MaxLength
txtMinLength.Text = SelectedControls(0).MinLength
End Sub
Listing 28.2: Code for ppLength property page.

This code needs no explanation, as it doesn’t differ from the previous code.

Using property pages at the time of designing
Let us see how a developer who is using Number ActiveX control can use Property Pages of Number control. Here are the steps to test it:

1. Open testing project (tstNumctrl) project
2. Invoke Form designer
3. Select Number1 control and click right button
4. You should see a new option in popup menu – Properties.
5. Select Properties option to invoke Property pages.
6. Property pages window is displayed with two tabs at the top, one for Value property page and another for Length property page.
7. In Value property page, you will see the value you assigned to Value property of the selected control. the value assigned to Value property is 1000. So initially you will see 1000.
8. Change the value to 2000 in property page. It will enable Apply button of the property page. At this stage, your property Page should be identical
9. Click on Apply to make Value property of Number1 control. Click on Length tab to move to Length property page.

Note: Pressing F4 on the control will invoke Properties Pallette. And selecting Popup Menu -> Properties option will invoke Property pages. This is same for all ActiveX controls.

Creating ActiveX Control

We have so far seen how to create an ActiveX DLL and ActiveX EXE. Those two are called as ActiveX code components. We will now discuss about how to create ActiveX Control.
ActiveX Controls were previously known as OLE controls. The fundamental difference between those OLE controls and ActiveX controls is the support for Internet. ActiveX control can be placed on web pages to make web pages more interactive. Something like how you place a Java Applet in a web page.

In this chapter, first we will create a simple ActiveX control to get an overall idea about how to create ActiveX controls. In the next chapter we will get into more details of ActiveX control.

Creating a Number control
Number ActiveX control is a modified version of Textbox. Unlike a textbox, Number control can accept only digits and backspace. You can use this control instead of a textbox whenever you want to accept a number from user. As user cannot enter anything other than digits, there is no scope for making errors. This control also contains a few user-defined properties, methods and events (see table 27.1)

Properties, Methods and Events of Number control are as follows:

Type Name Value
Property Value Sets/returns the value in number control.
MaxLength Sets/ returns the maximum number of digits that can be entered.
MinLength Sets/returns the minimum number of digits to be entered.
Method Clear Clears the content of the control.
Event InvalidChar Fired when an invalid character is entered. Passes invalid character as the parameter.
LengthError Fired when minimum length is not entered by user.
Table 27.1 : Members of ActiveX controls.

The following are the major steps in creating an ActiveX control:

• Creating ActiveX control project
• Placing intrinsic controls (standard controls) on UserControl and changing their properties
• Writing code for events
• Changing properties of the project and creating .OCX file.

Let us follow the steps mentioned above to create Number control.

Creating an ActiveX control Project
Create a new project of type ActiveX control to create Number control as follows:

1. Select File->New Project and choose ActiveX Control as the project type.
A new project is created with a single UserControl. A UserControl object is similar to a form. It can contain intrinsic controls such as textbox, command button etc.
Placing control and changing properties
1. Now invoke UserControl designer by double clicking on UserControl1 in Project Explorer.
2. Place a textbox at the upper left corner of the UserControl.
3. Resize UserControl to the size of textbox.
When control is placed in client application, client application can change the size of the usercontrol according to its requirement.
Whenever user control’s size is changed the size of textbox should also be changed. This is done using Resize event of usercontrol (see listing 27.1).
4. Change the following properties of Usercontrol and Textbox.

Object Property Value
UserControl Name Number
Text1 Name Txtnumber
Text “”(Null)

At the end of this step, UserControl designer
Writing Code
We will write only a part of the code now. Now concentrate on important events such as KeyPress event for textbox, Resize event of UserControl.

Private Sub txtNumber_KeyPress(KeyAscii As Integer)
' ignore nondigits
If KeyAscii < 48 Or KeyAscii > 57 Then
' if key is not tab key
If KeyAscii <> 8 Then
KeyAscii = 0 'ignore
End If
End If
End Sub

Private Sub UserControl_Resize ()

txtNumber.Move 0, 0, UserControl.Width, UserControl.Height

End Sub
Listing 27.1:Code for user control.

UserControl object contains Width and Height properties that contain the width and height of the UserControl object. So change the size of textbox to the size of UserControl object using Width and Height properties of UserControl.

Number control needs a few properties. So let us add required properties to ActiveX control. To create properties we can use ActiveX Control Interface Wizard. But for now let us do it manually. In the next chapter we will see how to use ActiveX Control Interface Wizard.

To create Value property:

1. Invoke code window and then Select Tools -> Add Procedure.
2. Enter Value as the name of the property and select Property radio button in Type group.
3. Click on Ok.

Two property procedures are automatically created. One is Property Let and another one is Property Get. Write the following code. The code is used to map Text property of textbox to value property of number control.

Public Property Get Value() As Variant
Value = txtNumber.Text
End Property

Public Property Let Value(ByVal vNewValue As Variant)
txtNumber.Text = vNewValue
End Property
Listing 27.2: Code for Value property procedure

We will add remaining functionality to the control later. For the time being, let us create .OCX file and use it in a client application.

Creating .OCX file

Save project and give the following names.

Project Numberctrl.vbp
UserControl Number.ctl

Change required properties of the project using project properties window as follows

Project Name NumberCtrl
Project Description Number Control By P.Srikanth.

To create .OCX file:

1. Select File-> Make Numberctrl.ocx
2. Specify the directory in which .ocx file is to be created.
3. Click on Ok.
Visual Basic creates .ocx file and also registers ActiveX control in system registry.

That's all you have to do to create a simple ActiveX control. Remember we still have to add some more features to our ActiveX control. In spite of that, let us use it in a client application to get an idea regarding how it works in client application.

Creating Testing Project
We create a testing project to test ActiveX control. The project contains nothing but a single form and one instance of Number control. Follow the steps given below.

1. Select File->New Project and select Standard Exe as the project type.
2. Select Project -> Components and select Number Control By P.Srikanth.
Tool box contains a new icon representing Number control. If you take MousePointer on to it, it displays Number as the tooltip.
3. Create an instance of Number control just like how you create an instance of standard control (by selecting the icon and then dragging on to form).
4. Also place a command button to get the number that we have entered into it through value property.
5. Change the following properties of command button and the form.

Object Property Value
Form Name txtNumctrl
Caption Testing Number Control
Command1 Name Cmddispvalue
Caption &Display Value

Write the following code.

Private Sub cmddispvalue_Click()

MsgBox Number1.Value, , "Value"

End Sub
Listing 27.3: Code for Display Value button.

An Icon at the bottom representing Number control loaded into project.

Running test project

1. Run the project by pressing F5.
2. Enter a few digits into Number control. It will receive them. Now enter a few alphabets. It will ignore alphabets. Try pressing backspace. It will erase previously entered digit.
3. Click on Display Value command button. A message box will be displayed with the value entered into the Number control.
4. Close testing project and open NumberCtrl (ActiveX control ) project. Now let us enhance our control by adding remaining properties, methods and events.

Enhancing Number Control
The only user-defined property that we have (Value) is mapped to Text property of txtNumber textbox. Now we want to limit the number of digits entered into text box. Text box control also contains MaxLength property. So let us create MaxLength property for UserControl and map it to MaxLength property of textbox.

To create MaxLength property:

1. Get into code window and then select Tools -> Add Procedure.
2. Enter MaxLength as the name and select Property radio button in Type group.
3. Then change property procedures as shown in listing 27.4.
Testing project when displaying value entered into Number control.

Public Property Get MaxLength() As Variant
MaxLength = txtNumber.MaxLength
End Property

Public Property Let MaxLength(ByVal vNewValue As Variant)
txtNumber.MaxLength = vNewValue
End Property
Listing 27.4: Code for MaxLength property.
Note: There is no MinLength property for text box. So creating MinLength property involves a bit more work. And we will do it later.

To create Clear method:

1. Select Tools -> Add Procedure
2. Enter Clear as the name and select Sub as type.
3. Write the following code.

Public Sub Clear ()
txtNumber.Text = ""
End Sub

To create InvalidChar event:

1. Select Tools -> Add Procedure
2. Enter InvalidChar as the name and select Event as the type.
Visual Basic places a single statement in general/declaration as follows.

Public Event InvalidChar()

Add an argument to event of integer type as shown below. This is to pass the Ascii code of the invalid character enter by the user.

Public Event InvalidChar(ch As Integer)

Modifying KeyPress event procedure of Text box
KeyPress event is to be modified as it has to raise InvalidChar event whenever it encounters invalid character. So modified code is shown in listing.

Private Sub txtNumber_KeyPress(KeyAscii As Integer)
' ignore nondigits
If KeyAscii < 48 Or KeyAscii > 57 Then
' if key is not tab key
If KeyAscii <> 8 Then
KeyAscii = 0 'ignore
RaiseEvent InvalidChar(KeyAscii)
End If
End If
End Sub
Listing 27.6: Code for KeyPress event of the textbox.

3. Now save the project and recreate .OCX file.
4. Close NumberCtrl project and open tstNumctrl project.
At the time of opening Visual Basic detects that Number control was modified and a new version was created. So it displays a message box informing that the control will be upgraded to new one.

Click on Ok to use upgraded control.

To test InvalidChar event and clear method, add a label control to display the most recently entered invalid characters and a command button to clear the value from number control.

Visual Basic informing user that ActiveX control will be upgraded to next release.

Change properties of all the controls that are added.

Control Property Value
Command button Name CmdClear
Caption &Clear
Label Name Lblchar
Caption “ “
BorderStyle 1-fixed Single
BackColor White (&H8000000E&)
Label Caption Recent Invalid Character


Write the following code for click event of clear button and InvalidChar event of Number1.

Private Sub cmdClear_Click()
Number1.Clear
Number1.SetFocus
End Sub

Private Sub Number1_InvalidChar(ch As Integer)
lblchar.Caption = Chr$(ch)
End Sub
Listing 27.7: Code in testing form.
Run the project and enter 1583 followd by J. As J is not a valid character for Number control, Number control fires InvalidChar event and passes the Ascii code of the character as the parameter. We used InvalidChar event of Number1 control and placed the character form of the Ascii code into label.


Testing MaxLength Property
Now let us test maxlength property of the control by following the steps given below.

1. Invoke properties window of Number1 control and change MaxLength property to 10.
2 .Run the testing project and see whether you can enter more than 10 digits.

Shocked…

Oh, it does not work. You are able to enter as many digits as you want. But if we set MaxLength property to 10, it indirectly set MaxLength property of text box to 10. Does it mean MaxLength property of text box is not working. I suggest before you come to any conclusion, try the following with Value property.

1. Invoke properties window of Number1 control and change Value property to 100.
2. When you dismiss Properties window, you see 100 in the control. That’s OK.
3. Run the testing project and see what you have in Number control.

Shocked… again.

Don’t worry. We will see later what is happening. For now all that I can say is, it is a very important part of ActiveX controls. We will understand more about it later in this chapter. For the time being it is a mystery.

Adding MinLength property and LengthError event
MinLength property specifies the minimum number of digits to be entered by user. It is set to 0 by default. If user doesn't enter given number of digits then LengthError event is fired and focus remains in the control.

Open NumberCtrl project. If it is not already open and take the following steps:

To add MinLength property:

1. Get into code window of UserControl.
2. Select Tools ->Add Procedure and enter MinLength as name.
3. Select Property radio button from Type group.
4. Click on ok

To add LengthError Event

1. Select Tools-> Add Procedure option.
2. Enter LengthError as name and select Event option in Type group.

Visual Basic places a single statement in general/declarations as follows.

Public Event LengthError()

Property Let and Property Get procedures are created for MinLength Property name is part of the interface of the control. But MinLength is not a variable. It can only interact but cannot store the value. So declare a variable vMinLength and store minimum length in that variable. When it comes to accessing minimum length, we use MinLength property but the value is actually stored in vMinLenth variable. Here are the changes to be made to the existing code.

General / Declarations

Private vMinLength As Integer

Public Property Get MinLength() As Variant
MinLength = vMinLength
End Property

Public Property Let MinLength(ByVal vNewValue As Variant)
vMinLength = vNewValue

End Property
Listing 27.7: Code for MinLength property

We use LostFocus event of txtNumber text box to check whether user has entered the required number of digits. Here is the code for LostFocus event.


Private Sub txtNumber_LostFocus()
' check whether MinLength number of digits are given
If Len(txtNumber.Text) < MinLength Then
RaiseEvent LengthError
txtNumber.SetFocus
End If
End Sub
Listing 27.8: Checking for Minimum Number of digits.

Property Persistency
Recollect the problem with MaxLength and Value properties of Number control. When we set Value property to 100 in design mode, that value was not available at runtime. The same was the problem with MaxLength. And, in fact, that will be the problem with all properties of the ActiveX control. Before we try to solve the problem, let us try to understand the reason for the problem.

ActiveX controls always run, when you place an ActiveX control on a form, even in design mode the ActiveX control runs. Actually an instance of ActiveX control is placed on the form and it is in run mode even when Form is in design mode.

When you place an ActiveX control on the form, an instance of ActiveX control is created and placed on the form. When you are moving from design mode to run mode by running Visual Basic project, the instance of ActiveX control that was placed in design mode is destroyed and a new instance of the ActiveX control is created at runtime. That means all the property settings that you have in design mode are gone as the instance itself is destroyed. When a new instance is created at runtime, it has all the properties reset to default values.

That means the property settings do not have any persistency. Properties lose their values when they move from design mode to run mode. And also when you save and reopen the project and so on.

We can achieve property persistence by storing the property setting before the instance is destroyed and retrieve the setting when a new instance is created. This is what is called as property persistence. So we achieved property persistence by writing the values of properties to disk and then reading them back when they are required.

WriteProperties Event
This event of UserControl object occurs whenever a controls property settings are to be saved. For example, when you are moving from design mode to run mode, as the settings of properties are to be saved, WriteProperties event occurs.

WriteProperties event is used to:

Write setting of properties into Propety Bag (PropBag) object using WriteProperty Method.

WriteProperties event doesn’t occurs in the following cases:

When Visual Basic believes no property values have changed.
When switching from run mode to design mode.

ReadProperties Event
This event occurs whenever the control is created except for the very first time. ReadProperties event is used to read the setting of properties that were written using WriteProperties event. The following are the steps to be taken in this event:

Read the values of properties from Property Bag (PropBag) object.

InitProperties Event
This event occurs when control is created for the very first time. For example, when you drag and drop a control on the form.

Use this event to set initial values to properties and perform any other operations that you want to perform only for once in the life time of the control.

PropertyChanged Method
PropetyChanged method is used to mark a property as changed. Only those properties that are marked as changed will be written by Visual Basic into property bag (PropBag) object during WriteProperties event.

This method takes the name of the property that has been changed as the parameter and notifies Visual Basic that the property has changed.

The following is the syntax of PropertyChanged method.

PropertyChanged propertyname

This method is used for the following reasons:

• To notify Visual Basic which properties need to be written to PropBag when project is saved or when switching from design mode to run mode.
• To update the value of the property when the property is changed through property page in design mode.
• To update database when a data bound property is changed


Providing Object Persistency to Number control
Now let us put what we have understood to practice. As you know we have not taken care of property persistence in Number control. Now let us add code for the above mentioned event to provide object persistence. Actually ActiveX Control Interface Wizard automatically writes code for these events. We will use it in the next chapter, but for the time being let us add the following code for Number control normally.

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
Value = PropBag.ReadProperty("Value", 0)
MinLength = PropBag.ReadProperty("MinLength", 0)
MaxLength = PropBag.ReadProperty("MaxLength", 0)
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
PropBag.WriteProperty "Value", Value, 0
PropBag.WriteProperty "MinLength", MinLength, 0
PropBag.WriteProperty "MaxLength", MaxLength, 0
End Sub
Listing 27.9: Code to write and read properties to and from property bag.

Test run
1. Open the text project and do the following.
Now invoke properties window and change Value property to 100 and MaxLength property to 10.
2. Run the project using F5.
You should see value 100 in Number control at runtime. And you should not be able to enter more than 10 digits. That means whatever settings you have at design mode those settings are available even in run mode.
The following is the sequence of events that made the property persistence possible:

• When project is switching from design mode to run mode, WriteProperties event occurs.
• WriteProperty method of PropBag object writes the current values of properties into PropBag object.
• Then control's instance in design mode is removed.
• Project has entered into run mode.
• A new instance of control is created and placed on the form.
• ReadProperties event occurs.
• ReadProperty method of PropBag object is used to read the values of properties from PropBag and assign those values to properties.
Now let us understand what are the events that occur in various scenarios related to property persistence.

Scenario #1, creating a new control
Whenever you create a new instance of an ActiveX control by placing the control on the form, the following event of ActiveX control occur in the given order.

• Initialize • InitProperties • Resize • Paint
Scenario #2, Switching from Design mode to Run mode
The following events of ActiveX control occurs whenever you switch from design mode to run mode in Visual Basic IDE.

• WriteProperties • Terminate • Initialize
• ReadProperties • Resize • Paint

Scenario #3, Switching from Run mode to design mode
The following events of ActiveX control occurs whenever you switch from run mode to design mode in Visual Basic IDE.

• Terminate • Initialize • ReadProperties
• Resize • Paint

Scenario #4, saving the project
The following events occur when you save project in VB IDE.

• WriteProperties • Terminate

Scenario #5, Project is opened into Visual Basic IDE
The following events occur when you open project in VB IDE

• Initialize • ReadProperties • Resize
• Paint • WriteProperties

Note: WriteProperties event occurs when you open the project because Visual Basic has to write the properties read using ReadProperties to in-memory copy of .frm file.

Properties persistence is very important part of ActiveX control. You need to maintain values for properties across control instance.

ActiveX EXE

In this chapter let us create an ActiveX EXE, which is also called as out-of-process server. One of the major advantages of the out-of-process server is, it can be run on a different machine from client machine and thus enabling you to develop Application Server in 3-tier client/server architecture. ActiveX Exe could also be run as a separate program. It is suitable for cases where you need to create an application that may be invoked as a standalone application or as a server. When it is invoked as a standalone application then users can interact with the application.
To get a feel of out-of-process server and how to use it in client application, let us create an out-of-process server that uses the Time class (created in the previous chapter), and testing application.
The ActiveX EXE that we are about to create contains the following features.

• It has a single class Time (taken as it is from previous chapter).
• A form that is displayed only when ActiveX EXE is invoked as a standalone application. The form is hidden when ActiveX EXE is invoked from a client application (used as a server).
• The form of ActiveX EXE is used to display running digital clock using Time class of the ActiveX EXE
• Client application as usual uses an object of Time class to invoke methods such as GetTime, SetTime etc.
• The startup object of ActiveX EXE is Sub Main, which is a procedure in code module. Main procedure determines whether form in server is to be displayed or not depending upon whether server is invoked as standalone application or invoked by client application.

Creating an ActiveX EXE
Let us start creating ActiveX EXE and its components like code module and form.

1. Create a new project using File -> New Project and select ActiveX EXE as project type.
2. Visual Basic creates a project with just one class module named Class1.
3. Invoke Project Properties and click on right button.
4. Select Add -> Class Module from popup menu.
5. In Add Class Module dialog select Existing tab and select TIME.CLS.
6. Click right button on Class1 and select Remove Class1 from popup menu. When you are prompted to save it, select No.
7. At this stage, we have only one class module (TIME) in our project.
8. Add a form using Project -> Add Form and select a simple form from Add Form dialog box.
9. Add a code module using Project -> Add Module and click on Open in Add Module dialog box.
10. At this stage, the project explorer .

11. Change the following properties of the project.

Project name AEXETIMESERVER
Project Description Time class in Out-of-process server by P.Srikanth.
Startup object Sub Main

12. Create a procedure with the name Main in code module and write the following code.

Public Sub Main()
If App.StartMode = vbSModeStandalone Then
frmTime.Show
End If
End Sub
Listing 26.1: Code for Main procedure of code module.

App object is one of the system objects. If StartMode property contains vbSmodeStandalone, it means ActiveX EXE is run as standalone program. The other option is vbSmodeAutomation.

13. Invoke Form designer and place a label and a timer control on the form.
14. Change the following properties of the form and controls.

Object Property Value
Form Name FrmTime
Caption ActiveX EXE Server
Label1 Name Lbltime
Caption 00:00:00
Autosize True
Fontsize 14
Borderstyle 1-Fixed Single
Timer1 Interval 1000


15. Write the following code for frmTime form.

General/Declarations
Dim t As New Time
Private Sub Form_Load()
Timer1_Timer
End Sub

Private Sub Timer1_Timer()
t.SetToCurrent
lblTime.Caption = t.GetTime
End Sub
Listing 26.2: Code in Form.

16. Save the project and its component under the following names (if you want you may give different names).
Project aexetimerserver.vbp
Form frmtime.frm
Module aexemodule.bas
Class Module aexetime.cls

Time class is taken from previous project. If we make any changes to time class and save them, the changes will be saved under Time.cls and this might effect the previous project (timerserer). So it is better we have a separate copy of Time class for the AEXETIMERSERER project.

To save time.cls under a different name:

1. Select Time class in project explorer and click on right mouse button.
2. Select Save Time.Cls As option from popup menu and enter AEXETIME as the name of the new file.
3. Time class is now stored under a new name - AEXETIME.CLS. It doesn’t effect TIME.CLS and previous project continues to use TIME.CLS.

Creating .EXE file

1. Select File menu and choose Make aexetimeserver.exe option.
2. Visual Basic creates aexetimeserver.exe in the specified directory and also registers it in system registry.
Running ActiveX Server as Standalone application

Let us run aexetimerserver.exe as a standalone application. In this case it should display frmTime, which contains running digital clock.

To run ActiveX exe server as standalone application:

1. Click on Start button on Taskbar
2. Select Run option from the start menu
3. Click on Browse button in Run window and select aexetimerserver.exe . (Your folder name may be different)
Running aexetimerserver.exe using Start->Run.

4. After selecting the file click on Ok to run the program.
5. A small window (frmTime) is displayed with running digital clock


Running client application
We use the same client program that we used for ActiveX DLL. But client application should have a reference to ActiveX EXE. So open client application (timetest.vbp) and follow the steps given below.

To create a reference to ActiveX EXE:

1. Select Project -> References
2. Uncheck Time class by P.Srikanth
3. Check Time class in Out-of-process server by P.Srikanth.
4. Click on Ok

Run client application by pressing F5. You should see the same screen as you have seen in the previous chapter and it also functions in the same manner. But one important difference is that now, Time class is in a separate process. And it could also be running on a separate machine altogether. If it runs on a different machine then you are accessing an object that is on a different machine and access to such object is handled by DCOM (distributed Component Object Model).

Another important point to be noted here is, when you are invoking ActiveX EXE from client application, frmTime is not displayed. But the application is loaded and Time class is provided to client application. Remember, we have checked for the startup mode and displyed frmTime form only when startup mode is standalone.

That is all you need to do to create an ActiveX EXE. The basic advantatge with ActiveX EXE is- it can run as a separate process. That could as well be on a seperate machine. So think of ActiveX EXE if they are the matters of concern. If you are looking for a collection of classes and no need to run them separately then implement the collection of classes as an ActiveX DLL. ActiveX DLL (in-process server) is much faster than ActiveX EXE (out-of-process server).

Instancing Property of Classes
The value of the Instancing property determines whether your class is private — that is, for use only within your component — or available for other applications.

As its name suggests, the Instancing property also determines how other applications create instances of the class. The property values have the following meanings.

Option Meaning
Private Means that other applications aren’t allowed access to type library information about the class, and cannot create instances of it. Private objects are only for use within your component.
PublicNotCreatable Means that other applications can use objects of this class only if your component creates the objects first. Other applications cannot use the CreateObject function or the New operator to create objects from the class.
MultiUse Allows other applications to create objects from the class. One instance of your component can provide any number of objects created in this fashion. An out-of-process component can supply multiple objects to multiple clients; an in-process component can supply multiple objects to the client and to any other components in its process.
GlobalMultiUse Is like MultiUse, with one addition: properties and methods of the class can be invoked as if they were simply global functions. It’s not necessary to explicitly create an instance of the class first, because one will automatically be created.
SingleUse Allows other applications to create objects from the class, but every object of this class that a client creates starts a new instance of your component. Not allowed in ActiveX DLL projects.
GlobalSingleUse Is like SingleUse, except that properties and methods of the class can be invoked as if they were simply global functions. Not allowed in ActiveX DLL projects.
Table 26.1: Options of Instancing property.

Class Modules and Project Types
The value of the Instancing property is restricted in certain project types. Allowed values are shown in the following table:

Instancing Value
ActiveX EXE ActiveX DLL
Private Yes Yes
PublicNotCreatable Yes Yes
MultiUse Yes Yes
GlobalMultiUse Yes Yes
SingleUse Yes
GlobalSingleUse Yes

Registration of ActiveX Components
Every ActiveX component is to be registered in Windows registry. Unless a component is registered, system has no way to get the required information about these components.

Visual Basic creates an entry in the registry for each component as and when component is compiled. But that is the case only with the system in which component is created. But as you can guess, you need to develop component only for once and then install it in other machines. When a component is loaded into another machine (different from development machine) you cannot access the components unless components are registered in windows system registry.

When you buy components, they come with an installation program, which takes care of installing and registering components in client’s machine.

Buf if you ever want to register an ActiveX component ,be it DLL or EXE or OCX, you can use REGSVR32 program available in windows\system folder.

To get help regarding REGSVR32.EXE, just enter REGSVR32 at system prompt after getting into WINDOWS\SYSTEM directory.

Syntax of RegSvr32, displayed by RegSvr32 when run without any parameters.

To register TIMERSERVER.DLL, enter:

1. Copy timerserver.dll into required directory. Let us assume the name of the directory is servers, which is in root directory of C drive.
2. Enter into windows\system directory. because regsvr32.exe resides in windows\system directory. and normally windows\system directory is not in the path. Otherwise you can invoke it from anywhere.
3. Invoke regsvr32 to register timerserver.dll as follows:
Regsvr32 c:\servers\timeserver.dll

4. If it is successful, you will see a window

Message displayed by RegSvr32 after a successful registration.

To Unregister TimerServer.dll:

If you ever decide to unregister timeserver.dll from registry, you can use regsvr32.exe with /u option to unregister the component.

Enter the following to unregister timeserver.dll.

Regsvr32 /u c:\servers\timeserver.dll

ActiveX

ActiveX technology was introduced in Visual Basic 5.0 for the first time. Since then it never looked back. I often hear people talking about ActiveX as some thing that is related to internet only. And some seem to think ActiveX as an advanced topic. In my sincere opinion, neither of them is true. Every Visual Basic programmer must understand what is ActiveX and how to create ActiveX components. So let us start our journey of ActiveX. But before we delve into ActiveX we need to understand the software architecture on which ActiveX is based – COM.
What is COM?
COM stands for Component Object Model. COM is software architecture that allows programmers to create components, which can be later used to build applications. The theme is reusability. To put it in other words, if you create a component using COM specifications, it can be used in any language and any platform where COM is supported.

COM is the underlying architecture that forms the foundation for higher-level software services, like those provided by OLE and ActiveX.

COM specifies the standards using which components are to be created. And the components created using COM specifications have the following characteristics:

They are platform independent. They are usable in Windows, Windows NT, Macintosh, and Unix. They are language independent. If you create a component in Visual Basic, later you can use that component in VC++, PowerBuilder or anywhere, where COM is supported.
They are also extensible.

COM is a general architecture for component software. Microsoft is using COM to address specific areas like creating controls, servers etc.

It is beyond the scope of this book to discuss about the specifications and internals of COM. There are so many technical articles in MSDN on COM and DCOM. Read them if you want to have an insight of COM.

What is ActiveX?
ActiveX is a new technology (actually a renamed technology). Its predecessor is OLE ; ActiveX allows you to create components based on COM specifications and enables you to develop interactive web pages.

ActiveX includes both client and server side technologies. That means it allows you to create components that run both on client and server.

An ActiveX component is a reusable piece of data and code (object) created using ActiveX technology. The best part of ActiveX is it allows you to create components that can be used in any project (irrespective of language) straight away. This saves a lot of development time. Well, if you boil it down, it comes to reusability, which is one of the characteristics of component software to which ActiveX belongs.

However, note that ActiveX talks about binary interoperability. That means only compiled components are reusable and NOT source code.



ActiveX Components
The components that you create using ActiveX technology are of different types. The following are the different types of ActiveX components.

ActiveX Applications (ActiveX .EXE)
An ActiveX application is a standalone application, such as MS-Word, MS-Excel etc. These applications provide objects that you can access and manipulate programmatically from an application written in Visual Basic or any application development tool that supports ActiveX.

Note: Each component has a collection of properties, methods and events that can be accessed from outside. These properties, methods and events are collectively called as interface of the component.

ActiveX Code Components (ActiveX .DLL)
ActiveX code component is a collection (library) of programmable objects, where objects are generally related to a specific topic such as, financial functions, date and time functions etc.

ActiveX code components do not run as separate applications, instead they are run in the same process area as the client (the application that is using the code component). More on this later in this chapter.

ActiveX Controls (.OCX controls)
ActiveX controls are user-defined controls. Formally they were called as OLE controls. Each ActiveX control does a specific job. For example, an ActiveX control may deal with displaying a calendar, another may deal with displaying running digital clock and so on. There are hundreds of ActiveX controls available from various vendors, whose primary job is creating ActiveX controls and sell them to developers.

Note that even Visual Basic 4.0 users could create OLE Server (now called as ActiveX Server) but creating an ActiveX control was introduced for the first time in Visual Basic 5.0. It really made Visual Basic programmers thrilled. Well, I am one of them and now you join the bandwagon.

In fact, we have already used good number of ActiveX controls, such as DataList, ADODC, DataGrid etc. We know how to use them but in the coming chapters 27, 28 & 29 we will learn how to create our own ActiveX controls.

ActiveX Document (. VBD Document)
ActiveX documents are Internet pages. You can use ActiveX documents to create interactive Internet application. Each ActiveX document is a Web page. An ActiveX document can host ActiveX controls and can invoke dialog boxes and so on.

Visual Basic 6.0 has introduced DHTML application. DHTML application provides better alternative to ActiveX document application.

In-process and Out-of-process servers
An ActiveX code component may be either in-process or out-of-process. In-process server is implemented as .DLL and out-of-process server is implemented as .EXE.

An application using ActiveX component interacts with it using Client/Server architecture. Application makes the request to the component and component responds to the request. Here client is the application that is using the services of the component. And the ActiveX component is the server. Depending upon where server runs, ActiveX components are classified into two types.

In-process server
An in-process server is an ActiveX .DLL. It runs in the address space of the client application. It cannot be run as a separate process. The communication between client (application) and server (code component) will be faster as both of them (client & server) reside in the same address space. And more importantly there is no context switch (switching from one process to another). An example for in-process server is ActiveX Data Objects library.



Out-of-process Server
An ActiveX code component that is implemented as .EXE is an out-of-process server. It runs in its own address space. When a client invokes a method of the server, control switches from client process to server process (context switch occurs). An out-of-process application can also be run as a standalone application.
Creating an ActiveX .DLL
An ActiveX DLL is a collection of object that can be used by client applications. Let us create a simple ActiveX code component that is implemented as in-process server (ActiveX .DLL).

We will create an ActiveX DLL with just one class. It is important to understand how to create a class when you are creating an ActiveX DLL, as ActiveX DLL is a collection of classes. A client application that is using this ActiveX DLL creates objects of the classes exposed by server and invokes methods and properties to get the job done.

Time Class
The ActiveX server that we are going to create contains only one class – Time class. The following is the list of properties, methods, and events of the class.

Type Name Meaning
Property Hour Sets/ returns the number of hours
Min Sets/ returns the number of minutes.
Second Sets/returns the number of minutes.
Method IncrementSecond Increments the time by one second.
SetToCurrent Sets the time to current system time.
GetTime Returns time of the class in HH: MM: SS format.
SetTime Takes time in HH: MM: SS format and changes time of the class to the given time.
Event InvalidTime Raised whenever Hour, Min, or Second property is set to an invalid value.
Table 25.1: Members of Time class.

The following are the major steps in creating an ActiveX DLL

• Create a project of ActiveX DLL type
• Create as many class modules as required.
• Change properties of project
• Create .DLL file

To creating an ActiveX DLL project:

1. Select File -> New Project and select ActiveX DLL as the type of the project.
2. Visual Basic creates a new project with a single class module with Class1 and change the name to time.
Using Class Builder utility
Class builder utility could be used to create skeleton for methods, properties and events. Let us use class builder utility to create attributes of Time class.

To invoke Class Builder Utility:

1. Select Add-In Manager option of Add-Ins Menu.
2. In Add-In Manager window double click on VB 6 Class Builder Utility
3. Then message Loaded appears under Load Behavior column.
4. Click on Ok.
5. Select Add-Ins menu and choose Class Builder Utility to invoke Class Builder.
6. If Class Builder displays a warning message, just ignore it and continue.

Renaming Class1 to Time

1. Select Class1 in Classes Pane of Class Builder Utility and click on right button.
2. Select Rename option and rename Class1 to Time.

Creating properties, methods and events using Class Builder

1. Click right button on Time class
2. Select New-> Property option from popup menu.
3. Enter the name of the property as hour and change data type to Integer.
4. In declaration group leave the Public Property radio button selected.
5. And click on Ok
At this stage class builder displays a property in the left pane.
6. Repeat the process for Min and Second properties.
7. Click right button on Time class and select New->Method from popup menu.
8. Enter IncrementSecond as the name of the method.
9. Select Attributes table and enter “Increment time by one second” as the description. Whatever description you enter here will be displayed in Object Browser when you select this method.
10. Click on Ok
11. Repeat the same process for SetToCurrent method. Enter “Sets time to current system time” as the description.
12. Again select New->Method from popup menu and enter SetTime as the name of the method and “Changes the time to the given time. Time must be given in HH: MM: SS format” as description.
13. Then click on + sign on the right of Arguments list box and enter the following details .
Name NewTime
Type String
ByVal Checked

Note: if optional checkbox is checked then the argument is optional. If no value is passed to the argument then the given default value will be stored in that.

14. Create one more method with the name GetTime and specify the Return Data Type as String.
15. Select New->Event from popup menu of Time class
16. Enter InvalidTime as the name of the event and “Fired when an given hour, min or second is invalid” as the description
At the end of creation of methods, properties and events, the class builder should look like .

Note: You can add property, method and event using icons in toolbar also.

Note: Select tab “All” if you want to see all the attributes of the class. Otherwise select one of the three tabs (Properties, Methods, and Events) to display the specific members.

To update project with changes made in class builder:

1. Select File-> Update Project option. Class builder updates the class module with the details furnished so far.
2. Exit Class builder with File-> Exit.

If you open Time class module, the code contains three properties, two methods and one event. The code is shown in listing 25.1.

'local variable(s) to hold property value(s)
Private mvarMin As Integer 'local copy
Private mvarSecond As Integer 'local copy
Private mvarHour As Integer 'local copy
'To fire this event, use RaiseEvent with the following syntax:
'RaiseEvent InvalidTime[(arg1, arg2, ... , argn)]
Public Event InvalidTime()

Public Sub SetToCurrent()
End Sub

Public Sub IncrementSecond()
End Sub

Public Property Let Hour(ByVal vData As Integer)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Hour = 5
mvarHour = vData
End Property

Public Property Get Hour() As Integer
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Hour
Hour = mvarHour
End Property

Public Property Let Second(ByVal vData As Integer)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Second = 5
mvarSecond = vData
End Property

Public Property Get Second() As Integer
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Second
Second = mvarSecond
End Property

Public Property Let Min(ByVal vData As Integer)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Min = 5
mvarMin = vData
End Property

Public Property Get Min() As Integer
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Min
Min = mvarMin
End Property

Public Function GetTime() As String
End Function

Public Sub SetTime(ByVal newtime As String)
End Sub
Listing 25.1: Code written by Class Builder
Modifying the code written by Class Builder
Class Builder utility just creates skeleton for methods. We have to insert the code to make method operational.

GetTime Method
This method is used to return the time in HH:MM:SS format. Format function is used to get leading zero for hour, minute and second. Format function takes a values and the format using which the value is to be formatted and returns the formatted values in the form of a string. For complete details of format function, please see on-line help.

Public Function GetTime() As String
Dim s As String
' Return time in HH:MM:SS format
s =Format(Hour,"00")& ":" & Format(Min, "00")& ":" _
& Format(Second, "00")
GetTime = s

End Function
Listing 25.2: GetTime Function.

SetTime Method
Takes time in HH: MM: SS format, breaks it into hours, minutes and seconds and places them into member variables. It checks whether three values are valid. If they are not valid it raises InvalidTime event.

Public Sub SetTime(ByVal newtime As String)
Dim h As Integer
Dim m As Integer
Dim s As Integer

' input must be in HH:MM:SS format
' if values are invalid then raise INVALIDTIME event
h = CInt(Mid(newtime, 1, 2))
m = CInt(Mid(newtime, 4, 2))
s = CInt(Mid(newtime, 7, 2))
If h >= 0 And h <= 23 And m >= 0 And m <= 59 And s >= 0 And s <= 59 Then mvarHour = h mvarMin = m mvarSecond = s Else RaiseEvent InvalidTime End If End Sub Listing 25.3: SetTime method. IncrementSecond Method This method is used to increment seconds by one. If incrementing the second causes second to exceed 59 then second is set to 0 and minute is incremented by one. And so on. Public Sub IncrementSecond() ' increment second by one mvarSecond = mvarSecond + 1 If mvarSecond > 59 Then
mvarSecond = 0
mvarMin = mvarMin + 1
If mvarMin > 59 Then
mvarMin = 0
mvarHour = mvarHour + 1
If mvarHour > 23 Then
mvarHour = 0
End If
End If
End If
End Sub
Listing 25.4: IncrementSecond method.

SetToCurrent method
This is used to change time to current system time. I have used methods of DataTime object and Time function to get current hour, minute and second.

Public Sub SetToCurrent()
' change time to current system time
mvarHour = DateTime.Hour(Time)
mvarMin = DateTime.Minute(Time)
mvarSecond = DateTime.Second(Time)
End Sub
Listing 25.5: SetToCurrent method.

Property Procedures
The following are the property procedures required for Hour, Min and Second properties. In all three, if the value is assigned is not valid the InvalidTime event is raised.

Public Property Let Hour(ByVal vData As Integer)
If vData >= 0 And vdate <= 23 Then mvarHour = vData Else RaiseEvent InvalidTime End If End Property Public Property Get Hour() As Integer Hour = mvarHour End Property Public Property Let Second(ByVal vData As Integer) If vData >= 0 And vData <= 59 Then mvarSecond = vData Else RaiseEvent InvalidTime End If End Property Public Property Get Second() As Integer Second = mvarSecond End Property Public Property Let Min(ByVal vData As Integer) If vData >= 0 And vData <= 59 Then mvarMin = vData Else RaiseEvent InvalidTime End If End Property Public Property Get Min() As Integer Min = mvarMin End Property Listing 25.6: Property procedures. That is about the coding part of the class. Out ActiveX server is almost ready. Generally an ActiveX server contains more than one class. But as we are primarily interested in understanding the concept through an example, one class is quite adequate in our sample ActiveX server. Save class as name Time.Cls and project as TimeProject.VBP. Changing properties of ActiveX Server Invoke Project properties to change the properties of ActiveX server. Here are the steps to change properties. 1. Select Project -> Project Properties to invoke properties window of the current project.
2. Change Project Name to TimeServer
3. Change Project Description to “Time Class By P.Srikanth”.
4. And click on Ok.

Creating .DLL file
Now the final step. We have to create .DLL file for the project. This DLL file is used by the client application. At the time of creating .DLL file Visual Basic registers this ActiveX server in system register.

Note: All ActiveX components must be registered in the system registry. Otherwise they cannot be used in client application.

To create .DLL file:

1. Select File menu and choose Make TimeProject.dll option.
2. When you are prompted to specify the directory and the name of the file, select the directory in to which you want to place .DLL file and leave the filename to default (TimeProject).
3. Click on Ok to create .DLL file.

That is the end of creation of ActiveX in-process server. In the next section, we will see how to use this server in a client application.

Using ActiveX Server
Let us create a small project to understand how to use an ActiveX in-process server. The project type is Standard .EXE type and it contains only one form. for the user interface of the form.

Here are the steps to create testing project.

1. Start a new project using File -> New Project and select Standard Exe as the project type.
2. Invoke Form designer and place two labels and four command buttons .
3. Change the properties of the controls and form as follows.

Object Property Value
Form Caption Time Class Demo
Label1 Caption Time
Label2 Name LblTime
Caption 00:00:00
Fontsize 16
Autosize True
Borderstyle 1-Fixed Single
Command1 Name CmdSetToCurrent
Caption &Set To Current Time
Command2 Name CmdIncrement
Caption &Increment Second
Command3 Name CmdChangeTime
Caption &Change Time
Command4 Name CmdQuit
Caption &Quit

Now we need to use ActiveX server. But to use an ActiveX server, first we have to have a reference to ActiveX server in the current project.

Creating a reference to ActiveX server
Unless you create a reference to ActiveX server (or any ActiveX component), you cannot access ActiveX server. So, the first step in using an ActiveX server is creating a reference as follows:

1. Select Project - > References
Visual Basic displays the list of ActiveX servers that are registered in the system registry .
2. Search for “Time Class By P.Srikanth”. Because whatever we give as project description in ActiveX server project, that will be displayed in References window.
3. Once you locate it, check the check box on the left. Also observe that the complete path of .DLL file is placed at the bottom of the window .
4. After turning on the check box click on Ok to close References window.
Save the project as TimeTest.Vbp and form as TimeTest.Frm.

Writing code for Sample project
We have to first declare an object of Time class with WithEvents keyword. Write code for InvalidTime event of the object. And then write code for command buttons. The total code for the sample project is shown in listing 25.7.

General/Declarations

Option Explicit
'declare an object of TIME class
Dim WithEvents t As Time

Private Sub cmdChange_Click()

Dim ts As String
' take time using inputbox
ts = InputBox("Enter time in HH:MM:SS format", "Time")
If ts <> "" Then
t.SetTime ts
lbltime.Caption = t.GetTime
End If

End Sub

Private Sub cmdquit_Click()
Unload Me
End Sub

Private Sub cmdSetToCurrent_Click()
t.SetToCurrent
lbltime.Caption = t.GetTime
End Sub

Private Sub CmdIncrement_Click()
t.IncrementSecond
lbltime.Caption = t.GetTime()

End Sub

Private Sub Form_Load()
Set t = New Time
t.SetToCurrent
lbltime.Caption = t.GetTime
End Sub

Private Sub t_InvalidTime()
MsgBox "Invalid Time"
End Sub
Listing 25.7: Code for event in the form.

Test Run

1. Now run the project. As in Form_Load event Time object is set to system time, you should see the system time as soon as the project starts.
2. After some time again click on Set To Current Time command button. The time should be updated to the current system time.
3. Click on Change Time command button and enter 10:10:58 as new type. This will change the time and new time is displayed.
4. Clicking on Increment Second button should make it 10:10:59. Again clicking on it should make it 10:11:00.
5. Now again choose Change Time and enter 30:20:02 as the time. As hour portion is not valid, SetTime method of the Time class fires InvalidTime event. And you should see “Invalid Time” message in message box.

That’s all that you have to do to test whether it is working in the way you want. If you found any mistakes in Time class then open ActiveX server project, make modifications and then recreate .DLL file.

DHTML Application

DHTML (Dynamic HTML) is a new concept introduced by Microsoft, where developers can dynamically change style and attributes of elements in HTML page after the page is loaded. Dynamic HTML allows you to break HTML page into various elements and program individual elements. That means you can treat a line of text as an element and change its attributes such as foreground color, background color etc, at run time using the code. You can also write code for events of elements.

DHTML is a new way of creating a Web page and it is made available to Visual Basic 6.0 programmer through DHTML application.

Note: To run DHTML application, you must have Internet Explorer 4.x or higher.


What is a DHTML application?
A DHTML application is a collection of HTML pages and Visual Basic code. DHTML application resides on the client machine and runs in Web Browser (Internet Explorer). The code written in Visual Basic responds to event such as user clicking on a button, mouse moving over an element etc.

Structure of DHTML application
A DHTML application is consisting of the following pieces:

• One or more HTML pages
• Visual Basic code to handle events that occurs in browser when user is viewing HTML pages.

Form-based application vs. DHTML application
Unlike a normal Visual Basic application, in DHTML application, the user interface consists of a collection of HTML pages. When user runs the application in Web browser, the user interacts with HTML pages and not Forms.

An HTML page can contain control just like a form. HTML page is stored with extension .htm, which is similar to .frm of a Form.

The following table will highlight the differences between form-based application and DHTML application.

Item Form-based Application DHTML application
User Interface Forms HTML pages
User interface elements such as buttons, text boxes. Controls Elements
File format .frm .htm
Creator Developer Developer or Web Designer.
Run time Visual Basic run time DLL, msvbvm60.dll Web browser control with msvbvm60.dll.
Table 31.1: Comparing Form-based application with DHTML application.




Features of Dynamic HTML
Dynamic HTML is relatively new concept. It takes some time for it to settle down. The following are the key features of Dynamic HTML. For detailed information regarding each of these features, please see on-line documentation.

• Allows you to create more interactive user interface through dynamic styles and dynamic content. Dynamic styles allow you to change the style of element at run time. Dynamic content allows you to customize (adding new elements, removing existing elements and modifying elements) the web page without browser submitting the request to server. This reduces time taken for customization.
• Allows you to place any element at the required position by using x and y coordinates.
• When an event occurs on a child object, the event can travel up the chain of hierarchy within the page until it encounters an event handler to process the event. This process is called event bubbling.

Developing a DHTML Application
Developing a DHTML application is not much different from a form-based application. The following are the steps involved in the process:

• Start a new project and select DHTML Application as the project type.
• From the Project Explorer window, open DHTML page designer by double clicking on the page.
• If you are designing your user interface from scratch, add HTML elements and ActiveX controls to your page and arrange them as desired.
• If you want to edit an existing page, use the Properties dialog box to refer an external HTML file, then make any necessary changes to the page's contents and appearance.
• Add code for any elements on the page for which you want to handle user actions.
• If necessary, add other pages to the project, add elements to them, and write code.
• Test and debug the application by running the project and viewing the document in Internet Explorer 4.01 or later.
• Compile the project.
• Deploy the application using the Package and Deployment Wizard.

Saving a DHTML page
You can save DHTML page in either of two ways:

Save it within designer file - saves the page as part of your application. No external .htm file is created. The .dsr file contains the page. This method is good when you want to move your application from one machine to another. But it doesn’t allow you to edit .htm file using external editor.

Save the page to a location on your computer - the page is saved to an external file, whose absolute path is given using Sourcefile property. This allows you to use external editor to edit .htm file. But it becomes difficult to move all external files when you move your application.


Writing code for Dynamic HTML
When you are working with DHTML application in Visual Basic, you use Dynamic HTML object model to access and manipulate HTML element on the page. You can modify appearance and behavior using properties and method of the elements.

Dynamic HTML object model
The following are the main objects in object model.

Basewindow - is a reference to the browser that displays the page. This is the topmost object in the hierarchy of Dynamic HTML object model.

Document – represents HTML page that you view in browser.

Events in Dynamic HTML
Most of the events of Dynamic HTML are same as events in Visual Basic. However the names of the event slightly differ. For example, Click event in Visual Basic programming model will be OnClick in Dynamic HTML object model.

Note: All events in Dynamic HTML are preceded by word “on”.

Also note that there are certain new event in Dynamic HTML that are not available in Visual Basic and some of the Visual Basic events are not available in Dynamic HTML.

Visual Basic events vs. Dynamic HTML events
The following tables list events in Visual Basic and corresponding events in Dynamic HTML in various categories.

Keyboard Events
Keyboard events in Dynamic HTML correspond very closely to keyboard events in Visual Basic. The following table lists the common Visual Basic keyboard events and their Dynamic HTML counterparts:

Visual Basic Event DHTML Event Comments
keydown onkeydown Fires when a key is pressed.
keypress onkeypress Fires when a user's keyboard input is translated to a character.
keyup onkeyup Fires when a user releases a key.
Table 31.2: Comparing Visual Basic form events with DHTML events.

When a keyboard event occurs, the keycode property of Dynamic HTML's event object contains the Unicode keycode of the corresponding key. The altKey, ctrlKey, and shiftKey properties specify the state of the ALT, CTRL, and SHIFT keys.

You can change which key is associated with the event by either changing the value of the keycode property or returning an integer value.

Note: You can cancel the event by returning zero or false.
Mouse Events
Mouse events in Dynamic HTML correspond closely to mouse events in Visual Basic. The following table lists the common Visual Basic mouse events and their Dynamic HTML counterparts:

Visual Basic Event DHTML Equivalent Comments
click onclick In addition to occurring when a user clicks on an element, this event also fires when the user presses ENTER on an element that can receive focus, such as a button.
doubleclick ondblclick This event works similarly to its Visual Basic counterpart.
mousedown, mouseup, mousemove onmouseout, onmousedown, onmouseup, onmousemove, onmouseover When moving between elements, the onmouseout event fires first to indicate that the mouse has left the original element. Next the onmousemove event fires, indicating that the mouse has moved. Finally, onmouseover fires to indicate that the mouse has entered the new element.
Table 31.3: Comparing Visual Basic Events with DHTML events.

When a mouse event occurs, the button property of the event object identifies which mouse button (if any) is down. The x and y properties specify the location of the mouse at the time of the event. For onmouseover and onmouseout events, the toElement and fromElement properties specify the elements the mouse is moving to and from.

Focus and Selection Events
Focus and selection events in Dynamic HTML differ slightly from their Visual Basic counterparts. In particular, focus events are called only from certain elements, and selection and dragging are handled differently.

The following table lists the common Visual Basic focus and selection events and their Dynamic HTML counterparts:

Visual Basic Event DHTML Equivalent Comments
gotfocus onfocus Fires when the user moves to an element capable of receiving input, such as a button or form element.
lostfocus onblur Fires when you move out of an element that is capable of receiving input.
selchange onselectstart
onselect The onselectstart event fires when a selection is first initiated — for example, when the user clicks a character or object in the document. Onselect fires when the user changes the selection — for example, by moving the mouse over a portion of the document while holding down the mouse button.
dragdrop, dragover ondragstart Fires when the user first begins to drag the selection. The default action is to prepare the selection to be copied to another element.
Table 31.4: Focus events comparison.

Note: Onblur and onfocus fire whether you move between elements in the page, between frames, or even between applications on the desktop. For example, if a page element has focus and the user switches to another application, the onblur event fires for that element. When the user switches back, onfocus fires.

Other Events
The following are the events that do not belong to any of the categories discussed so far.

Visual Basic Event DHTML Equivalent Comments
change onchange Onchange fires when the user tabs off or presses ENTER on an element, moving out of it. In Visual Basic, the change event fires as soon as the user performs any action within the control.
close Not Available No direct equivalent exists for this event.
error Onerror Fires when an error occurs loading an image or other element, or when a scripting error occurs.
initialize Onready
statechange Fires when the page changes from initializing to interactive, and from interactive to loaded. A page is interactive as soon as the user can interact with it by scrolling or clicking on anchors or elements. A page is loaded when all the content has been downloaded.
load Onload Fires after the document is loaded and all the elements on the page have been completely downloaded.
paint Not Available No direct equivalent exists for this event.
resize onresize This Dynamic HTML event functions similarly to its Visual Basic counterpart; however, you do not need to write code to handle resizing of an HTML page as you do a Visual Basic form. Resize in HTML happens automatically.
scroll onscroll Fires whenever the scroll box for the page or any element within it is repositioned.
terminate Not Available No direct equivalent exists for this event. You can perform terminate-type actions in the onunload event. A terminate event does exist for the DHTMLPage object. This object is not part of the DHTML object model, and is unique to Visual Basic.
unload onunload Fires immediately prior to the document being unloaded (when navigating to another document).
Table 31.5 : Comparing miscellaneous events.

Events Unique to Dynamic HTML
In addition, there are some events in Dynamic HTML that do not have equivalents in Visual Basic. A few of the more interesting of these are shown in the following table:
DHTML Event
Usage
Onabort Fires when the user aborts the download of an image or page element by pressing the Stop button.
Onreset Fires when the user selects a Reset button on a form.
Onsubmit Fires when the user selects a Submit button on a form. Can be used to perform validation of data on the client before sending it to the server.

Making Elements programmable
You can programmatically handle elements on HTML page in DHTML application. That means you can write code for events of the elements and the code is executed whenever the event occurs on the element. You can also change property of the elements dynamically.

To make an element programmable, the element must be assigned an ID. Some elements are by default assigned and ID. Whereas for some other elements you have to provide ID.

To makes an element programmable:

1. Select element in Designer.
2. Invoke properties for the element
3. Change ID property to a unique ID.
4. Refer to the element in the program using ID that you assigned in previous step.

Note: All IDs on a page must be unique. If you have a duplicate ID then at the end of ID Visual Basic adds a number to make it unique.

Enabling the default action
Many event of elements have default action. For example, when you click on a Hyperlink to invoke the specified page, the click event by default will take you to the required page. But if programmer writes code then programmer has to let the default action take place.

To let default action take place, return True from the event and returning False (default) doesn’t perform the default action.

Common Styles for HTML Elements
The style properties you use to set the physical appearance of an HTML element are named differently than their corresponding properties in Visual Basic.

The following table lists a few of the more frequently used styles and explains their use.

DHTML Style
Purpose
backgroundcolor Setting the background color of all elements except the Document object, which represents the body of the page. For the page itself, the property is called bgcolor.
border Setting a border around any element. All elements on an HTML page can have a border, including paragraphs of text.
color Setting the foreground color for all elements except the Document object, which represents the body of the page. For the page itself, the property is called fgcolor.
Font Setting the font for the element. A series of related properties (fontfamily, fontsize, fontstyle, etc.) are used to fine-tune the appearance of the font.
Margin Controlling the distance between the border of the element and the edge of the page. This property can be set to control all of the element's margins, or you can set the top, bottom, left, and right margins independently through a series of related properties.
padding Controlling the distance between the inner text of the element and its border. This property can be set to control the padding space on all sides of the elements, or you can set the padding of the top, bottom, left, and right sides independently through a series of related properties.
textdecoration Formatting text within an element. You use this property to make the text blink, or to display it with a strikethrough, underline, or overline.
Table 31.6: Common style of DHTML elements.

Creating sample DHTML application
We have seen a lot of DHMTL theory. Now let us put that to practice by developing a simple application. The application is creation of three web pages that contain the information regarding P.Srikanth (author). The application contains three pages - Home page, Experience page and Courses offered page. The first page is called as home page and contains links to other pages. Experience page displays the experience in various divisions. And last page is the most interesting of all. It takes the details of courses offered by Srikanth from a database and displays details based on the course selected by user.

I should admit, through this sample application, I can cover only a part of DHTML application’s ability. If you are interested in developing more application using DHTML applications, then I strongly suggest you read everything about Dynamic HTML in on-line documentation.

To create sample application:

1. Start a new project and select DHTML application as the type of the project.
2. Visual Basic creates a new project with two components – code module, modDHTML, and DHTML page, DHTMLPage1.

Double click on DHTMLPage1 to invoke designer and to load DHTML page into it.

Understanding TreeView pane and Detail pane
In DHTML page designer we have two portions. Left side pane is called as Treeview and right side pane is called as Detail pane.

Treeview Pane
TreeView pane displays hierarchical representation of the element within HTML page. Some of the element contains ID by default. And for elements that do not have id by default you can assign Id using Id property.

All elements in the treeview are children of the Body element and the Document object

Note: When you are working with DHTML page designer you get a different tool box containing element related to DHTML page.

The treeview provides three valuable shortcuts:

• When you select an item in the treeview, Visual Basic highlights the appropriate item in the detail panel and in the Properties window. This can help you determine at a glance the correspondence between elements in the treeview and on the page. Note that this works in reverse as well: When you select an element on the detail panel or in the Properties window, Visual Basic highlights the corresponding element in the treeview and scrolls the treeview accordingly.
• You can double-click an element in the treeview to open the Code Editor window for that element. The system selects the default event for the element.
• For ActiveX controls that do not have a visible user interface at run time (such as the common dialog control), the treeview is the only way you can select and manipulate these elements after adding them to your page.

Detail Pane

Presents a drawing surface on which you can create a new page or edit the contents of an existing page. You can add HTML elements to the page, position elements, and set properties that control their physical appearance.

Creating first HTML page
Now let us concentrate on creating first page. This page contains two hyperlinks to the other two pages of this application. This page also contains some text and an image.

Let us understand how to create all these elements.

1. Invoke properties by pressing F4 and select IDHTMLPageDesigner using dropdown listbox at the top and change Name and Id properties to homepage.
2. First go to the top of the page and type “Home Page of P.Srikanth” and change its format to heading1 using dropdown list box on the upper-left corner.
3. Place a HorizontalRule below the text so that it works as the divider.
4. Place two paras of text
5. Place first of two hyperlinks and change text on the hyperlink to “Experience”.
6. When the hyperlink element is selected press F4 to invoke properties and change the href property to skwebsite_experience.html. In hyperlink reference, skwebsite is the name of the application, and experience.html is the name of the html file that will be created for second HTML page.
7. Place second hyperlink and change text on the hyperlink to “Courses”
8. Change href property of second hyperlink to skwebsite_courses.html. When user clicks on this hyperlink, page containing course details is displayed.
9. Place an image on the right of title
10. Invoke properties of image element and change Image source property to the name of the file in which you have required image. In this example the complete path is C:/Books/VB60/programs/me.bmp.
With that designing part of first page is complete.

Note: In case you want to write code for any of the paras, change ID property and use the given id in your program to refer to the element.
Creating second page (Experience)
Second DHTML page contains the information regarding experience. This page is simplest of all three pages. Apply the following procedure to create and design second page.

1. Select Project -> Add DHTML page to add a new DHTML page to project.
Visual Basic displays a dialog box asking whether you want to save HTML of the page to be saved as part of project or it is to be saved in an external file. S
2. Leave it to default setting (saving as part of project) and click on Ok.
3. Invoke properties and change Id and Name properties of IDHTMLPageDesigner to Experience.
4. Enter text Placing the text on the page is done by straightaway getting to the required position and typing the text.

That’s all you have in experience page.

Now if you want to test how it works, run the project using F5. When VB prompts you to specify the first page, select homepage as the startup page. And accept homepage as the startup page. When you click on experience hyperlink, you should enter into experience page.
Creating Third page (courses)
This page has a lot of process. Because, this page takes the list of courses from database and displays the list in a list element to user. And when user selects a course from the list, it displays the details of the selected course. The total process is handled using ADO. The database is COURSE.MDB and the table is subjects.

This page contains a list element and a few textfields. List element is used to display the list of available subject (each subject is treated as a course). The list is populated using Load event of the page. And when user selects an option (course) in the list then we will display the details of the course. These details come from subjects table. For this we use OnClick event of the list element.

The following are the steps required to create third page.

1. Add a new DHTML page to project using Project -> Add DHTML Page
Select Save HTML with Visual Basic project options.
2. Invoke properties windows using F4 and change Name and Id properties of IDHTMLPageDesigner to courses.
3. Place elements
4. Change the Value property of all four textfields to empty string.
5. Change ReadOnly property of all four textfields to True. Because textfields are used to display the information only. User is not supposed to change the data.
6. For List element, by default one option is added. Invoke property page of list element and delete all the options in the list element using Delete button.
7. Change size to 5 lines.

As we are going to use ADO, load Microsoft ActiveX Data Objects 2.0 library using Project->References.

And finally write the following code.

General/Declarations

Dim rs As New ADODB.Recordset
Dim con As New ADODB.Connection

Private Sub DHTMLPage_Load()

Dim elmnt As HTMLOptionElement

' connect to database and get the details of the courses offered
con.Open "Provider=Microsoft.jet.oledb.3.51;data source=c:\books\vb60\programs\course.mdb"
rs.Open "select scode,sdesc from subjects", con

' load data into list box


Do Until rs.EOF ‘add one element at a time
Set elmnt = Document.createElement("OPTION")
With elmnt
.Text = rs("sdesc")
.Value = rs("Scode")
End With
List1.Options.Add elmnt
Set elmnt = Nothing
rs.MoveNext
Loop
rs.Close
Set rs = Nothing

End Sub

‘ Returns second value if first value is null
Public Function Nvl(av As Variant, rv As Variant) As Variant

If IsNull(av) Then
nvl = rv
Else
nvl = v
End If

End Function

Private Function List1_onclick() As Boolean
' get the details of the selected subject
Dim scode As String
Dim rs As New ADODB.Recordset

scode = List1.Value
qry = "select version, duration, prerequsite,coursefee from subjects where scode = '" & scode & "'"
rs.Open qry, con

txtduration.Value = nvl(rs("duration"), "")
txtprerequisite.Value = nvl(rs("prerequsite"), "")
txtversion.Value = nvl(rs("version"), "")
txtcoursefee.Value = nvl(rs("coursefee"), "")
rs.Close
Set rs = Nothing

End Function
Listing 31.1: Code for third DHTML page.
Test run
Run the application and check whether all features are working. Take the following steps.

1. Run the application using F5. Visual Basic displays home page.
2. Click on Experience hyperlink (it will be underlined)
Internet Explorer displays Experience page.
3. Click on Back icon in Internet Explorer.
4. Click on Courses hyperlink.
5. Select one of the subjects listed in the list element. The details of the selected page are displayed in text box elements.
6. Quit the application by terminating Internet Explorer.

ActiveX Control Related Objects and Property pages

Objects related to ActiveX control
The following are the objects that are involved in the process of creating an ActiveX control.

• UserControl object
• AmbientProperties object
• Extender object
• Constituent control objects

UserControl Object
This is the object used to create a single ActiveX control. Every ActiveX control is consisting of one UserControl object and a set of constituent controls. Just like a From, a UserControl object also has a designer, which allows you to place intrinsic control on the UserControl object.

You have properties, methods, and events for UserControl object. They are discussed later in this chapter.

AmbientProperties Object
This is used to get information from container of ActiveX control. The properties of AmbientProperties object are the ambient properties of the control. These properties are read-only. These properties allow you to determine how you adapt your control according to the capabilities of the container.

Not all ambient properties are standard. Some of them are specific to only a particular container.

AmbientChanged event occurs whenever any of the ambient properties (properties in container) changes. This enables programmer to change control according to the container.

AmbientProperties object is not available in Initialize event.

The following is the list of standard ambient properties.


Property Meaning Default value if property is not supported by Container.
BackColor Color that contains the suggested interior color of the contained control. &H80000005
DisplayAsDefault Returns True if the control is the default control otherwise false. false
DisplayName The name that the control assigned by developer. "".
Font Contains the suggested font information of the contained control. MS Sans Serif 8.
ForeColor Suggested foreground color of the contained control. 0x80000008: the system color for window text.
LocaleID Specifies the language and country of the user System locale ID.
Palette Picture object whose palette specifies the suggested palette for the contained control.
RightToLeft Indicates the text display direction and control visual appearance on a bi-directional system. False.
ScaleUnits The name of the coordinate units being used by the container. ""
TextAlign Specifies how text is to be aligned. 0 - General Align.
UserMode Specifies if the environment is in design mode or end user mode True.
Table 28.1: Ambient properties of a UserControl.

The following code changes the background color of the text box to the background color of the container whenever background color of the container is changed.

Private Sub UserControl_AmbientChanged(PropertyName As String)
If PropertyName = "BackColor" Then
txtNumber.BackColor = Ambient.BackColor
End If
End Sub
Listing 28.1: Changing BackColor property of text box to BackColor property of user Control.

AmbientChanged event of the UserControl object occurs whenever any of the ambient properties is changed. Ambient object provides access to values of ambient properties.

PropertyName parameter of the AmbientChanged event contains the name of the properties that has been changed in the container.

Extender Object
This object holds properties of the control that are actually controlled by the container of the control rather than by the control itself

The properties, methods, and events of Extender object are provided by the container. So there is no guarantee that all these are supported in all platforms.

You can access extender properties using Extender property of UserControl.

The following is the list of extender properties.

Property Meaning
Name Contains the user-defined name of the control.
Visible Specifies if the control is visible or not.
Parent Represents the container of the control, such as a form in Visual Basic.
Cancel Indicates that the control is the Cancel button for the container.
Default Indicates that the control is the default button for the container.
Container Represents the visual container of the control.
DragIcon Picture that specifies the icon to use when the control is dragged.
DragMode Specifies if the control will automatically drag, or if the user of the control must call the Drag method.
Enabled Specifies if the control is enabled. This is not present unless the control also has an Enabled property.
Height Specifies the height of the control in the container’s scale units.
HelpContextID Specifies the context ID to use when F1 key is pressed being in the control.
Index Specifies the position in a control array that this instance of the control occupies.
Left Specifies the position of the left edge of the control to the left edge of the container, specified in the container’s scale units.
TabIndex Specifies the position of the control in the tab order of the controls in the container.
TabStop Specifies if Tab will stop on the control.
Tag Contains a user-defined value.
ToolTipText Contains the text to be displayed when the cursor stays on the control for more than a second.
Top Specifies the position of the top edge of the control to the top edge of the container, specified in the container’s scale units.
WhatThisHelpID Specifies the context ID to use when the What’s This pop-up is used on the control.
Width Specifies the width of the control in the container’s scale units.

Table 28.2: Extender properties.

The following are the methods provided by Extender object.

• Drag
• Move
• SetFocus
• ShowWhatsThis
• Zorder

The following are the events provided by Extender object

• DragOver
• DragDrop
• GotFocus
• LostFocus

Properties of UserControl object
The following are the properties that are specific to user control object.

Property Meaning
AccessKey Returns or sets a string that contains the keys that will act as the access keys (or hot keys) for the control.
Ambient Returns an AmbientProperties object holding the ambient properties of the container.
ContainedControls Returns a collection of the controls that were added to the control.
EditAtDesignTime Returns or sets a value determining if a control can become active during the developer design time
EventsFrozen If it is set to true, then events of usercontrol are ignored by container
Extender Returns the Extender object for this control that holds the properties of the control that are kept track of by the container.
ParentControls Returns a collection containing other controls in parent container.
PropertyPages Is a string array containing the names of the property pages in the project that are associated with this control.
ContainerHwnd Returns the window handle (hWnd) of a UserControl’s container.
Parent Returns a reference to the container object on which the control is sited.
CanGetFocus Determines whether focus should move to this control or not.
Table 28.3: Properties of User Control.

UserControl Events
The following are the various events of usercontrol object and their description.

Event When does it occur?
AccessKeyPress Occurs when user presses one of the accesskeys for the control. It passes the key that is pressed by user.
AmbientChanged Occurs when an ambient property’s value changes. This passes the name of the property as the only parameter
EnterFocus This event occurs whenever a constituent control receives focus.
ExitFocus Occurs whenever focus leaves the control.
GotFocus Occurs in the constituent control when focus enters it. The EnterFocus event is raised before the GotFocus event.
Hide Occurs when the object’s Visible property changes to False.
InitProperties Occurs when a new instance of an object is created.
This allows programmer to initialize new control when it is placed on the form.
ReadProperties Occurs when loading an old instance of an object that has a saved state. This is used to read the values of the properties. Used for property persistence.
Show Occurs when the object’s Visible property changes
WriteProperties Occurs when an instance of an object is to be saved. This is used to save the values of properties.
AsyncReadProgress Occurs when more data is available as a result of an AsyncRead method.
AsyncReadComplete Occurs when the container has completed an asynchronous read request.
HitTest Occurs when the user moves the mouse over a UserControl object. Only occurs when the Windowless property of the UserControl is set to True and the BackStyle property is set to Transparent.
Initialize Occurs when an application creates an instance of a user control.
Terminate Occurs when the instance of the control is about to be destroyed.
Table 28.4: Events of user control object.

Property Pages
Before we started creating ActiveX Control, we had already used a few ActiveX controls. All of them have Property pages that allow you to change properties of the control. Now let us create two property pages for our Number control. First one contains a text box to take number from user and changes Value property, Second one contains two text boxes Maximum Length and Minimum Length properties. A developer using Number ActiveX Control can invoke property pages and change properties.

The best way of creating a property page is using Property Page Wizard. Now having decided how many property pages to have and what to have in each of these property pages, we are ready to use Property Page Wizard.

To invoke property page wizard:

1. First make Property Page Wizard available to Visual Basic project by selecting Add-Ins menu and then select Add-In Manager option.
2. In Add-In Manager dialog box double click on VB 6 Property Page Wizard. You should see Loaded message in Load Behavior column.
3. Click on Ok.
4. Then select Add-Ins menu and Property Page Wizard. You will see a series of windows prompting for required information.

The following are the steps to create two property pages and to place Value property in first property page and MinLength and MaxLength properties on the second property page.

1. When Property Page Wizard is displayed, it first displays Introduction screen.
2. Click on Next button to move to select the Property Pages page.
3. Click on Add button.
4. Enter ppValue as the name of the page.
5. Click on Add button again and enter ppLength as the name of second property page.
6. Click on Next button to move to Add Properties page.
7. Available Properties list contains the list of available properties.
8. Make sure ppValue tab is selected in Available Property Pages.
9. Select Value property and click on > to move the property to ppValue property.
10. In the same way select ppLength tab and click on >> to place MinLength and MaxLength properties on ppLength property page.
11. Click on Finish button to start building property pages.
12. Invoke ppValue property page and change Caption property to “Value”
13. Invoke ppLength property page and change Caption property to “Length”.

Property Page Wizard has created two property pages ( ppValue and ppLength)

The code that Property Page Wizard has written for ppValue property page is as follows.

Private Sub txtValue_Change()
Changed = True
End Sub

Private Sub PropertyPage_ApplyChanges()
SelectedControls(0).Value = txtValue.Text
End Sub

Private Sub PropertyPage_SelectionChanged()
txtValue.Text = SelectedControls(0).Value
End Sub
Listing 28.1: Code written by property page wizard.
Property page containing text boxes for MaxLength and MinLength properties.

Let us understand the code written by Property Page Wizard. But before we try to do that, we have to understand properties, events of property page.

Changed Property
When this property is set to true, Apply button in the property page will be enabled. In addition to that, setting it to true calls ApplyChanges event whenever you click on Ok button or move to a different property page.

SelectedControls property
This is a collection that contains the controls that are currently selected on the form. SelectedControls (0) references the control that is currently selected. This is used to get the values for properties of the currently selected instance of the ActiveX control for which property page belongs.

The code written by Property Page Wizard, uses SelectedControls (0) (first selected control) only. If you want to handle all selected controls, you have to modify the code written by wizard.

SelectionChanged Event
This is fired whenever an instance of the ActiveX control is selected for editing properties through property pages. This event is used to get the values of the properties from selected control (SelectedControls (0)) and assign those values to controls in property pages to enable user to change them.

ApplyChanges Event
This event is fired whenever user is selecting Apply button, selecting Ok button, closing page or shifting to a different page.

The event occurs only when Changed property is set to true,

Now, if you look at the code written by Property Page Wizard, you should be able to understand the code. The code uses all the properties and events that we have discussed. The following is the summary of the code.

• Sets Changed property to True, whenever user changes values in txtValue text box, which is meant for Value property.
• SelectionChanged event is used to get the value of Value property of the currently selected control (SelectedControls(0)) and put that value in txtValue textbox.
• ApplyChanges event is used to write value entered in txtValue textbox into Value property of the currently selected control (SelectedControls (0)).

Code for ppLength property page
The code written by Property Page Wizard for ppLength property page is as follows.

Private Sub txtMaxLength_Change()
Changed = True
End Sub

Private Sub txtMinLength_Change()
Changed = True
End Sub

Private Sub PropertyPage_ApplyChanges()
SelectedControls(0).MaxLength = txtMaxLength.Text
SelectedControls(0).MinLength = txtMinLength.Text
End Sub

Private Sub PropertyPage_SelectionChanged()
txtMaxLength.Text = SelectedControls(0).MaxLength
txtMinLength.Text = SelectedControls(0).MinLength
End Sub
Listing 28.2: Code for ppLength property page.

This code needs no explanation, as it doesn’t differ from the previous code.

Using property pages at the time of designing
Let us see how a developer who is using Number ActiveX control can use Property Pages of Number control. Here are the steps to test it:

1. Open testing project (tstNumctrl) project
2. Invoke Form designer
3. Select Number1 control and click right button
4. You should see a new option in popup menu – Properties.
5. Select Properties option to invoke Property pages.
6. Property pages window is displayed with two tabs at the top, one for Value property page and another for Length property page.
7. In Value property page, you will see the value you assigned to Value property of the selected control. the value assigned to Value property is 1000. So initially you will see 1000.
8. Change the value to 2000 in property page. It will enable Apply button of the property page. At this stage, your property Page should be identical
9. Click on Apply to make Value property of Number1 control. Click on Length tab to move to Length property page.

Note: Pressing F4 on the control will invoke Properties Pallette. And selecting Popup Menu -> Properties option will invoke Property pages. This is same for all ActiveX controls.

Creating ActiveX Control

We have so far seen how to create an ActiveX DLL and ActiveX EXE. Those two are called as ActiveX code components. We will now discuss about how to create ActiveX Control.
ActiveX Controls were previously known as OLE controls. The fundamental difference between those OLE controls and ActiveX controls is the support for Internet. ActiveX control can be placed on web pages to make web pages more interactive. Something like how you place a Java Applet in a web page.

In this chapter, first we will create a simple ActiveX control to get an overall idea about how to create ActiveX controls. In the next chapter we will get into more details of ActiveX control.

Creating a Number control
Number ActiveX control is a modified version of Textbox. Unlike a textbox, Number control can accept only digits and backspace. You can use this control instead of a textbox whenever you want to accept a number from user. As user cannot enter anything other than digits, there is no scope for making errors. This control also contains a few user-defined properties, methods and events (see table 27.1)

Properties, Methods and Events of Number control are as follows:

Type Name Value
Property Value Sets/returns the value in number control.
MaxLength Sets/ returns the maximum number of digits that can be entered.
MinLength Sets/returns the minimum number of digits to be entered.
Method Clear Clears the content of the control.
Event InvalidChar Fired when an invalid character is entered. Passes invalid character as the parameter.
LengthError Fired when minimum length is not entered by user.
Table 27.1 : Members of ActiveX controls.

The following are the major steps in creating an ActiveX control:

• Creating ActiveX control project
• Placing intrinsic controls (standard controls) on UserControl and changing their properties
• Writing code for events
• Changing properties of the project and creating .OCX file.

Let us follow the steps mentioned above to create Number control.

Creating an ActiveX control Project
Create a new project of type ActiveX control to create Number control as follows:

1. Select File->New Project and choose ActiveX Control as the project type.
A new project is created with a single UserControl. A UserControl object is similar to a form. It can contain intrinsic controls such as textbox, command button etc.
Placing control and changing properties
1. Now invoke UserControl designer by double clicking on UserControl1 in Project Explorer.
2. Place a textbox at the upper left corner of the UserControl.
3. Resize UserControl to the size of textbox.
When control is placed in client application, client application can change the size of the usercontrol according to its requirement.
Whenever user control’s size is changed the size of textbox should also be changed. This is done using Resize event of usercontrol (see listing 27.1).
4. Change the following properties of Usercontrol and Textbox.

Object Property Value
UserControl Name Number
Text1 Name Txtnumber
Text “”(Null)

At the end of this step, UserControl designer
Writing Code
We will write only a part of the code now. Now concentrate on important events such as KeyPress event for textbox, Resize event of UserControl.

Private Sub txtNumber_KeyPress(KeyAscii As Integer)
' ignore nondigits
If KeyAscii < 48 Or KeyAscii > 57 Then
' if key is not tab key
If KeyAscii <> 8 Then
KeyAscii = 0 'ignore
End If
End If
End Sub

Private Sub UserControl_Resize ()

txtNumber.Move 0, 0, UserControl.Width, UserControl.Height

End Sub
Listing 27.1:Code for user control.

UserControl object contains Width and Height properties that contain the width and height of the UserControl object. So change the size of textbox to the size of UserControl object using Width and Height properties of UserControl.

Number control needs a few properties. So let us add required properties to ActiveX control. To create properties we can use ActiveX Control Interface Wizard. But for now let us do it manually. In the next chapter we will see how to use ActiveX Control Interface Wizard.

To create Value property:

1. Invoke code window and then Select Tools -> Add Procedure.
2. Enter Value as the name of the property and select Property radio button in Type group.
3. Click on Ok.

Two property procedures are automatically created. One is Property Let and another one is Property Get. Write the following code. The code is used to map Text property of textbox to value property of number control.

Public Property Get Value() As Variant
Value = txtNumber.Text
End Property

Public Property Let Value(ByVal vNewValue As Variant)
txtNumber.Text = vNewValue
End Property
Listing 27.2: Code for Value property procedure

We will add remaining functionality to the control later. For the time being, let us create .OCX file and use it in a client application.

Creating .OCX file

Save project and give the following names.

Project Numberctrl.vbp
UserControl Number.ctl

Change required properties of the project using project properties window as follows

Project Name NumberCtrl
Project Description Number Control By P.Srikanth.

To create .OCX file:

1. Select File-> Make Numberctrl.ocx
2. Specify the directory in which .ocx file is to be created.
3. Click on Ok.
Visual Basic creates .ocx file and also registers ActiveX control in system registry.

That's all you have to do to create a simple ActiveX control. Remember we still have to add some more features to our ActiveX control. In spite of that, let us use it in a client application to get an idea regarding how it works in client application.

Creating Testing Project
We create a testing project to test ActiveX control. The project contains nothing but a single form and one instance of Number control. Follow the steps given below.

1. Select File->New Project and select Standard Exe as the project type.
2. Select Project -> Components and select Number Control By P.Srikanth.
Tool box contains a new icon representing Number control. If you take MousePointer on to it, it displays Number as the tooltip.
3. Create an instance of Number control just like how you create an instance of standard control (by selecting the icon and then dragging on to form).
4. Also place a command button to get the number that we have entered into it through value property.
5. Change the following properties of command button and the form.

Object Property Value
Form Name txtNumctrl
Caption Testing Number Control
Command1 Name Cmddispvalue
Caption &Display Value

Write the following code.

Private Sub cmddispvalue_Click()

MsgBox Number1.Value, , "Value"

End Sub
Listing 27.3: Code for Display Value button.

An Icon at the bottom representing Number control loaded into project.

Running test project

1. Run the project by pressing F5.
2. Enter a few digits into Number control. It will receive them. Now enter a few alphabets. It will ignore alphabets. Try pressing backspace. It will erase previously entered digit.
3. Click on Display Value command button. A message box will be displayed with the value entered into the Number control.
4. Close testing project and open NumberCtrl (ActiveX control ) project. Now let us enhance our control by adding remaining properties, methods and events.

Enhancing Number Control
The only user-defined property that we have (Value) is mapped to Text property of txtNumber textbox. Now we want to limit the number of digits entered into text box. Text box control also contains MaxLength property. So let us create MaxLength property for UserControl and map it to MaxLength property of textbox.

To create MaxLength property:

1. Get into code window and then select Tools -> Add Procedure.
2. Enter MaxLength as the name and select Property radio button in Type group.
3. Then change property procedures as shown in listing 27.4.
Testing project when displaying value entered into Number control.

Public Property Get MaxLength() As Variant
MaxLength = txtNumber.MaxLength
End Property

Public Property Let MaxLength(ByVal vNewValue As Variant)
txtNumber.MaxLength = vNewValue
End Property
Listing 27.4: Code for MaxLength property.
Note: There is no MinLength property for text box. So creating MinLength property involves a bit more work. And we will do it later.

To create Clear method:

1. Select Tools -> Add Procedure
2. Enter Clear as the name and select Sub as type.
3. Write the following code.

Public Sub Clear ()
txtNumber.Text = ""
End Sub

To create InvalidChar event:

1. Select Tools -> Add Procedure
2. Enter InvalidChar as the name and select Event as the type.
Visual Basic places a single statement in general/declaration as follows.

Public Event InvalidChar()

Add an argument to event of integer type as shown below. This is to pass the Ascii code of the invalid character enter by the user.

Public Event InvalidChar(ch As Integer)

Modifying KeyPress event procedure of Text box
KeyPress event is to be modified as it has to raise InvalidChar event whenever it encounters invalid character. So modified code is shown in listing.

Private Sub txtNumber_KeyPress(KeyAscii As Integer)
' ignore nondigits
If KeyAscii < 48 Or KeyAscii > 57 Then
' if key is not tab key
If KeyAscii <> 8 Then
KeyAscii = 0 'ignore
RaiseEvent InvalidChar(KeyAscii)
End If
End If
End Sub
Listing 27.6: Code for KeyPress event of the textbox.

3. Now save the project and recreate .OCX file.
4. Close NumberCtrl project and open tstNumctrl project.
At the time of opening Visual Basic detects that Number control was modified and a new version was created. So it displays a message box informing that the control will be upgraded to new one.

Click on Ok to use upgraded control.

To test InvalidChar event and clear method, add a label control to display the most recently entered invalid characters and a command button to clear the value from number control.

Visual Basic informing user that ActiveX control will be upgraded to next release.

Change properties of all the controls that are added.

Control Property Value
Command button Name CmdClear
Caption &Clear
Label Name Lblchar
Caption “ “
BorderStyle 1-fixed Single
BackColor White (&H8000000E&)
Label Caption Recent Invalid Character


Write the following code for click event of clear button and InvalidChar event of Number1.

Private Sub cmdClear_Click()
Number1.Clear
Number1.SetFocus
End Sub

Private Sub Number1_InvalidChar(ch As Integer)
lblchar.Caption = Chr$(ch)
End Sub
Listing 27.7: Code in testing form.
Run the project and enter 1583 followd by J. As J is not a valid character for Number control, Number control fires InvalidChar event and passes the Ascii code of the character as the parameter. We used InvalidChar event of Number1 control and placed the character form of the Ascii code into label.


Testing MaxLength Property
Now let us test maxlength property of the control by following the steps given below.

1. Invoke properties window of Number1 control and change MaxLength property to 10.
2 .Run the testing project and see whether you can enter more than 10 digits.

Shocked…

Oh, it does not work. You are able to enter as many digits as you want. But if we set MaxLength property to 10, it indirectly set MaxLength property of text box to 10. Does it mean MaxLength property of text box is not working. I suggest before you come to any conclusion, try the following with Value property.

1. Invoke properties window of Number1 control and change Value property to 100.
2. When you dismiss Properties window, you see 100 in the control. That’s OK.
3. Run the testing project and see what you have in Number control.

Shocked… again.

Don’t worry. We will see later what is happening. For now all that I can say is, it is a very important part of ActiveX controls. We will understand more about it later in this chapter. For the time being it is a mystery.

Adding MinLength property and LengthError event
MinLength property specifies the minimum number of digits to be entered by user. It is set to 0 by default. If user doesn't enter given number of digits then LengthError event is fired and focus remains in the control.

Open NumberCtrl project. If it is not already open and take the following steps:

To add MinLength property:

1. Get into code window of UserControl.
2. Select Tools ->Add Procedure and enter MinLength as name.
3. Select Property radio button from Type group.
4. Click on ok

To add LengthError Event

1. Select Tools-> Add Procedure option.
2. Enter LengthError as name and select Event option in Type group.

Visual Basic places a single statement in general/declarations as follows.

Public Event LengthError()

Property Let and Property Get procedures are created for MinLength Property name is part of the interface of the control. But MinLength is not a variable. It can only interact but cannot store the value. So declare a variable vMinLength and store minimum length in that variable. When it comes to accessing minimum length, we use MinLength property but the value is actually stored in vMinLenth variable. Here are the changes to be made to the existing code.

General / Declarations

Private vMinLength As Integer

Public Property Get MinLength() As Variant
MinLength = vMinLength
End Property

Public Property Let MinLength(ByVal vNewValue As Variant)
vMinLength = vNewValue

End Property
Listing 27.7: Code for MinLength property

We use LostFocus event of txtNumber text box to check whether user has entered the required number of digits. Here is the code for LostFocus event.


Private Sub txtNumber_LostFocus()
' check whether MinLength number of digits are given
If Len(txtNumber.Text) < MinLength Then
RaiseEvent LengthError
txtNumber.SetFocus
End If
End Sub
Listing 27.8: Checking for Minimum Number of digits.

Property Persistency
Recollect the problem with MaxLength and Value properties of Number control. When we set Value property to 100 in design mode, that value was not available at runtime. The same was the problem with MaxLength. And, in fact, that will be the problem with all properties of the ActiveX control. Before we try to solve the problem, let us try to understand the reason for the problem.

ActiveX controls always run, when you place an ActiveX control on a form, even in design mode the ActiveX control runs. Actually an instance of ActiveX control is placed on the form and it is in run mode even when Form is in design mode.

When you place an ActiveX control on the form, an instance of ActiveX control is created and placed on the form. When you are moving from design mode to run mode by running Visual Basic project, the instance of ActiveX control that was placed in design mode is destroyed and a new instance of the ActiveX control is created at runtime. That means all the property settings that you have in design mode are gone as the instance itself is destroyed. When a new instance is created at runtime, it has all the properties reset to default values.

That means the property settings do not have any persistency. Properties lose their values when they move from design mode to run mode. And also when you save and reopen the project and so on.

We can achieve property persistence by storing the property setting before the instance is destroyed and retrieve the setting when a new instance is created. This is what is called as property persistence. So we achieved property persistence by writing the values of properties to disk and then reading them back when they are required.

WriteProperties Event
This event of UserControl object occurs whenever a controls property settings are to be saved. For example, when you are moving from design mode to run mode, as the settings of properties are to be saved, WriteProperties event occurs.

WriteProperties event is used to:

Write setting of properties into Propety Bag (PropBag) object using WriteProperty Method.

WriteProperties event doesn’t occurs in the following cases:

When Visual Basic believes no property values have changed.
When switching from run mode to design mode.

ReadProperties Event
This event occurs whenever the control is created except for the very first time. ReadProperties event is used to read the setting of properties that were written using WriteProperties event. The following are the steps to be taken in this event:

Read the values of properties from Property Bag (PropBag) object.

InitProperties Event
This event occurs when control is created for the very first time. For example, when you drag and drop a control on the form.

Use this event to set initial values to properties and perform any other operations that you want to perform only for once in the life time of the control.

PropertyChanged Method
PropetyChanged method is used to mark a property as changed. Only those properties that are marked as changed will be written by Visual Basic into property bag (PropBag) object during WriteProperties event.

This method takes the name of the property that has been changed as the parameter and notifies Visual Basic that the property has changed.

The following is the syntax of PropertyChanged method.

PropertyChanged propertyname

This method is used for the following reasons:

• To notify Visual Basic which properties need to be written to PropBag when project is saved or when switching from design mode to run mode.
• To update the value of the property when the property is changed through property page in design mode.
• To update database when a data bound property is changed


Providing Object Persistency to Number control
Now let us put what we have understood to practice. As you know we have not taken care of property persistence in Number control. Now let us add code for the above mentioned event to provide object persistence. Actually ActiveX Control Interface Wizard automatically writes code for these events. We will use it in the next chapter, but for the time being let us add the following code for Number control normally.

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
Value = PropBag.ReadProperty("Value", 0)
MinLength = PropBag.ReadProperty("MinLength", 0)
MaxLength = PropBag.ReadProperty("MaxLength", 0)
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
PropBag.WriteProperty "Value", Value, 0
PropBag.WriteProperty "MinLength", MinLength, 0
PropBag.WriteProperty "MaxLength", MaxLength, 0
End Sub
Listing 27.9: Code to write and read properties to and from property bag.

Test run
1. Open the text project and do the following.
Now invoke properties window and change Value property to 100 and MaxLength property to 10.
2. Run the project using F5.
You should see value 100 in Number control at runtime. And you should not be able to enter more than 10 digits. That means whatever settings you have at design mode those settings are available even in run mode.
The following is the sequence of events that made the property persistence possible:

• When project is switching from design mode to run mode, WriteProperties event occurs.
• WriteProperty method of PropBag object writes the current values of properties into PropBag object.
• Then control's instance in design mode is removed.
• Project has entered into run mode.
• A new instance of control is created and placed on the form.
• ReadProperties event occurs.
• ReadProperty method of PropBag object is used to read the values of properties from PropBag and assign those values to properties.
Now let us understand what are the events that occur in various scenarios related to property persistence.

Scenario #1, creating a new control
Whenever you create a new instance of an ActiveX control by placing the control on the form, the following event of ActiveX control occur in the given order.

• Initialize • InitProperties • Resize • Paint
Scenario #2, Switching from Design mode to Run mode
The following events of ActiveX control occurs whenever you switch from design mode to run mode in Visual Basic IDE.

• WriteProperties • Terminate • Initialize
• ReadProperties • Resize • Paint

Scenario #3, Switching from Run mode to design mode
The following events of ActiveX control occurs whenever you switch from run mode to design mode in Visual Basic IDE.

• Terminate • Initialize • ReadProperties
• Resize • Paint

Scenario #4, saving the project
The following events occur when you save project in VB IDE.

• WriteProperties • Terminate

Scenario #5, Project is opened into Visual Basic IDE
The following events occur when you open project in VB IDE

• Initialize • ReadProperties • Resize
• Paint • WriteProperties

Note: WriteProperties event occurs when you open the project because Visual Basic has to write the properties read using ReadProperties to in-memory copy of .frm file.

Properties persistence is very important part of ActiveX control. You need to maintain values for properties across control instance.

ActiveX EXE

In this chapter let us create an ActiveX EXE, which is also called as out-of-process server. One of the major advantages of the out-of-process server is, it can be run on a different machine from client machine and thus enabling you to develop Application Server in 3-tier client/server architecture. ActiveX Exe could also be run as a separate program. It is suitable for cases where you need to create an application that may be invoked as a standalone application or as a server. When it is invoked as a standalone application then users can interact with the application.
To get a feel of out-of-process server and how to use it in client application, let us create an out-of-process server that uses the Time class (created in the previous chapter), and testing application.
The ActiveX EXE that we are about to create contains the following features.

• It has a single class Time (taken as it is from previous chapter).
• A form that is displayed only when ActiveX EXE is invoked as a standalone application. The form is hidden when ActiveX EXE is invoked from a client application (used as a server).
• The form of ActiveX EXE is used to display running digital clock using Time class of the ActiveX EXE
• Client application as usual uses an object of Time class to invoke methods such as GetTime, SetTime etc.
• The startup object of ActiveX EXE is Sub Main, which is a procedure in code module. Main procedure determines whether form in server is to be displayed or not depending upon whether server is invoked as standalone application or invoked by client application.

Creating an ActiveX EXE
Let us start creating ActiveX EXE and its components like code module and form.

1. Create a new project using File -> New Project and select ActiveX EXE as project type.
2. Visual Basic creates a project with just one class module named Class1.
3. Invoke Project Properties and click on right button.
4. Select Add -> Class Module from popup menu.
5. In Add Class Module dialog select Existing tab and select TIME.CLS.
6. Click right button on Class1 and select Remove Class1 from popup menu. When you are prompted to save it, select No.
7. At this stage, we have only one class module (TIME) in our project.
8. Add a form using Project -> Add Form and select a simple form from Add Form dialog box.
9. Add a code module using Project -> Add Module and click on Open in Add Module dialog box.
10. At this stage, the project explorer .

11. Change the following properties of the project.

Project name AEXETIMESERVER
Project Description Time class in Out-of-process server by P.Srikanth.
Startup object Sub Main

12. Create a procedure with the name Main in code module and write the following code.

Public Sub Main()
If App.StartMode = vbSModeStandalone Then
frmTime.Show
End If
End Sub
Listing 26.1: Code for Main procedure of code module.

App object is one of the system objects. If StartMode property contains vbSmodeStandalone, it means ActiveX EXE is run as standalone program. The other option is vbSmodeAutomation.

13. Invoke Form designer and place a label and a timer control on the form.
14. Change the following properties of the form and controls.

Object Property Value
Form Name FrmTime
Caption ActiveX EXE Server
Label1 Name Lbltime
Caption 00:00:00
Autosize True
Fontsize 14
Borderstyle 1-Fixed Single
Timer1 Interval 1000


15. Write the following code for frmTime form.

General/Declarations
Dim t As New Time
Private Sub Form_Load()
Timer1_Timer
End Sub

Private Sub Timer1_Timer()
t.SetToCurrent
lblTime.Caption = t.GetTime
End Sub
Listing 26.2: Code in Form.

16. Save the project and its component under the following names (if you want you may give different names).
Project aexetimerserver.vbp
Form frmtime.frm
Module aexemodule.bas
Class Module aexetime.cls

Time class is taken from previous project. If we make any changes to time class and save them, the changes will be saved under Time.cls and this might effect the previous project (timerserer). So it is better we have a separate copy of Time class for the AEXETIMERSERER project.

To save time.cls under a different name:

1. Select Time class in project explorer and click on right mouse button.
2. Select Save Time.Cls As option from popup menu and enter AEXETIME as the name of the new file.
3. Time class is now stored under a new name - AEXETIME.CLS. It doesn’t effect TIME.CLS and previous project continues to use TIME.CLS.

Creating .EXE file

1. Select File menu and choose Make aexetimeserver.exe option.
2. Visual Basic creates aexetimeserver.exe in the specified directory and also registers it in system registry.
Running ActiveX Server as Standalone application

Let us run aexetimerserver.exe as a standalone application. In this case it should display frmTime, which contains running digital clock.

To run ActiveX exe server as standalone application:

1. Click on Start button on Taskbar
2. Select Run option from the start menu
3. Click on Browse button in Run window and select aexetimerserver.exe . (Your folder name may be different)
Running aexetimerserver.exe using Start->Run.

4. After selecting the file click on Ok to run the program.
5. A small window (frmTime) is displayed with running digital clock


Running client application
We use the same client program that we used for ActiveX DLL. But client application should have a reference to ActiveX EXE. So open client application (timetest.vbp) and follow the steps given below.

To create a reference to ActiveX EXE:

1. Select Project -> References
2. Uncheck Time class by P.Srikanth
3. Check Time class in Out-of-process server by P.Srikanth.
4. Click on Ok

Run client application by pressing F5. You should see the same screen as you have seen in the previous chapter and it also functions in the same manner. But one important difference is that now, Time class is in a separate process. And it could also be running on a separate machine altogether. If it runs on a different machine then you are accessing an object that is on a different machine and access to such object is handled by DCOM (distributed Component Object Model).

Another important point to be noted here is, when you are invoking ActiveX EXE from client application, frmTime is not displayed. But the application is loaded and Time class is provided to client application. Remember, we have checked for the startup mode and displyed frmTime form only when startup mode is standalone.

That is all you need to do to create an ActiveX EXE. The basic advantatge with ActiveX EXE is- it can run as a separate process. That could as well be on a seperate machine. So think of ActiveX EXE if they are the matters of concern. If you are looking for a collection of classes and no need to run them separately then implement the collection of classes as an ActiveX DLL. ActiveX DLL (in-process server) is much faster than ActiveX EXE (out-of-process server).

Instancing Property of Classes
The value of the Instancing property determines whether your class is private — that is, for use only within your component — or available for other applications.

As its name suggests, the Instancing property also determines how other applications create instances of the class. The property values have the following meanings.

Option Meaning
Private Means that other applications aren’t allowed access to type library information about the class, and cannot create instances of it. Private objects are only for use within your component.
PublicNotCreatable Means that other applications can use objects of this class only if your component creates the objects first. Other applications cannot use the CreateObject function or the New operator to create objects from the class.
MultiUse Allows other applications to create objects from the class. One instance of your component can provide any number of objects created in this fashion. An out-of-process component can supply multiple objects to multiple clients; an in-process component can supply multiple objects to the client and to any other components in its process.
GlobalMultiUse Is like MultiUse, with one addition: properties and methods of the class can be invoked as if they were simply global functions. It’s not necessary to explicitly create an instance of the class first, because one will automatically be created.
SingleUse Allows other applications to create objects from the class, but every object of this class that a client creates starts a new instance of your component. Not allowed in ActiveX DLL projects.
GlobalSingleUse Is like SingleUse, except that properties and methods of the class can be invoked as if they were simply global functions. Not allowed in ActiveX DLL projects.
Table 26.1: Options of Instancing property.

Class Modules and Project Types
The value of the Instancing property is restricted in certain project types. Allowed values are shown in the following table:

Instancing Value
ActiveX EXE ActiveX DLL
Private Yes Yes
PublicNotCreatable Yes Yes
MultiUse Yes Yes
GlobalMultiUse Yes Yes
SingleUse Yes
GlobalSingleUse Yes

Registration of ActiveX Components
Every ActiveX component is to be registered in Windows registry. Unless a component is registered, system has no way to get the required information about these components.

Visual Basic creates an entry in the registry for each component as and when component is compiled. But that is the case only with the system in which component is created. But as you can guess, you need to develop component only for once and then install it in other machines. When a component is loaded into another machine (different from development machine) you cannot access the components unless components are registered in windows system registry.

When you buy components, they come with an installation program, which takes care of installing and registering components in client’s machine.

Buf if you ever want to register an ActiveX component ,be it DLL or EXE or OCX, you can use REGSVR32 program available in windows\system folder.

To get help regarding REGSVR32.EXE, just enter REGSVR32 at system prompt after getting into WINDOWS\SYSTEM directory.

Syntax of RegSvr32, displayed by RegSvr32 when run without any parameters.

To register TIMERSERVER.DLL, enter:

1. Copy timerserver.dll into required directory. Let us assume the name of the directory is servers, which is in root directory of C drive.
2. Enter into windows\system directory. because regsvr32.exe resides in windows\system directory. and normally windows\system directory is not in the path. Otherwise you can invoke it from anywhere.
3. Invoke regsvr32 to register timerserver.dll as follows:
Regsvr32 c:\servers\timeserver.dll

4. If it is successful, you will see a window

Message displayed by RegSvr32 after a successful registration.

To Unregister TimerServer.dll:

If you ever decide to unregister timeserver.dll from registry, you can use regsvr32.exe with /u option to unregister the component.

Enter the following to unregister timeserver.dll.

Regsvr32 /u c:\servers\timeserver.dll

ActiveX

ActiveX technology was introduced in Visual Basic 5.0 for the first time. Since then it never looked back. I often hear people talking about ActiveX as some thing that is related to internet only. And some seem to think ActiveX as an advanced topic. In my sincere opinion, neither of them is true. Every Visual Basic programmer must understand what is ActiveX and how to create ActiveX components. So let us start our journey of ActiveX. But before we delve into ActiveX we need to understand the software architecture on which ActiveX is based – COM.
What is COM?
COM stands for Component Object Model. COM is software architecture that allows programmers to create components, which can be later used to build applications. The theme is reusability. To put it in other words, if you create a component using COM specifications, it can be used in any language and any platform where COM is supported.

COM is the underlying architecture that forms the foundation for higher-level software services, like those provided by OLE and ActiveX.

COM specifies the standards using which components are to be created. And the components created using COM specifications have the following characteristics:

They are platform independent. They are usable in Windows, Windows NT, Macintosh, and Unix. They are language independent. If you create a component in Visual Basic, later you can use that component in VC++, PowerBuilder or anywhere, where COM is supported.
They are also extensible.

COM is a general architecture for component software. Microsoft is using COM to address specific areas like creating controls, servers etc.

It is beyond the scope of this book to discuss about the specifications and internals of COM. There are so many technical articles in MSDN on COM and DCOM. Read them if you want to have an insight of COM.

What is ActiveX?
ActiveX is a new technology (actually a renamed technology). Its predecessor is OLE ; ActiveX allows you to create components based on COM specifications and enables you to develop interactive web pages.

ActiveX includes both client and server side technologies. That means it allows you to create components that run both on client and server.

An ActiveX component is a reusable piece of data and code (object) created using ActiveX technology. The best part of ActiveX is it allows you to create components that can be used in any project (irrespective of language) straight away. This saves a lot of development time. Well, if you boil it down, it comes to reusability, which is one of the characteristics of component software to which ActiveX belongs.

However, note that ActiveX talks about binary interoperability. That means only compiled components are reusable and NOT source code.



ActiveX Components
The components that you create using ActiveX technology are of different types. The following are the different types of ActiveX components.

ActiveX Applications (ActiveX .EXE)
An ActiveX application is a standalone application, such as MS-Word, MS-Excel etc. These applications provide objects that you can access and manipulate programmatically from an application written in Visual Basic or any application development tool that supports ActiveX.

Note: Each component has a collection of properties, methods and events that can be accessed from outside. These properties, methods and events are collectively called as interface of the component.

ActiveX Code Components (ActiveX .DLL)
ActiveX code component is a collection (library) of programmable objects, where objects are generally related to a specific topic such as, financial functions, date and time functions etc.

ActiveX code components do not run as separate applications, instead they are run in the same process area as the client (the application that is using the code component). More on this later in this chapter.

ActiveX Controls (.OCX controls)
ActiveX controls are user-defined controls. Formally they were called as OLE controls. Each ActiveX control does a specific job. For example, an ActiveX control may deal with displaying a calendar, another may deal with displaying running digital clock and so on. There are hundreds of ActiveX controls available from various vendors, whose primary job is creating ActiveX controls and sell them to developers.

Note that even Visual Basic 4.0 users could create OLE Server (now called as ActiveX Server) but creating an ActiveX control was introduced for the first time in Visual Basic 5.0. It really made Visual Basic programmers thrilled. Well, I am one of them and now you join the bandwagon.

In fact, we have already used good number of ActiveX controls, such as DataList, ADODC, DataGrid etc. We know how to use them but in the coming chapters 27, 28 & 29 we will learn how to create our own ActiveX controls.

ActiveX Document (. VBD Document)
ActiveX documents are Internet pages. You can use ActiveX documents to create interactive Internet application. Each ActiveX document is a Web page. An ActiveX document can host ActiveX controls and can invoke dialog boxes and so on.

Visual Basic 6.0 has introduced DHTML application. DHTML application provides better alternative to ActiveX document application.

In-process and Out-of-process servers
An ActiveX code component may be either in-process or out-of-process. In-process server is implemented as .DLL and out-of-process server is implemented as .EXE.

An application using ActiveX component interacts with it using Client/Server architecture. Application makes the request to the component and component responds to the request. Here client is the application that is using the services of the component. And the ActiveX component is the server. Depending upon where server runs, ActiveX components are classified into two types.

In-process server
An in-process server is an ActiveX .DLL. It runs in the address space of the client application. It cannot be run as a separate process. The communication between client (application) and server (code component) will be faster as both of them (client & server) reside in the same address space. And more importantly there is no context switch (switching from one process to another). An example for in-process server is ActiveX Data Objects library.



Out-of-process Server
An ActiveX code component that is implemented as .EXE is an out-of-process server. It runs in its own address space. When a client invokes a method of the server, control switches from client process to server process (context switch occurs). An out-of-process application can also be run as a standalone application.
Creating an ActiveX .DLL
An ActiveX DLL is a collection of object that can be used by client applications. Let us create a simple ActiveX code component that is implemented as in-process server (ActiveX .DLL).

We will create an ActiveX DLL with just one class. It is important to understand how to create a class when you are creating an ActiveX DLL, as ActiveX DLL is a collection of classes. A client application that is using this ActiveX DLL creates objects of the classes exposed by server and invokes methods and properties to get the job done.

Time Class
The ActiveX server that we are going to create contains only one class – Time class. The following is the list of properties, methods, and events of the class.

Type Name Meaning
Property Hour Sets/ returns the number of hours
Min Sets/ returns the number of minutes.
Second Sets/returns the number of minutes.
Method IncrementSecond Increments the time by one second.
SetToCurrent Sets the time to current system time.
GetTime Returns time of the class in HH: MM: SS format.
SetTime Takes time in HH: MM: SS format and changes time of the class to the given time.
Event InvalidTime Raised whenever Hour, Min, or Second property is set to an invalid value.
Table 25.1: Members of Time class.

The following are the major steps in creating an ActiveX DLL

• Create a project of ActiveX DLL type
• Create as many class modules as required.
• Change properties of project
• Create .DLL file

To creating an ActiveX DLL project:

1. Select File -> New Project and select ActiveX DLL as the type of the project.
2. Visual Basic creates a new project with a single class module with Class1 and change the name to time.
Using Class Builder utility
Class builder utility could be used to create skeleton for methods, properties and events. Let us use class builder utility to create attributes of Time class.

To invoke Class Builder Utility:

1. Select Add-In Manager option of Add-Ins Menu.
2. In Add-In Manager window double click on VB 6 Class Builder Utility
3. Then message Loaded appears under Load Behavior column.
4. Click on Ok.
5. Select Add-Ins menu and choose Class Builder Utility to invoke Class Builder.
6. If Class Builder displays a warning message, just ignore it and continue.

Renaming Class1 to Time

1. Select Class1 in Classes Pane of Class Builder Utility and click on right button.
2. Select Rename option and rename Class1 to Time.

Creating properties, methods and events using Class Builder

1. Click right button on Time class
2. Select New-> Property option from popup menu.
3. Enter the name of the property as hour and change data type to Integer.
4. In declaration group leave the Public Property radio button selected.
5. And click on Ok
At this stage class builder displays a property in the left pane.
6. Repeat the process for Min and Second properties.
7. Click right button on Time class and select New->Method from popup menu.
8. Enter IncrementSecond as the name of the method.
9. Select Attributes table and enter “Increment time by one second” as the description. Whatever description you enter here will be displayed in Object Browser when you select this method.
10. Click on Ok
11. Repeat the same process for SetToCurrent method. Enter “Sets time to current system time” as the description.
12. Again select New->Method from popup menu and enter SetTime as the name of the method and “Changes the time to the given time. Time must be given in HH: MM: SS format” as description.
13. Then click on + sign on the right of Arguments list box and enter the following details .
Name NewTime
Type String
ByVal Checked

Note: if optional checkbox is checked then the argument is optional. If no value is passed to the argument then the given default value will be stored in that.

14. Create one more method with the name GetTime and specify the Return Data Type as String.
15. Select New->Event from popup menu of Time class
16. Enter InvalidTime as the name of the event and “Fired when an given hour, min or second is invalid” as the description
At the end of creation of methods, properties and events, the class builder should look like .

Note: You can add property, method and event using icons in toolbar also.

Note: Select tab “All” if you want to see all the attributes of the class. Otherwise select one of the three tabs (Properties, Methods, and Events) to display the specific members.

To update project with changes made in class builder:

1. Select File-> Update Project option. Class builder updates the class module with the details furnished so far.
2. Exit Class builder with File-> Exit.

If you open Time class module, the code contains three properties, two methods and one event. The code is shown in listing 25.1.

'local variable(s) to hold property value(s)
Private mvarMin As Integer 'local copy
Private mvarSecond As Integer 'local copy
Private mvarHour As Integer 'local copy
'To fire this event, use RaiseEvent with the following syntax:
'RaiseEvent InvalidTime[(arg1, arg2, ... , argn)]
Public Event InvalidTime()

Public Sub SetToCurrent()
End Sub

Public Sub IncrementSecond()
End Sub

Public Property Let Hour(ByVal vData As Integer)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Hour = 5
mvarHour = vData
End Property

Public Property Get Hour() As Integer
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Hour
Hour = mvarHour
End Property

Public Property Let Second(ByVal vData As Integer)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Second = 5
mvarSecond = vData
End Property

Public Property Get Second() As Integer
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Second
Second = mvarSecond
End Property

Public Property Let Min(ByVal vData As Integer)
'used when assigning a value to the property, on the left side of an assignment.
'Syntax: X.Min = 5
mvarMin = vData
End Property

Public Property Get Min() As Integer
'used when retrieving value of a property, on the right side of an assignment.
'Syntax: Debug.Print X.Min
Min = mvarMin
End Property

Public Function GetTime() As String
End Function

Public Sub SetTime(ByVal newtime As String)
End Sub
Listing 25.1: Code written by Class Builder
Modifying the code written by Class Builder
Class Builder utility just creates skeleton for methods. We have to insert the code to make method operational.

GetTime Method
This method is used to return the time in HH:MM:SS format. Format function is used to get leading zero for hour, minute and second. Format function takes a values and the format using which the value is to be formatted and returns the formatted values in the form of a string. For complete details of format function, please see on-line help.

Public Function GetTime() As String
Dim s As String
' Return time in HH:MM:SS format
s =Format(Hour,"00")& ":" & Format(Min, "00")& ":" _
& Format(Second, "00")
GetTime = s

End Function
Listing 25.2: GetTime Function.

SetTime Method
Takes time in HH: MM: SS format, breaks it into hours, minutes and seconds and places them into member variables. It checks whether three values are valid. If they are not valid it raises InvalidTime event.

Public Sub SetTime(ByVal newtime As String)
Dim h As Integer
Dim m As Integer
Dim s As Integer

' input must be in HH:MM:SS format
' if values are invalid then raise INVALIDTIME event
h = CInt(Mid(newtime, 1, 2))
m = CInt(Mid(newtime, 4, 2))
s = CInt(Mid(newtime, 7, 2))
If h >= 0 And h <= 23 And m >= 0 And m <= 59 And s >= 0 And s <= 59 Then mvarHour = h mvarMin = m mvarSecond = s Else RaiseEvent InvalidTime End If End Sub Listing 25.3: SetTime method. IncrementSecond Method This method is used to increment seconds by one. If incrementing the second causes second to exceed 59 then second is set to 0 and minute is incremented by one. And so on. Public Sub IncrementSecond() ' increment second by one mvarSecond = mvarSecond + 1 If mvarSecond > 59 Then
mvarSecond = 0
mvarMin = mvarMin + 1
If mvarMin > 59 Then
mvarMin = 0
mvarHour = mvarHour + 1
If mvarHour > 23 Then
mvarHour = 0
End If
End If
End If
End Sub
Listing 25.4: IncrementSecond method.

SetToCurrent method
This is used to change time to current system time. I have used methods of DataTime object and Time function to get current hour, minute and second.

Public Sub SetToCurrent()
' change time to current system time
mvarHour = DateTime.Hour(Time)
mvarMin = DateTime.Minute(Time)
mvarSecond = DateTime.Second(Time)
End Sub
Listing 25.5: SetToCurrent method.

Property Procedures
The following are the property procedures required for Hour, Min and Second properties. In all three, if the value is assigned is not valid the InvalidTime event is raised.

Public Property Let Hour(ByVal vData As Integer)
If vData >= 0 And vdate <= 23 Then mvarHour = vData Else RaiseEvent InvalidTime End If End Property Public Property Get Hour() As Integer Hour = mvarHour End Property Public Property Let Second(ByVal vData As Integer) If vData >= 0 And vData <= 59 Then mvarSecond = vData Else RaiseEvent InvalidTime End If End Property Public Property Get Second() As Integer Second = mvarSecond End Property Public Property Let Min(ByVal vData As Integer) If vData >= 0 And vData <= 59 Then mvarMin = vData Else RaiseEvent InvalidTime End If End Property Public Property Get Min() As Integer Min = mvarMin End Property Listing 25.6: Property procedures. That is about the coding part of the class. Out ActiveX server is almost ready. Generally an ActiveX server contains more than one class. But as we are primarily interested in understanding the concept through an example, one class is quite adequate in our sample ActiveX server. Save class as name Time.Cls and project as TimeProject.VBP. Changing properties of ActiveX Server Invoke Project properties to change the properties of ActiveX server. Here are the steps to change properties. 1. Select Project -> Project Properties to invoke properties window of the current project.
2. Change Project Name to TimeServer
3. Change Project Description to “Time Class By P.Srikanth”.
4. And click on Ok.

Creating .DLL file
Now the final step. We have to create .DLL file for the project. This DLL file is used by the client application. At the time of creating .DLL file Visual Basic registers this ActiveX server in system register.

Note: All ActiveX components must be registered in the system registry. Otherwise they cannot be used in client application.

To create .DLL file:

1. Select File menu and choose Make TimeProject.dll option.
2. When you are prompted to specify the directory and the name of the file, select the directory in to which you want to place .DLL file and leave the filename to default (TimeProject).
3. Click on Ok to create .DLL file.

That is the end of creation of ActiveX in-process server. In the next section, we will see how to use this server in a client application.

Using ActiveX Server
Let us create a small project to understand how to use an ActiveX in-process server. The project type is Standard .EXE type and it contains only one form. for the user interface of the form.

Here are the steps to create testing project.

1. Start a new project using File -> New Project and select Standard Exe as the project type.
2. Invoke Form designer and place two labels and four command buttons .
3. Change the properties of the controls and form as follows.

Object Property Value
Form Caption Time Class Demo
Label1 Caption Time
Label2 Name LblTime
Caption 00:00:00
Fontsize 16
Autosize True
Borderstyle 1-Fixed Single
Command1 Name CmdSetToCurrent
Caption &Set To Current Time
Command2 Name CmdIncrement
Caption &Increment Second
Command3 Name CmdChangeTime
Caption &Change Time
Command4 Name CmdQuit
Caption &Quit

Now we need to use ActiveX server. But to use an ActiveX server, first we have to have a reference to ActiveX server in the current project.

Creating a reference to ActiveX server
Unless you create a reference to ActiveX server (or any ActiveX component), you cannot access ActiveX server. So, the first step in using an ActiveX server is creating a reference as follows:

1. Select Project - > References
Visual Basic displays the list of ActiveX servers that are registered in the system registry .
2. Search for “Time Class By P.Srikanth”. Because whatever we give as project description in ActiveX server project, that will be displayed in References window.
3. Once you locate it, check the check box on the left. Also observe that the complete path of .DLL file is placed at the bottom of the window .
4. After turning on the check box click on Ok to close References window.
Save the project as TimeTest.Vbp and form as TimeTest.Frm.

Writing code for Sample project
We have to first declare an object of Time class with WithEvents keyword. Write code for InvalidTime event of the object. And then write code for command buttons. The total code for the sample project is shown in listing 25.7.

General/Declarations

Option Explicit
'declare an object of TIME class
Dim WithEvents t As Time

Private Sub cmdChange_Click()

Dim ts As String
' take time using inputbox
ts = InputBox("Enter time in HH:MM:SS format", "Time")
If ts <> "" Then
t.SetTime ts
lbltime.Caption = t.GetTime
End If

End Sub

Private Sub cmdquit_Click()
Unload Me
End Sub

Private Sub cmdSetToCurrent_Click()
t.SetToCurrent
lbltime.Caption = t.GetTime
End Sub

Private Sub CmdIncrement_Click()
t.IncrementSecond
lbltime.Caption = t.GetTime()

End Sub

Private Sub Form_Load()
Set t = New Time
t.SetToCurrent
lbltime.Caption = t.GetTime
End Sub

Private Sub t_InvalidTime()
MsgBox "Invalid Time"
End Sub
Listing 25.7: Code for event in the form.

Test Run

1. Now run the project. As in Form_Load event Time object is set to system time, you should see the system time as soon as the project starts.
2. After some time again click on Set To Current Time command button. The time should be updated to the current system time.
3. Click on Change Time command button and enter 10:10:58 as new type. This will change the time and new time is displayed.
4. Clicking on Increment Second button should make it 10:10:59. Again clicking on it should make it 10:11:00.
5. Now again choose Change Time and enter 30:20:02 as the time. As hour portion is not valid, SetTime method of the Time class fires InvalidTime event. And you should see “Invalid Time” message in message box.

That’s all that you have to do to test whether it is working in the way you want. If you found any mistakes in Time class then open ActiveX server project, make modifications and then recreate .DLL file.