Building Our First Component
Earlier, we visited our first example of using an ASP component—the
BrickCalc component—and we promised that we'd return to see
how to build the component. The Brick Calculator component is a
Windows Script Component (WSC), written using the Windows Script
Component Wizard and Notepad. WSCs are an ideal way to prototype
components, allowing us to write the components using VBScript
or JScript, which means that they can be written in a matter of
minutes.
If this is the first time you've heard of WSCs, then you
might be asking yourself the same sorts of questions I asked
myself when I first heard about them. For example, we've already
said that a COM object is a binary file—so how does WSC create
a COM object using VBSscript or JScript? Moreover, how will we
deal with registration and getting a CLSID? How do we get an
interface to work with?
A Similar Case
WSCs work in a very similar way to the OLE DB simple providers
in Visual Basic. An OLE DB simple provider is a two-tiered
component made up of your simple Visual Basic (or C++ or J++ ,
for example) code and a DLL. The DLL processes the code you've
written, and exposes a regular OLE DB programming interface to
its consumers.
WSCs (previously known as Scriptlets) work in much the same
way. Whenever we register a script-based COM object, the
registry entry points to a COM-compliant executable called
scrobj.dll. Furthermore, any script-based COM object has an
extra key in the registry, which points to a script file. This
file contains metadata, which defines both the executable code
and the interfaces to be made externally available.
Without further ado, let's build our first component for use
in ASP. In order to build the component, you'll need to download
the WSC kit from http://msdn.microsoft.com/scripting. You'll
need to download both the Windows Script Components (Windows
Script Version 5) and the Windows Script Component Wizard—both
of which are available at this site.
Planning the Brick Calculator Component
The Brick Calculator component has just one task to perform—calculating
the number of bricks needed to build a wall. So, the component
will implement one method called HowManyBricks(). Knowing that
we only need one method to perform the required task, we need
think about what information we should to supply the method, in
the form of parameters, to perform the calculation.
If we were approaching this methodically in the real world,
we could work out the size of the wall, check the size of the
brick, and then divide the size of the wall by the size of the
brick to find out how many bricks we need. To perform this
calculation we'd need to know four things
q The length of the wall
q The height of the wall
q The length of the bricks used
q The height of the bricks used
We are defining one property of the component, BrickType,
which will tell the component the type of brick we are using—breezeblock
or house brick. This covers the length and the height of the
bricks, which are hard coded into the component. We are then
left with the length and height of the wall, which we will pass
to our component as parameters to the method. Our method now
looks like this:
HowManyBricks(WallHeight, WallLength)
And that's all the information we need to create the shell of
the component using the Windows Script Component Wizard—to
which we will later add the functionality using script.
Using The Windows Script Component Wizard
This Wizard is made available from the Programs | Microsoft
Windows Script option on the Start menu. When you start it up,
you should get the following:
In this screen we've already added a Name for the component
we are creating—BrickCalc. As you type in the name of the
component, you'll see that the Filename and ProgID are provided
for us automatically. We can also provide a Version number and a
Location for the component. Having named the component, click on
Next, which takes you to the screen where you can provide the
characteristics of the component.
The first option in Screen 2 allows you to specify the script
language that you want to use to write the component. We have
chosen VBScript. The next option allows you to use the scriptlet
with DHTML behaviors (which we do not want to do), or add in
support for Active Server Pages. The support for ASP option
allows us to access the intrinsic ASP objects from our
component. This is not necessary for this component, so you can
uncheck the checkbox. The final option is to support Error
Checking and Debugging. If you are only prototyping your
component, it is helpful to have these options checked—because
they provide helpful information if you have not implemented
your component correctly. Once you have selected the options
that you want, click Next.
In Screen 3 we enter the properties for our component.
Remember that our component only has one property, BrickType,
which tells the component whether it needs to calculate the
number of breeze blocks or normal house bricks needed. We set
this to Write-Only because we only need to retrieve the value
from our ASP page, and we have set a default of BreezeBlock
(although we don't actually need to set a default). Then we
click Next to define our methods.
Again, we only have one method: HowManyBricks(). This takes
two parameters—WallLength and WallHeight—which the user
submits from the form.
When you've completed this hit Next to take you to Screen 5,
which handles the events in our component. We're not going to
use any events, so hit Next again for Screen 6
The final screen gives us a summary of the component we are
about to create. If we need to change anything we can use the
Back button. Otherwise, we just click the finish button.
And that should create the .wsc file. This file currently
defines the interface of the component; we can now add our
script, which will provide the implementation.
The XML File Created by the Wizard
Let's look at the XML file that our component has created (just
navigate to the file in Windows Explorer and double-click).
Don't worry if you do not understand XML—this will actually
show you just how easy the basics of XML are. As you will see,
XML looks very similar to HTML.
We start off on the first line with the XML declaration,
which any XML file uses. This is followed by a root tag,
<component>, which surrounds the whole component. Then we
have a processing instruction (in the tag that starts and ends
with question marks) to say that we are supporting error
handling and debugging (remember we checked tick boxes for these
in the second screen of the Wizard):
<?xml version="1.0"?>
<component>
<?component error="true"
debug="true"?>
...
Next we have the registration details, which include a
description of the component, a ProgID, the version number and
the CLSID. Note the simplicity of the XML tags that actually
describe their contents:
...
<registration
description="BrickCalc"
progid="BrickCalc.WSC"
version="1.00"
classid="{f954a720-67c1-11d3-99b1-00104b4c84a4}"
>
</registration>
...
Next we have the properties and methods that the component
will expose, nested inside the <public> tags, held in tags
that say <property> and <method>:
...
<public>
<property name="BrickType">
<put/>
</property>
<method name="HowManyBricks">
<PARAMETER name="WallLength"/>
<PARAMETER name="WallHeight"/>
</method>
</public>
...
Finally we have the block, which will contain the script code
that adds the functionality of the component. (And a closing
</component> tag.) At the moment it is like an interface
without any implementation.
...
<script language="VBScript">
<![CDATA[
dim BrickType
BrickType = "BreezeBlock"
function put_BrickType(newValue)
BrickType = newValue
end function
function HowManyBricks(WallLength, WallHeight)
HowManyBricks = "Temporary Value"
end function
]]>
</script>
</component>
Now we have to add in the functionality, using a simple bit
of VBScript (note that we have hard-coded values for the size of
the bricks):
function HowManyBricks(WallLength, WallHeight)
If BrickType = "BreezeBlock" Then
TheResult = Int(WallLength / 0.75) + 1
Result = TheResult * (Int(WallHeight / 0.33) + 1)
HowManyBricks = Result
Else
TheResult = Int(WallLength / 0.35) + 1
Result = TheResult * (Int(WallHeight / 0.15) + 1)
HowManyBricks = Result
End If
end function
Once you've done that, save the file—and now we are ready
to register our component.
Registering the File
Windows Script Components are very easy to register, as the WSC
kit adds options to Register, Unregister, and Generate TypeLib
(type library) for a component when you right click on it in
Windows Explorer. Don't worry about the type library option for
the moment; we'll talk about type libraries later in the book.
We should be notified that our component registered
successfully. This uses the regsvr32.exe program to add the
necessary references to the registry, including the extra key
that points to scrobj.dll.
And that's it—we have created our first COM component. To
check that it works, try your own version with the ASP pages
provided in the WroxBloxForm.asp/WroxBloxResult.asp example,
which are available with all the rest of the code for the book
from http://webdev.wrox.co.uk/books/2882/.
WSCs offer far greater functionality than is described here.
They have evolved very quickly, and the best way to keep up with
them is to check out http://msdn.microsoft.com/scripting/ where
there are full tutorials and more examples.