Вы находитесь на странице: 1из 39

ActiveX Control Tutorial

Pa r t 1

Introduction
Good Morning and welcome to the first instalment in this ActiveX control tutorial.
Today, we'll be:
• Getting the low-down on ActiveX components
• Finding out the difference between ActiveX components and ActiveX controls
• Discussing a few nerdy things (too boring to mention)
• And…. <drum roll> … we'll be creating our own ActiveX control!
I know you're excited – but please, hold it in.
So without further ado, let's tootle off into the magical realms of ActiveX...
What's an ActiveX Control?
What's the difference between a horse trainer and a tailor? One tends a mare and one
mends a tear!
And now for another belly-chuckler - what's the difference between an ActiveX
component and an ActiveX control?
OK, not quite a dinner party puzzler but still an important point. Let's take a look at what
exactly an ActiveX component is... and is not.
An ActiveX component is just a general term, encompassing:
• An ActiveX EXE
• An ActiveX DLL
• An ActiveX Control
An ActiveX component is not:
• Active, in any way, shape or form
• A source of fibre that can help you lose weight as part of a calorie controlled diet
So what exactly are ActiveX EXEs and DLLs? Basically, they're chunks of code you use
in your Visual Basic projects just by setting a reference to them – a little like how you set
a reference to DAO or ADO when you need access to a database.
But that's another department completely... more to the point, just what are ActiveX
controls?
Well, you might not know this, but you already have experience of ActiveX controls.
You've used them, tweaked them and tossed them to one side – all in the course of a days
work. Ohhhh yes.
Indeed, every time you set the Text property of a Text Box, you're utilising an ActiveX
control. Every time you respond to the Click event of a Command Button, you're utilising
an ActiveX control. Every time you run the MoveNext method of the Data control, you're
utilising an ActiveX control.
I think you get the picture. In essence, an ActiveX control is anything you might see in the
Toolbox.
Top Tip: Don't forget that you can also add more controls to the Toolbox by selecting
Projects, Components
Err, so what?

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


But how can all this background information help in everyday programming life?
Well, with the advent of Visual Basic 5 and, more recently Visual Basic 6, supercool
geeky-types have been able to create their very own ActiveX controls.
So perhaps you could create your own groovy text box control that only allows the user
to input numbers. Or perhaps just text. Or perhaps text and numbers, but no spaces.
Maybe you'd like to create a company-wide Exit button that flashes every time you hover
your mouse over it. Sure, it might be about as useful as a pencil sharpener in the bullring,
but it'd look good.
Other slightly more practical uses include creating a standardised Save dialog box. Or a
lighter-weight version of the MSChart control. Or a plain but simple replacement for the
InputBox() function. Or perhaps an intelligent scrollable window that displays a picture
you pass it. Or a new and improved combo box. Or maybe just something else.
Then, when you need to use that groovy flashing Exit button, you simply draw it onto
your form, just as you would any standard control. You could then set its
MyControl.Forecolor property, and perhaps respond to its MyControl_Click event by
adding a bit of code. You could even execute one of its' methods every now and then,
such as MyControl.FlashAnimation.
The difference here is that you, as a productive, presentable, professional, pragmatic
programmer, created the control. And as such, you dictate when the MyControl_Click
event fires. Or how the MyControl.FlashAnimation method works. Or in which way the
MyControl.ForeColor property is implemented – is the user presented with a text list of
just four colours or the standard colour selection panel?
We'll be covering all this and more in this series. But for now, let's jump in at the deep end
and knock out our very first ActiveX control!
The Power of Controls
Now, brace yourself as we prepare to create our own ActiveX control.
We're going to create a little option button that flashes a few times when you run a certain
method. It's not overly useful, but could help grab a user's attention.
• Start Visual Basic
• Create a New 'ActiveX Control' project
A grey box should appear on your screen. This is your workspace – it's basically a form
without a border, caption or minimize/maximise/close buttons.
And that makes sense, after all when did you last use a control that has its own close
button?
First off, let's rename our ActiveX control:
• Change the Name property of UserControl1 to 'Flasher'
• Now change the Name property of Project1 to 'Animation'
Excellent! Now...
• Double-click on the Option Button control in the toolbox
• Remove the Caption property of the Option Button
• Change its Name property to 'optFlasher'
We've just added an Option Button to the workspace. Now let's add the Timer control:
• Double-click on the Timer control
• Change its Name property to 'tmrAnimation'

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


That's great. Now I want you to resize a few of the things on your screen. We'll be doing
all this resizing in code later on, but for now:
• Move the Option Button to the very top left, so it just touches the corner edges of
your workspace – like this:

• Now resize the workspace so it just touches the bottom edges of your Option
Button – like this:

Now the stuff you currently see in your workspace will become your 'control', the thing
your user sees when adding it to their forms.
Hmm, it's about time we added some code. Not much, just a lil'.
• Enter the code window by selecting View, Code
• Type in the following code:
Public Sub Flash()
tmrAnimation.Interval = 300
End Sub
This just sets the Interval property of tmrAnimation to around a third-of-a-second (300
milliseconds). When the Timer springs into action every 300-milliseconds, it fires its Timer
event.
So let's add code to that...
• In the Object drop-down list (which currently says General), select 'tmrAnimation'
• The Procedure drop-down list next to it should say 'Timer' – if not, select the
'Timer' event from the list
Your screen should look a little like this at the moment:

• Tap in the following code:


Static NoOfFlashes As Integer
'This is just a variable that holds
'a number - the 'Static' prefix just
'means it doesn't forget its value
'when this procedure is over...

optFlasher.Value = Not (optFlasher.Value)


'Sets the value of our Option Button
'to the opposite of its current value...
'so if it's "on", it'll be turned off -
'and vice versa

NoOfFlashes = NoOfFlashes + 1
'Increment the variable to show number
'of times we have "flashed"

If NoOfFlashes = 8 Then
'If we've had eight separate flashes so far

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


NoOfFlashes = 0
'Reset the NoOfFlashes...

tmrAnimation.Interval = 0
'... and turn off the timer

End If
That's it! You've completed the creation of your first ActiveX control.
Now let's put it to the test...
Testing our Control
Let's see what all that hard work has given us.
• Click File, Add Project
• Select 'Standard EXE' and click Open
Now we have two different projects open at the same time; our control and this new
Standard EXE thing we've just created.
Let's add our new control to the Standard EXE now.
• Drag out the Flasher control ( ) on your toolbar onto Form1, like this:

Top Tip: If your Flasher control is greyed-out... it means your copy of Visual Basic has
been attacked by huge killer bees from the terrifying jungles of Outer Mongolia or you
haven't closed the workspace of your control. Hmm, probably the latter actually. Close
the workspace and try again!
See how your Option Button appears?
Look in the Properties window. Can you see all the Properties your control already has? A
Name property, TabIndex, ToolTipText... and more! These are all assigned by default.
Now...
• Add a Command Button to the form
• Place the following code behind it:
Flasher1.Flash
The method you've just tapped in is the one we coded!
When we added the 'Public Sub Flash' code, it's automatically turned into one heckuva
groovy method!
Try hitting F5 and running your application. Now hit the Command Button! See what
happens?
The Option Button should flash for a few seconds... great for highlighting a warning of
some sort. But not so great at anything else.
P a rt 2
Introduction
welcome to the second part in this cool ActiveX tutorial.
As ever, I'm your surprisingly sophisticated host Karl Moore – and this week we'll be
covering:
• Creating property procedures
• Enumeration (whoah!)
• Dealing with resizing

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


• Some other stuff
If you missed part one, it's probably a good idea to check it out before reading on - click
here!
I can see you're getting all giddy now, so let's don our anoraks and thick glasses as we hop
on the pink boat destined for the fluffy world of ActiveX controls...
[Ed: What?]
Size Matters
Today, we're going to start creating an advanced text box.
In just a few clicks of the mouse, we'll allow users of our control to dictate how the text
box works – perhaps it will restrict people to entering just numbers or mere text. This will
be done by setting properties.
We'll also make the text box automatically translate characters to upper case, lower case –
or any ol' case.
So let's get going...
• Start up Visual Basic
• Create a new 'ActiveX Control' project
• Add a text box to your workspace
For the moment, don't worry about sizing or positioning or whatever. These things do
matter – just ask my girlfriend – but we'll deal with them later.
• Rename the text box to 'txtTextBox'
• Remove 'Text1' from the Text property
We haven't really done much yet, but let's test it so far.
• Click File, Add Project
• Select 'Standard EXE'
• Add your 'UserControl1' control from the toolbox direct onto Form1

Notice how the text box inside our control doesn't automatically resize itself?
• Right click on 'Project2' in the Project Explorer and click Remove Project, not
saving any changes
The text box doesn't automatically resize because as of yet, we haven't told it to. Oh, and
'cause Visual Basic is about as smart as the winner of last year's "World's Scruffiest Bloke"
competition.
• Click View, Code to enter the code window
• Select UserControl from the Object drop-down box
Don't forget that the UserControl is just your control. When something happens to it,
certain events fire – such as Initialize, Resize, LostFocus and so on. It's the equivalent of
the Form object in regular programming, where you have events such as Load and
Unload.
• Select Resize from the Procedure drop-down box
• Add the following code to your project:
Private Sub UserControl_Resize()
With txtTextBox
.Height = UserControl.ScaleHeight
.Top = UserControl.ScaleTop

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


.Left = UserControl.ScaleLeft
.Width = UserControl.ScaleWidth
End With
End Sub
Here, we're resizing the dimensions of the text box depending on various properties of the
UserControl object.
The UserControl object is there to tell you how your user is playing with the control. So if
they resize it, the Resize event fires – and you grab the new ScaleHeight, etc. properties,
reorganising your controls as such.
In our project, we simply set the text box properties equal to the exact UserControl Scale
properties. Of course, if you had more than just one simple text box to resize – you'd have
to start with a few Einstein-like calculations – but for now, I'll spare you the pleasure.
Go ahead and test the control– just as we did earlier.
See what happens? Whenever the user resizes your control, the text box follows!
My test project looks like this:

Sure, it's about as stunning as Queen Elizabeth's bottom, but this is only the second
tutorial...
[Ed: So by the last instalment should we expect something akin to Pamela Anderson?]
Decisions, Decisions...
Now I want the person using this control to be able to decide whether the text box should
accept just letters, numbers or both – and whether letters entered should be converted to
upper or lower case.
So I've already determined two possible properties:
• AcceptType – should it hold just letters, numbers or both?
• ConvertCase – automatically convert to upper case, lower case or neither?
But how will the user tell me which they wish to use? I could perhaps tell them to set
AcceptType=1 if they wish to hold letters, 2 if they only require numbers and so on. Err,
but that ain't too user friendly. And you know how darn picky those users get.
This is where enumerations come into play. Yessiree, that's another geeky word designed
to scare off potential programmer types. But it's really very simple.
• Back in your project, open the code window
• Enter the General Declarations section

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


• Select (General) from the Object drop-down box and (Declarations) from the
Procedure drop-down box
• Type in the following code:
Public Enum CharacterType
All
Numbers
Letters
End Enum
Let me explain what's happening here; the first line simply tells Visual Basic we're creating
an enumeration christened CharacterType. The Public bit just ensures our end users can
see the enumeration.
The next three lines list our options – no spaces allowed. The user can select All, Numbers
or Letters.
Top Tip: You can also assign numbers to each of our options, so All might equal zero,
Numbers might equal one and so on. Lookup the 'Enum Statement' in Visual Basic help
for more information!
That final line of code simply states that the enumeration ends here.
So we've just defined the 'options' for our planned 'AcceptType' property. Now let's add
another enumeration for the 'CaseConvert' property.
• Type in the following code:
Public Enum CaseType
All
UpperCase
LowerCase
End Enum
Hmm, I guess you're not impressed – in fact, I saw more impression the last time I drop a
1st class stamp onto a freshly produced ingot of 22 carat gold. But you will be, as soon as
we get these things working.
Still, that's it for enumerations. Let's add a few properties!
It's a Two-Way Thing
You've played around with properties before. Every time you say...
Text1.Text = "Hello World!"
... you're setting a property. And every time you say...
MsgBox Text1.Text
... you're reading a property.
Because you're now a supercool ActiveX programmer, you're going to have to provide all
this functionality to your end user too.
Now creating properties can get a little bit difficult – so let me try to explain. When you
set a property in code, it runs one bit of code. When you retrieve a property in code, it
runs another piece of code.
So even though you may be setting and retrieving the same property, behind the scenes
two different pieces of code actually fire up. And as you're now working behind the
scenes, you need to know about them.
• Open the code window
• Click Tools, Add Procedure

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


• In the Name box, type 'AcceptType'
• Click the Property option button
• Hit OK
You should notice the following added to your code window:
Public Property Get AcceptType() As Variant

End Property

Public Property Let AcceptType(ByVal vNewValue As Variant)

End Property
Here we have a let and a get. The let piece of code runs when a user tries to set the value
of our AcceptType property. And the get piece runs when someone tries to retrieve the
value of AcceptType.
Apart from that rather important difference, this property lark isn't that dissimilar from
regular subs and functions. You can imagine that the let piece of code is a sub, that
accepts the new value of AcceptType in the passed vNewValue. And the get piece of code
works just like a function – to send information back to the user, you simply set
AcceptType to a specific value.
Following me?
[Reader: Yeah, in the same way the King of Egypt followed Moses...]
Let's take a peek at an example property let and get pair...
Dim strUserName as String

Public Property Get UserName() As Variant


UserName = strUserName
End Property

Public Property Let UserName(ByVal NewUserName As Variant)


strUserName = NewUserName

End Property
Here, we have a local variable called strUserName.
When the property is set...
MyControl.UserName = "John"
... the let procedure runs and sets the value of strUserName.
When the property is retrieved...
MsgBox MyControl.UserName
... the get procedure runs and returns the value of strUserName.
That's exactly how most property procedures work. But we're using enumerations to make
life easier for our end user... yet alas, slightly more difficult for ourselves.
• Change the skeletal property procedures Visual Basic created for us to something
like this:
Public Property Get AcceptType() As CharacterType

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


End Property

Public Property Let AcceptType(ByVal CharType As CharacterType)

End Property
The only important thing we've done here is to change 'Variant' to 'CharacterType'. If the
user passes a variant, they could be sending anything our way. This way we're saying –
you will pass us one of the CharacterType options and nothing else. Haha, the power!!
Muhahaha!
<ahem>
Top Tip: If you wanted the user to just supply a True or False value, you could always
use 'As Boolean' in place of 'As CharacterType'. Or perhaps 'As Integer' or 'As String'.
Now let's add actual code to bring the property procedure to life:
• In the General Declarations section, declare the following:
Dim m_CharType as CharacterType
• Add a little more code to our AcceptType property procedures, changing them to:
Public Property Get AcceptType() As CharacterType
AcceptType = m_CharType
End Property
Public Property Let AcceptType(ByVal CharType As CharacterType)
m_CharType = CharType
End Property
Think about it for a short while. Do you understand what's happening here? The
m_CharType variable stores the actual value.
Top Tip: You're probably wondering why we're bothering to code all these Property
Get/Let statements – when it seems to do just the same job as a public variable. The
difference here is that you have the power to add code behind your Get/Let statements,
whereas with a public variable you have no control whatsoever. In other words, you
could have a property that accepts some usernames – but if they choose 'Admin', you
could tell them to go swizzle. Erm, programmatically speaking, of course.
• Now add the ConvertCase property to your project:
Dim m_CaseType As Integer

Public Property Get ConvertCase() As CaseType


ConvertCase = m_CaseType
End Property

Public Property Let ConvertCase(ByVal CsType As CaseType)


m_CaseType = CsType
End Property
Are you getting acquainted with properties yet? Hah, you see they're not that frightening –
in fact I was more petrified the last time I watched that epic of epic's, Hoger and
Rammerstein's the Sound of Music.
[Ed: So were we – it was your 538th visit!]

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Go and Test It!
Now let's test your control!
• Click File, Add Project
• Select 'Standard EXE'
• From the toolbox, add your control to the form
Click on the control and take a peek at the properties window. Do you see the
'AcceptType' and 'ConvertCase' properties?

If you click on any of our custom designed properties, you should be presented with a
combo box – enabling you to select any of our defined options!
Try changing the options. Does it work?
Note the numbers next to each option. These are automatically added by Visual Basic.
Now try adding a command button – and insert code behind it that changes our two
properties in code. Notice that just after you type...
Control.OurProperty =
... it allows you to select one of our options, making your code much easier to read. Isn't
that pleasing!?
Now, using the instructions I gave you last week, set the Standard EXE project as 'startup'
– then run it, both setting and reading our properties in code.
Did it all work? What happens when you read the properties?
'UserControl1' isn't a very professional name. Why not try changing it to something like
'TextBoxPro' using the techniques we explored last week?
Conclusion
This week we've started work on our wizzy intelligent text box control. We discussed
resizing and then explained properties.
We went on to put two of our own properties in place – both of which supported
enumerations, making it easier for the end developer and ensuring code is easy-to-read.
Next week, we'll build on what we started today – and will find out just how those
enumerations can start to make our life a lot easier. We'll also add a host of new
properties, code a few methods plus add our own custom events – the easy way!
But until next week, this is your fantabulous host Karl Moore, saying goodnight for
tonight. Goodnight!

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Click Here </activex/controls2demo/> to download or view all files used in this
tutorial.

ActiveX Control Tutorial - Part 3


By Karl Moore
Introduction
Guten Morgan and welcome to the third part of this surprisingly super ActiveX control
tutorial.
As ever, I'm your host Karl Moore and this week we'll continue to chip away at the Super
Cool Text Box project we started a couple of weeks ago.
We'll be:
• Adding a chunk of code to make our text box work
• Discussing how to add events to your code
• Discussing how to add events to your diary
• Getting a Wizard to type code for us
So mount the stallion they call VeeBee – it's time to ride off into the glorious, 24-bit
pixelised Microsoft sunset...
Putting the Properties to Work
So far, we've created the skeleton for our new and improved Text Box. We've added a
couple of properties, defined enumerations and handled resizing.
Err, but it doesn't exactly work yet. In fact, I saw more work emitting from Queen
Elizabeth's left eyebrow, the last time she ordered, "Take over the fort Charlie, I'm off for
an all-expenses-paid weekend in Tunisia".
Hmm, think about it. Even if the AcceptType was set to 'Letters', the end user can still
enter anything into the Text Box. But hey-ho, in this section, we're going to change all
that.
• Open last week's project
• Enter the code window of our control
• Select our Text Box from the Object drop-down list
• Select the Keypress event from the Procedure drop-down list

The Keypress event fires whenever the user types something in the Text Box. An
argument is passed with the event – KeyAscii.
Top Tips: KeyAscii is a number that represents a key on the keyboard. To convert
KeyAscii to its keyboard letter, use Chr(KeyAscii). To convert a letter to its KeyAscii
code, use Asc(Letter). Setting KeyAscii = 0 in the KeyPress event cancels the character.
• Add the following code to the txtTextBox_KeyPress event:
Private Sub txtTextBox_KeyPress(KeyAscii As Integer)

Select Case AcceptType

'Check out the AcceptType property

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Case Numbers
'If only accepting numbers, check...

If IsNumeric(Chr(KeyAscii)) = False Then


' If the passed KeyAscii keyboard equivalent
' is NOT numeric, then cancel the character!
KeyAscii = 0
Beep
Exit Sub
End If

Case Letters
'If only accepting letters, check...

If Not (KeyAscii > 64 And KeyAscii < 91) And _


Not (KeyAscii > 96 And KeyAscii < 123) Then
' If the KeyAscii number isn't greater than
' 64 and less than 91 (upper case characters)
' and it isn't greater than 96 and less than
' 123 (lower case characters), then cancel
' the character!
KeyAscii = 0
Beep
Exit Sub
End If

End Select

Select Case ConvertCase


'Check out the ConvertCase property

Case UpperCase
'If text needs to be in upper case,
'change the KeyAscii value to
'the Ascii code of an upper case
'version of the KeyAscii {phew!}
'DON'T FORGET - Asc() changes a
'letter to it's Ascii value, UCase()
'changes a letter to upper case,
'Chr() changes an Ascii character to
'a normal letter. So here, we're converting
'the Ascii to a normal letter, making it
'upper case then changing it back again!
KeyAscii = Asc(UCase(Chr(KeyAscii)))

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Case LowerCase
'Errm... opposite of the above ;-)
KeyAscii = Asc(LCase(Chr(KeyAscii)))

End Select

End Sub
By observing the comments, you should be able to understand this code. Don't worry if it's
seems slightly alien – after all, it was written by me, Karl Moore, distant son of Phwasack
"Area 51" Carstolemew and third supreme commander of the planet Clot.
Just bare in mind that you don't need to know about 'KeyAscii codes' in order to create
most ActiveX controls. Except this one.
In our control, it's the above chunk of code that does all the work - checks the properties,
ensures characters are upper case or lower case, and beeps if a character is invalid.
Try testing our code. Add a new test 'Standard EXE' project and throw our control onto a
Form.
Don't set the properties at design time – set them in code behind a Command Button.
Then run your application, press the Command Button and attempt to type a few invalid
characters.
Does the control work?
<Karl sniggers as he sinfully realises this is a one-way medium>
Note: If you set the control properties at design time, they will disappear when you run
the application. That's because we haven't told Visual Basic to save that information. You
do this via Property Bags. Remember that – it'll make sense later.
And Another Note: Can you spot the bug? What happens when you choose the 'Letters'
option and tap the spacebar? What about the backspace? Can you fix this?
The Problem...
So you've created your own control with two easy-to-use properties. You've even put
those properties to use via a chunk of code in the KeyPress event of the text box.
Now it's time for a nerdy developer to test your control.
You stick him at your desk and 2.4 seconds later he feebly complains, "But how can I read
or write stuff inside the text box?"
"Damn", comes your reply. "You noticed"
If using a normal text box, you could retrieve the value by running the code...
MsgBox Text1.Text
... but unfortunately your control doesn't have a text property. However our actual Text
Box (txtTextBox) does.
'Cause you're a super-intelligent ActiveX boffin now, you could easily implement such
functionality by adding code similar to the following...
Public Property Get Text() As String
Text = txtTextBox.Text
End Property

Public Property Let Text(ByVal NewText As String)

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


txtTextBox.Text = NewText
End Property
Do you understand what is happening here? You're just passing the Text property of the
Text Box around through Property procedures.
But what if users requested all the other usual properties of a Text Box control?
Alignment, Appearance, BackColor, BorderStyle, Font and ForeColor - to name just a
few.
That's a lot of monotonous coding. And what if they also wanted to respond to certain
events, such as the KeyPress and Click events of your Text Box?
Well, we've not really mentioned events yet – so let's discuss them now.
Most controls have at least a few events related with them. The Text Box control has a
KeyPress event, as we saw earlier today. The Command Button has a Click event. The
Scroll Bar has a Change event. And so on.
When the Text Box or Command Button decides it should fire the event – well, it does.
And that means any code you have written behind the event runs. After your code has
finished, control is then returned to the control. Confused? You should be, but please stick
with it.
Now, you can create your own custom control events by adding a simple statement to the
General Declarations section of your code, like this:
Public Event Click()
or...
Public Event DocumentProcessed(DocumentID as Integer)
Simple enough. And then you could raise the event to the developer using your control by
adding a line like this to your code:
RaiseEvent Click
or...
RaiseEvent DocumentProcessed(5623)
Note: Notice how that last event passes an argument, the DocumentID.

So let's recall our original problem – what if our end user wanted to respond to events of
the Text Box? Say, the Click event?
Well, we could create our own custom events identical to those of the Text Box. Then,
when those Text Box events fire, we could raise our own events to the end user.
Let's see an example of how we'd do this with the Click event:
Public Event Click()

Private Sub txtTextBox_Click()


RaiseEvent Click
End Sub
All we're doing here is – every time the Click event of our Text Box fires, we're just
passing the message to our end user via our own control's Click event.
But writing all of that code for every single Text Box event would become just as boring
and error-prone as it would be to write similar code for every single Text Box property -
so boring in fact, that only Train Spotters International ever tried it. Unfortunately they all
kicked the bucket before the project was completed. Old age, you know.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


So is there an alternative to rid of writing all these monotonous properties, events or even
methods? You bet your bottom dollar there is – and it's all hidden behind an innocent-
looking Microsoft wizard...
The Solution!
Thankfully whilst beta-testing Visual Basic 5/6, Billionaire Bill and his gang of merry
programmers decided that making developers type line after line of such repetitive code
was rather cruel. And also dead boring.
So one of the head nerds played around to produce a magical Microsoft wizard that can
automatically produce run-of-the-mill code and rid of all your worries. Well, maybe not all
your worries.
Anyway – interested? Let's load up the Wizard...
• Click Add-Ins, Add-In Manager
• Double-click on the 'VB 5/6 ActiveX Ctrl Interface Wizard' until it's Load
Behaviour changes to 'Loaded'
• Click Add-Ins, ActiveX Control Interface Wizard
• If you're presented with a welcome screen, click Next

The current screen should ask you to select the 'interfaces' you want Visual Basic to
automatically 'code' for you.
Interfaces? Yeah, that's just a posh word to describe what stuff your control shows (or
'exposes') to the developer. And 'stuff' is a technical term defined as properties, methods
and events.
So - the list box to the left of your screen displays this list of suggested interface members,
such as the Font property and the Click event.
Note: These suggested interfaces have been determined by the existing properties,
methods and events of controls you currently have in your workspace. At the moment, we
just have a Text Box – so it's suggesting it should code all the 'stuff' related to a Text
Box, such as the Font property.
• Move a few of the interface members across to the second box:
• -- BackColor, BorderStyle, Click, DblClick, Font, FontBold, FontItalic,
FontUnderline, PasswordChar, Refresh, Text
• Click Next
If you wanted to add any extra properties, methods or events – the current screen would
be the place to do it. But we don't, so...
• Click Next
Now we're going to 'map' all the properties, methods and events we selected direct to our
Text Box. This lets the wizard know that our custom Click event, for example, should be
fired when the Click event of the Text Box is activated. And the custom BackColor
property should pass its value direct to the BackColor property of the Text Box. And so
on and so forth.
This is called 'mapping'.
• Select all the interface members in the list box (hold your left mouse button down
and drag along the list)
• From the 'Maps to Control' list, select your Text Box
• Click Next

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


If you added any properties, methods or events that don't directly 'map' to anything - this
is where you give the wizard a little more information, allowing it to create a basic skeletal
outline procedure for you. But we haven't, so we won't.
• Click Next
• Click Finish
Hold on, Max... err, what's happened to all our beautiful code?
What the Wizard Did
So the wizard has finished whirring and you're sitting there, staring in
astonishment/disbelief/annoyance.
Let's take a look at an example of the wizard's work:
'WARNING! DO NOT REMOVE OR MODIFY
'THE FOLLOWING COMMENTED LINES!
'MappingInfo=txtTextBox,txtTextBox,-1,Text

Public Property Get Text() As String


Text = txtTextBox.Text
End Property

Public Property Let Text(ByVal New_Text As String)


txtTextBox.Text() = New_Text
PropertyChanged "Text"
End Property
Hmm, nothing too complex there. In fact, it's almost exactly as we anticipated – except for
the 'PropertyChanged' line, but we'll explain that shortly.
Hold on... have you noticed yet? The wizard has commented out the AcceptType and
ConvertCase properties you worked so hard to create!
Oh, wait a minute – yep, it's OK - the Wizard has replaced them with almost identical
procedures – except the Let procedures now have a 'PropertyChanged' line in them.
Top Tip: As the wizard has now commented out your two procedures, you no longer need
the m_CharType and m_CaseType variables you created. The wizard has created it's own
variables to hold the values of the AcceptType and ConvertCase properties – the more
sensibly christened m_AcceptType and m_ConvertCase
What else has that darn wizard done? Oh, it seems there's now code in the WriteProperties
and ReadProperties events of the UserControl object. And that code babbles on about
'ReadProperty' and 'WriteProperty'.
Thankfully the code still works, no problems. But tell me Joe, darn it, what's the story
with all these here Property thangs?
Well, remember what I mentioned earlier? If you change the properties of your control at
design time, then run your project – those changes disappear faster than Hitler's wig on a
windy day.
That's 'cause we've never told Visual Basic to save them. However the Wizard has now
added all this Read/Write Property code that does just that – saves or 'persists' our
properties.
But that's enough on that topic for now. Go have a good ol' rest and join us next week for
the full, feature-length nail-biting explanation!

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


<Ed: What a cliff hanger!>
Conclusion
This week we added code to make our Super Cool Text Box control work. We then
discussed events and how to raise them within your control.
We finished off by checking out the neat ActiveX control wizard and how it can make
mundane, error-prone coding a task of the past.
Perhaps we haven't had as much 'hands-on' today as previous weeks – but don't worry,
you've just about completed your control and learned a lot of important lessons along the
way.
And that means you're getting closer to becoming an ActiveX Wizard! And I'm not talking
about the Microsoft type.
Hey - Well Done!
Now for a little homework. Bear in mind that you read a property via the Get statement
and write to it via the Let statement. What could you do to make a property read-only or
write-only? And why would you want to do that?
Incidentally, "Because you suggested it" is not a valid answer.
First chap to post the correct answer on the bulletin board wins a three-year old Mars bar.
Before the next tutorial, it'd also be good practice to play around with events. Try raising
your own and then responding to them in code. You can even add extra events to our
Super Cool Text Box control, if you wish.
Next week, we'll unravel the mystery of the wizard's weird property code – and take a
geek peek at Property Bags, which incidentally are nothing to do with shopping bags,
leather bags or indeed, baggy bags.

ActiveX Control Tutorial - Part 4


Introduction
Hola and welcome to the fourth instalment of the only ActiveX control tutorial that's
groovier than Austin Powers and perhaps even hotter than Felicity Shagwell's pants*.
* 'Course, that all depends on whether you adopt the American or saucier English
definition. I opt for the latter. Any complaints?
If you've missed any of the previous slots, be sure to check them out before continuing:
• Part One </activex/controls/> – Introduction to ActiveX controls
• Part Two </activex/controls2/> – Properties, Enumeration, Resizing
• Part Three </activex/controls3/> – Events, Mapping, ActiveX Wizard
As ever, I'm your wizzy host Karl Moore and this week, we'll be:
• Discussing what that wizard did last week
• Figuring out what property bags are all about
• Figuring out what old bags are all about
• Adding our very own custom property pages (cool stuff!)
So grab that copy of Visual Basic and let's fly off into the programmatic world of ActiveX
controls...
Bag O' Properties
Thankfully, by the end of this tutorial you will have finished the Super Cool Text Box
control we've been working on. And that's good, 'cause I'm getting bored now.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


In fact, I haven't experienced this much boredom since the time London Ritz Hotel made a
slight booking error and placed the entire Wool Appreciation Society in the same meeting
hall as the International Morris Dancer's convention.
<Ed: Really? How did you find out about that, Karl?>
<Karl: I'm Morris Dancer number #2538>
So far in our lil' project, we've added a few funky properties, checked up on enumeration
and resizing, figured out raising events – and even used a wizard to help save time with
any run-of-the-mill coding.
But last week, I left you on a cliffhanger. Oh yes, don't deny it.
You see, after the wizard finished running – it left a wad of 'read and write properties'
code all over the place, remember? The question was, what does it all do?
Well, sit back my little cherubs, as I explain all.
<Babble mode: ON>
Let's say you go ahead and add our spicy control to a nice test project. You then alter the
'AcceptType' property to 'Letters', save everything and marinade overnight in a healthy
dollop of hard disk juice.
The next morning, you return and open the project. But <shock, horror> the 'AcceptType'
property is now displaying the default 'All'.
So what happened? Who stole the property?
Well, let me give you a clue: it wasn't the Butler. Oh no. The truth is we simply haven't
told Visual Basic that it should save the property.
"Why doesn't VB save it automatically – instead of forcing programmers to do all the
hard work?" - Good question.
Let's think about it – hmm, I guess some properties don't really need saving. For example,
the SelText property of a Text Box, which returns any text currently selected, doesn't
need saving – but it is still a property.
Yet other properties such as 'AcceptType' clearly do need saving – and Visual Basic does
provides a neat method for doing this. OK, so how do you actually tell VB to save your
property?
When an instance of your control is saved, the WriteProperties event of the UserControl
(that's your control 'workspace') fires. In addition, a 'PropertyBag' is passed as an
argument to this event.

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)


A property bag is just a virtual bag that stores, err, properties.
<Ed: No? Gee, nothing gets past you, Karl!>
In effect, it's a holding place for values. And you can read and write to this group of values
by using two of the property bag methods.
So let's pretend a developer is using our Super Cool Text Box control and changes the
Text property in design mode. The geezer then hits the Save button.
Quicker than you can say antidisestablishmentarianism, Visual Basic (*) yells to your
control, "Hey, I'm trying to save here" – and fires its WriteProperties event – passing a
property bag to it.
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


You can imagine this property bag as a shopping trolley without the wonky wheels – your
task is to fill it up with the information you need to save. You do the "filling up" like this:
Call PropBag.WriteProperty("Text", _
txtTextBox.Text, "")
Here you're running the WriteProperty method of the passed property bag. You're telling
it to save this information under the heading of "Text", with a value of txtTextBox.Text.
The final double-quotation marks indicate a default value of, well, nothing actually.
So you write values to the property bag – and hence, save your control properties, such as
Text - using this template:
Call PropBag.WriteProperty(PropertyName, _
PropValue, Default)
Let's take a peek at another code example:
Call PropBag.WriteProperty("ConvertCase", _
m_ConvertCase, m_def_ConvertCase)
Here, our code is saying – "Save this item under a heading of ConvertCase, with a value
of m_ConvertCase – and a default value of m_def_ConvertCase".
So in brief, the WriteProperties method fires when a control is being saved. You're passed
an 'empty shopping trolley' – and asked to put all the stuff you need to save into it.
Typically this trolley is stored along with the thing that uses it, such as in a Form FRM file.
Take a quick look at your Super Cool Text Box project. Notice how the Wizard
automatically added all this code for you? You'll get a chance at writing your own
WriteProperty code later.
Anyway, that's how you tell Visual Basic to save the values of your properties, such as
AcceptType.
But what about when the user opens his or her project? How do we get the property
values we've just put into the property bag – back out?
Top Tip: You may wonder why, in addition to passing a 'PropValue' value, we also send
the WriteProperties method a 'Default' value. Erm, why bother passing across two
values? Won't it simply be the 'PropValue' that gets saved – not the default? That one
puzzled me for a while. But it appears the WriteProperty method compares both the
property value and the default – and only saves if they're different. After all, it would
waste disk space to save the redundant default value of a control – such as the Text Box
BackColour being white, when it's white by default. But by supplying this default, it
allows the property bag to compare and decide which bits it should save. Clever stuff,
eh? You'll understand this concept more as we delve further into default values over the
next section.
* Asteriskical Top Tip (hah, and they sed I couldn't spel!): Actually, when you finally
distribute your control – it's not only Visual Basic developers who'll be able to utilise it.
When you create an ActiveX component of any type, it's automatically compatible with
all ActiveX/COM-aware programming languages, including Visual C++
And Then There Was ... ReadProperties
Next up on my nerdy curriculum, we have the ReadProperties event. Excited yet? Not
exactly an inspiring name, I grant you – but please bear with it.
Ironically, despite doing exactly the opposite of the WriteProperties method we just
uncovered, ReadProperties is surprisingly similar in usage.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Hmm, I could cunningly ask you to reread the previous section backwards or something,
but I don't think the Ed would like that. In fact, he'd have me off the site before you can
say antidis...
<Fading 'Arghhh!' sound as author Karl Moore is thrown out the nearest window by an
evil, hooded figure bearing a suspicious resemblance to the Ed. Can't be certain it was
him though. Recognised nothing major, just silly little similarities. Like the thick cigar
sticking out of the balaclava. Oh, and the one-legged limp. And the 'I am the Editor' tee
shirt he wore. Strange coincidence, that. Ho-humm. Minutes later, a slightly-bruised
Karlos sneaks back indoors to continue the tutorial>
Now, let's pretend one groovy son-of-a-developer used your Super Cool Text Box control
yesterday to start developing his Parcel Tracking program. He's now returned to continue
work – and opens the Visual Basic project.
What happens? As the form bearing your creation opens, Visual Basic says "Hey diddly
dandy, I'm loading you up here" – and fires the control's ReadProperties event:

Private Sub UserControl_ReadProperties(PropBag _


As PropertyBag)
Here, you're passed a property bag that potentially contains a handful of property values,
such as those previously saved. It's at this stage you can read those properties. Let's peek
at an example:
m_AcceptType = PropBag.ReadProperty("AcceptType", _
m_def_AcceptType)
Here, we're passing ReadProperty the name of the item to find within the bag
('AcceptType') – and a default value of m_def_AcceptType.
If, after a quick rummage around, the ReadProperty method manages to find a value for
our item, it's passed back – otherwise our default value is returned.
Either way our m_AcceptType variable, which ultimately handles the AcceptType
property is set appropriately.
Let's look at another supercool example:
txtTextBox.Text = PropBag.ReadProperty("Text", "")
Here, we're directly setting the Text property of our Text Box equal to the "Text" value in
the property bag. If no value exists in the bag, ReadProperty passes back our default of ""
– an empty string.
So you read values from the property bag – in other words, retrieve your control
properties - using this template:
Destination = PropBag.ReadProperty(PropertyName, Default)
In brief, the ReadProperties event fires when your control is being loaded. It passes you a
possible bagful of properties – and allows you to pick out the items you want and set
variables or object properties accordingly.
Do you understand how both the reading and writing of properties fit together? Take a
closer look at your project. Do you understand what the wizard has done?
Why don't you practice these techniques by adding a 'play around' property, such as
Text2? You can access it via a property Let and Get routine, then use the WriteProperty
and ReadProperty skills you've just learned to 'permanently' store the information
alongside your control.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Top Tip: Here's a great way to chat up geekesses. Instead of saying you used the
'ReadProperty' and 'WriteProperty' methods to save stuff, simply mention how you
'persisted' the values. Trust me, you'll sound much more of an anorak – and the grrls just
love it!
But hold on one lil' minute, missy – we've still not figured out the meaning of that
mysterious 'PropertyChanged' statement our wizard threw inside every Let procedure -
remember? Grab that cigar Sam; it's time to investigate...
PropertyChanged
Behind virtually all of our Property Let routines, you will notice the wizard added a
strange 'PropertyChanged' statement, as so:
Public Property Let ConvertCase(ByVal _
New_ConvertCase As CaseType)
m_ConvertCase = New_ConvertCase
PropertyChanged "ConvertCase"
End Property
Why? Well, this is very simple. And I'm not talking about 'E=mc2' simple here. I'm taking
more along the lines of '1=1' simple.
All PropertyChanged does is inform the thing using your control that a particular property
has changed. In other words:
PropertyChanged "ConvertCase"
...would send a message back to Visual Basic saying, "Hey, somebody has altered
ConvertCase – so make sure the Properties window is up-to-date. Oh, and don't forget
that 'cause a change has been made, you'll probably want to save the project some time
soon!"
Once again, the Wizard has automatically added all this for you. If you need to do it for
yourself however, use this format:
Public Property Let PropName(ByVal _
vNewValue As Variant)
'Usual code for processing property goes here
PropertyChanged PropName
End Property
Let's Get Physical!
Hey, wait a minute. I've done nothing but babble on about theory so far. It's time to get
physical!
<Karl starts grooving away to a song of the same name, unaware of onlookers. Ten
minutes later, after one final dazzling disco floor split, he composes himself then returns
to the computer>
Ahem.
Have you used the ADO control before? If you right click on it, then select Properties –
you'll see a small form that enables you to select various options. It's really just an
advanced version of the Properties window.

Lot's of professional components have these 'property pages'. They allow you, as the
developer to have much more control over how you can display and allow users to select
properties.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


That means you can use Tabs, Combo Boxes, TreeViews, Command Buttons – basically
anything you can add to a regular form – to brighten up the selection of options.
For the rest of today, I'm going to show you how to create your own property page. My
example won't be anything spectacular, but hopefully it will give you a few ideas as to how
you can create your own.
So wave goodbye to alphabetically ordered Property window, and say hello to the all-
singing, all-dancing property page:
• Open our Super Cool Text Box control project
• Click Project, Add Property Page
You should be presented with a screen allowing you to add a raw property page or use the
Property Page Wizard. For now, let's be lazy and go with the Wizard – we'll do a little
manual work later.
• Select the 'VB Property Page Wizard' and click Open
• Click Next at the introduction
Your screen should now look like this:

Each item in this list will represent one 'tab' when you view the property page of your
control. For instance, this control has five different property pages – each represented by a
tab:

• Uncheck the StandardColor and StandardFont boxes


• Click 'Add' and type: General
• Click OK
Top Tip: Our project will only have one property page, General. But you could have
many more – as the above screenshot demonstrates!
• Click Next
Note that Visual Basic has already selected a list of 'Available Properties', though sadly
not 'AcceptType' or 'ConvertCase'. Don't worry, we'll deal with this later.
• Add all available properties to the 'General' list
• Click Next
• Select No for the Summary Report and click Finish
• After the Wizard has finished, click OK
Aviation Certificate, Anyone?
Open up the property page our Wizard created. It should look something like this:

Huh, not very exciting. In fact, you're looking at the only computer screenshot so plain it
ships with its own aviation certificate.
Let's take a peek at some of the code behind this rather dull property page.
Underneath all the Change events of the Text Boxes and the Click events of the Check
Boxes, you should find this code:
Changed = True
This tells Visual Basic that at least one property on the page has changed. Of course, it
doesn't signify that the change should be saved - you mustn't forget that all property pages

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


have an OK, Cancel and Apply button. It simply informs VB that a property has been
altered – a little like the PropertyChanged method of your control.
Now, just as a regular Form has its own events, so does the Property Page. When
someone hits the OK or Apply buttons, the ApplyChanges event runs – then it's up to you
to save the properties. This is a little like the WriteProperties event of your control.
Likewise, when someone first opens your Property Page, the SelectionChanged event
fires. This can be compared to the ReadProperties event of your control – it allows you to
'set' the various whatnots on your property page.
So let's take a peek at some of the code the wizard threw behind those two events:
Private Sub PropertyPage_ApplyChanges()
SelectedControls(0).Text = txtText.Text
SelectedControls(0).PasswordChar = txtPasswordChar.Text
'... etc ...

'This is like WriteProperties -


' It passes the changes on your
'property page back to the control
'– SelectedControls(0)
End Sub

Private Sub PropertyPage_SelectionChanged()


txtText.Text = SelectedControls(0).Text
txtPasswordChar.Text = SelectedControls(0).PasswordChar
'... etc ...
'This is like ReadProperties -
'It reads the properties of your control
'via SelectedControls(0) – and displays
'the info via your property page text boxes,
'check boxes, combos, etc.
End Sub
Now, you've probably noticed 'SelectedControls' appearing once or thrice throughout the
code. This is a method of your property page - basically a direct 'link' to the running
instance of your control.
So if you wanted to check out a property of your control, say the PasswordChar value,
you can access it via the SelectedControls(0) item. You can read any of our control
properties using this format:
SelectedControls(0).PropertyName
For example:
SelectedControls(0).PasswordChar
... passes back the value of the controls PasswordChar property. The SelectedConrols(0)
bit here is just a gateway to your control and its properties.
And if you can understand that, the code should look simple.
Excellent! Let's summarise:

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


In the ApplyChanges event, you're simply setting properties of the user's control
dependant on the various Text Boxes, Check Boxes, etc. present on your property page.
You're applying changes made in the property page direct to the control.
In the SelectionChanged event, which remember is similar to our control's
ReadProperties event, you merely set the values of your Text Boxes, Check Boxes, etc.
dependant on the properties of the user's control.
Put simply, the SelectedControls(0) statement just gives you direct access to the user's
instance of your control – and all it's properties.
Try testing your control! Add it to a demo project, right click and select Properties. Try
changing a few of the options, then click Apply or OK.
Notice how the Properties window updates itself?
Changing the Property Page
Now I don't know about you, but I ain't awfully satisfied with my property page. It looks
about as stunning as a sumo wrestler's bottom.
So let's try to spruce it up a little by adding support for our custom AcceptType and
ConvertCase properties:
• Add two Labels and two Combo Boxes to your Property Page

• Name the Combo Boxes 'cboAcceptType' and 'cboConvertCase' respectively


• Change both their Style properties to '2 – Dropdown List'
Now, when the property page opens, we want those two Combo Boxes to hold our
enumeration options – such as 'All' or 'Letters'. Unfortunately there isn't an easy way to
automatically do this, so we'll add them manually – under the property page's Initialize
event (similar to Form_Load).
• Add the following code to your property page:
Private Sub PropertyPage_Initialize()
With cboAcceptType
.AddItem ("Anything")
.AddItem ("Just Numbers")
.AddItem ("Just Letters")
End With

With cboConvertCase

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


.AddItem ("Anything")
.AddItem ("Upper Case")
.AddItem ("Lower Case")
End With
End Sub
Try testing your project now. When you open the property page, are you able to select an
item from the list?
Good – let's continue:
• In the Click event behind each Combo Box, add the code:
Changed=True
Remember, this tells Visual Basic that at least one property on the page has been changed.
Now let's add a little code to the bit which reads properties and sets the value of your Text
Boxes, etc.
• Add the following code to the SelectionChanged event:
Select Case SelectedControls(0).AcceptType
'Note that I'm using the enumeration name prefix
'instead of the ambiguous "All"
Case CharacterType.All
cboAcceptType.Text = "Anything"
Case CharacterType.Letters
cboAcceptType.Text = "Just Letters"
Case CharacterType.Numbers
cboAcceptType.Text = "Just Numbers"
End Select

Select Case SelectedControls(0).ConvertCase


Case CaseType.All
cboConvertCase.Text = "Anything"
Case CaseType.LowerCase
cboConvertCase.Text = "Lower Case"
Case CaseType.UpperCase
cboConvertCase.Text = "Upper Case"
End Select
Here, we're just examining the current AcceptType and ConvertCase properties, then
changing the Combos as appropriate.
So that's how we get the initial properties into the property page. Now we need to deal
with how to get them out, after the user clicks OK or Apply.
• Add the following code to the ApplyChanges event:
Select Case cboAcceptType.Text
Case "Anything"
SelectedControls(0).AcceptType = _
CharacterType.All
Case "Just Letters"
SelectedControls(0).AcceptType = _
CharacterType.Letters

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Case "Just Numbers"
SelectedControls(0).AcceptType = _
CharacterType.Numbers
End Select

Select Case cboConvertCase.Text


Case "Anything"
SelectedControls(0).ConvertCase = _
CaseType.All
Case "Lower Case"
SelectedControls(0).ConvertCase = _
CaseType.LowerCase
Case "Upper Case"
SelectedControls(0).ConvertCase = _
CaseType.UpperCase
End Select
Here, we're just doing the reverse of the SelectionChanged event. We're analysing the
content of the two Combo Box controls, then changing the user's control properties to
reflect them.
Top Tip: There are numerous ways in which this code can be improved, but has been left
as shown for simplicity. Can you think of a different method to set our properties other
than via text comparison in a Select Case statement? Can you see where you could use
the With keyword?
Go ahead; test your property page in the usual manner. Does it work? Notice how
changes made in the Properties window are instantly reflected in your property page, and
vice versa. That's all down to the mysterious 'PropertyChanged' command, keeping
everyone up-to-date as to the latest happenings.
Phew! What a difficult section!
But it's time to celebrate – congratulations on getting this far! You've successfully
completed all the main components of the Super Cool Text Box control!
Conclusion
Today, we've explained the mysterious property keywords that cropped up in last week's
tutorial.
The three major methods we discovered were WriteProperty, ReadProperty and
PropertyChanged. Each assist in keeping your control both stable and user-friendly.
In the last half of this tutorial, we looked at the advantages of Property Pages, their
similarity with the UserControl concepts discussed in the first section, plus learned how
you can implement them to enhance your control's usability.
We discovered that if you're after something more than just an alphabetical list, it's time to
turn to the property page. And I'm not talking about the back cover of your local rag.
For a little homework, why not try to improve some of the code here? Add your own
properties, along with the appropriate read and write code. You could even inject a little
razzmatazz into the Property Page we finished building just a few minutes ago.
And guess what prizes we're offering for the best design? Well, somebody claimed the
three-year old Mars bar last week, so we're down to... oh. Nothing, actually.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Next week, we'll conclude the tutorial with instructions on how you can package your
control for the end user. I'll also be providing a host of free, commercial-quality examples
(with full source code!) – plus a handful of top tips to ensure your control stands out
above the crowd.
But until next time, this is your host Karl Moore waving you all a goodnight for tonight.
Goodnight!

ActiveX Control Tutorial - Part 5


By Karl Moore
Introduction
Ciao and welcome to the fifth and final instalment of our ActiveX control tutorial.
As ever, I'm your host Karl Moore – and if you've missed any of the previous slots, check
them out here:
• Part One </activex/controls/> – Introduction to ActiveX controls
• Part Two </activex/controls2/> – Properties, Enumeration, Resizing
• Part Three </activex/controls3/> – Events, Mapping, ActiveX Wizard
• Part Four </activex/controls4/> – Wizardy Whatnots Explained and Property
Bags/Pages
This week, we'll be:
• Finding out how to distribute your control
• Answering common questions
• Learning techniques to ensure your creations stand out above the crowd
• Looking at how you can use this new skill to enhance your career
So grab your poisoned-nib arrow and SAS survival handbook - and let's finish the
adventure of a lifetime. Alternatively, sit back and enjoy the tutorial.
Distributing your Control
So, you've finally perfected your wonderful creation. It's flashes, whizzes and whirs - and
packs more code than Bletchley Park in 1947.
Now what? Well, we need to distribute the control to our end users.
Thankfully, this part is really easy. In fact, even my pet iguana Strangely Green can do it.
You may remember him from the database tutorial. Cute lil' thing.
Am I digressing? Oh, sorry. Well, let's get on and figure out how to distribute your
control:
• Launch Visual Basic
• Open the control you wish to distribute, such as the Super Cool Text Box we've
been working on over the past few weeks
• Click on File, Make <ProjectName>.ocx

• Select the .OCX location in the dialog box and click OK


After a little cranking of the hard disk, Visual Basic will create your own .OCX file. This
is your final control.
Top Tip: An OCX is to your ActiveX control what an EXE is to a standard VB project.
So that's our actual 'EXE' sorted. Before we create the setup program for our end user,
let's see our control in action:

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


> Create a new Standard EXE in Visual Basic
> Select Project, Components
> Find your control in the list, select it and click OK
Top Tip: If your control is called something like 'Project1', you can rename it – by
reopening your control in Visual Basic, selecting Project/Properties, entering something
into the 'Project Description' box – and then recompiling the OCX as above.
You should now find your control in the toolbox of your Standard EXE project.
> Add the control to your form
> Try playing with a few properties, methods and events
You should find that your control works just like any other. And if so, that's excellent.
Let's continue with our setup program:
• Launch the 'Package and Deployment' wizard, found on the Start menu (usually
within the Visual Studio or Visual Basic Program folders)
• Select your .VBP ActiveX control project after clicking the 'Browse' button
• Hit the 'Package' icon
• If asked if you want to recompile your OCX file, select 'No' – we did that just a
few minutes ago

Now it's time for the wizard to step in. Follow the prompts through to the end. Note that:
• On the 'Cab Options' screen, select 'Multiple Cabs' if you're going to distribute via
floppy disk, or 'Single Cab' if you're going to dish out via CD-ROM or as a zipped
up download from the Internet
• On the 'Installation Title' screen, enter the title of your project such as 'Super Cool
Text Box'
• If you want to save your setup settings for a later session, enter a script name on
the 'Finished!' screen
Most of the time, you'll be fine just accepting the defaults. But be sure to read the
explanations and change anything you desire.
• When you've cycled through all the wizard screens, hit Finish
• After your machine stops buzzing, read the brief status report then click Close
That's it! You've just created a setup package for your control, ready to be distributed to
your end users!
Try checking out the folder in which the wizard placed your setup files. You did make a
note of it, right? It's probably called 'Package'.
Try copying these files across to a different computer, running the Setup program
(setup.exe) and trying out your control within Visual Basic, Excel or whatever. It should
work just the same as it does on your computer!
Well done! You've just created and tested a setup package for your control!
In fact, you'd better keep those test setup disks. They'd make an ideal Christmas present
for any self-respecting nerd.
Important Top Tip: Now that you've compiled your control, it isn't just restricted to use
within Visual Basic. You could utilise it within Excel, Word, Internet Explorer, Visual
C++ or any ActiveX-aware application!
Top Tips for your Control, Part One

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Before we get into the intricacies of control versioning and class IDs, let's talk about
something much more important: how to replace that boring little toolbox picture that
represents your control.
Open your control in Visual Basic and select the 'UserControl' object from the Properties
window. This displays all the properties of your control. Find the ToolboxBitmap property
and use the ellipsis to set an appropriate picture file.
The size of the toolbar bitmaps is about 16 x 15 pixels – but don't worry if you're slightly
out, Visual Basic will automatically resize the image for you.
If you're getting desperate for images, you might want to check out the samples that ship
with Visual Basic – usually in the Program Files\Microsoft Visual
Studio\Common\Graphics folder.
Compiling your Control
Every time you compile your OCX control, Visual Basic assigns it a unique class ID. For
example, my control was assigned the ID "DF2785AB-AA42-4EEB-9C4B-
566B3B70E340".
Let's say your friend, erm, Mr Wibbleshaw, has decided to use your control in his latest
program. When he distributes his creation, the setup package naturally bundles your
control too.
Now here's something you need to understand: when one of Mr Wibbleshaw's forms needs
to display your control, it shouts out, "Hey, I'm looking for control DF2785AB-AA42-
4EEB-9C4B-566B3B70E340" – and hopefully the control comes running along and
plonks itself on Wibbelshaw's form.
So in other words, his application references your control by that automatically generated
and guaranteed unique class ID.
And that makes sense. After all, if your control was called 'Nice Text Box' – and someone
else wrote a 'Nice Text Box' too – the incorrect control could accidentally be displayed.
And that control probably wouldn't support the same properties and methods as the first
proper one.
So basically, programs use class IDs to point to (or 'reference') controls. But what if news
hits the town that you've created a new and improved version of your control? All your
users rush and install it, including the chaps that use Mr Wibbleshaw's program.
What will happen?
Well, every time you compile your control, Visual Basic creates a new class ID for it.
That means Mr Wibbleshaw's program would probably be best using the new and
improved control – but is still looking for the old ID. And since you recompiled the
control, it has a new ID.
Confused? Yeah, me too. But the point of this wonderfully written story is that each time
you compile your control, it really must stick with the same ID. If it doesn't, it means the
developer using your control has to recompile his program with your new control so it
remembers the new class ID.
<Ed: Phew!>
You can keep your ID the same by clicking on Project, Properties in your project after
creating your final ready-for-distribution OCX. Click on the 'Component' tab and in the
Version Compatibility frame, select 'Binary Compatibility' and choose your freshly
compiled OCX file.

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Now, everytime your project tries to compile, it will use the same class ID as the OCX file
you just pointed to.
It's worth noting that sometimes you can't maintain compatibility between versions of your
control because you've made such major changes – still, if you've set the above Binary
Compatibility, Visual Basic will at least warn you first.
Raising Errors
Ever been in the middle of testing your application, when one of those horrid grey 'Error'
boxes appears, offering you the option of Debugging or Ending your program? Oh,
choices, choices.
Well, it's time to get revenge. You can raise your very own errors within controls by using
Err.Raise()
Let's say you created some database control with a 'Username' property. And you didn't
want your user to choose the name 'sa'. Let's look at how we could handle this in code:
Public Property Let Username(New Username As String)

If NewUsername = "sa" Then


Err.Raise vbObjectError + 101, "Username Property", _
"Cannot specify username 'sa'"
Else
mstrUsername = NewUsername
End If

End Property
This raises an error in the application attempting to set your control's Username property.
Groovy? I think so.
Top Tip: To find out more about raising errors within your control, look up the 'Raise
Method' (Visual Basic Reference) in the Visual Basic help files.
If something goes wrong in your own code that you can't handle, you could try 'passing
back' the error to the developer using your control. Once again, you could simply use
Err.Raise() – this time, in your error handler. You'd be raising an error that you received –
or rather, passing it back.
Resizing your Controls
In our sample Text Box control, we didn't have to worry about resizing too much. We
simply set the dimensions of our Text Box to the dimensions of the UserControl object.
However if we were dealing with more complex items – such as a File Open dialog box
that needed to perfectly resize all the controls within it – you'd need to get much more
technical. You'd be dividing heights by three, multiplying the square root of 18 by the
width of your control, then taking away the number you last thought of... and so on.
Trust me, resizing work can get pretty complicated. So you might want to think about
purchasing one of the many resize controls available that simply does it all for you – try
checking out our ReSize OCX review </controls/resizeocx/> for size.
Top Tips for your Control, Part Two
Getting it on the Net
If you have the urge, you can even get your control on the Internet. How?

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Well, you might want to test it within Internet Explorer (IE) first. Whilst in your ActiveX
control project, try selecting Project, Properties then clicking the 'Debugging' tab. Choose
the 'Start component:' option and select your control. Then click OK and press F5 to run
your control within IE.
Whilst running in the browser – an ActiveX 'container' - click on View, Source. What do
you see? Does this make sense after reading the section on class IDs?
To create an Internet setup package for your control, run the Package and Deployment
wizard as earlier – but this time select 'Internet Setup' as opposed to 'Standard Setup' –
and follow the on-screen instructions.
Adding an About Box
Ever noticed how some controls have a really cool 'About' box that you can activate by
clicking on the ellipsis at the top of the Properties window?
Well, you can add your own by including the following code in your control:
Public Sub About()
'load your about form, whatever it may be
frmAbout.Show
End Sub
After this, select Tools, Procedure Attributes. Select 'About' from the drop-down list, then
click on the 'Advanced>>' button. From the procedure ID drop-down, select the
'AboutBox' option. This tells the Properties window that this piece of code displays your
About box.
And that's it!
Top Tip: Don't forget that you don't have to display a form as your About box, it could
just be as simple as a message box (MsgBox). Still, a form does look groovier!
Let's Get Multiple
You may have already noticed, but some OCX files pack more than just one simple
control. Oh yes. Take the 'Microsoft Windows Common Controls' that ship with Visual
Basic. That includes a whopping nine separate controls.
So how can you have more than one control in each ActiveX control project? Simple. Just
click Project, Add User Control. This adds another 'workspace' to your project, which is
the 'form' of your control.
And then continue developing just as you would normally. When you finally compile the
control and add it to a test project, you'll notice two icons in the toolbar – one for each
'workspace' (User Control) in your project.
Protecting your Control
So, you've created your own supercool control and want to release it to the world - but
are slightly worried about devious developers devouring dodgy yet delectable
distributions? Or in English, you're worried about piracy?
No problems. Although I've never personally needed to go this far, there are numerous
programs on the market to help you create 'Trialware', a time- or feature-limited product
that gives developers a taste of your talents.
Retrieving the Control Name
Ever wondered how the Text Box control inserts its Visual Basic name into the Text
property each time you add one to a form – such as Text1, Text2 and so on?
It's easy to do. Simply grab the DisplayName property of the Ambient object, like this:

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Text1.Text = Ambient.DisplayName
Don't forget, the Ambient object contains information about your control's environment,
such as the BackColor and Font of the form it resides on. It's a good idea to make your
control be a good little boy - and use these properties to set it's own BackColor and so on.
What Next?
First off, I'd like to personally congratulate you on getting this far in the ActiveX control
tutorial. It's been a tough course, but you're obviously a tougher cookie.
But where do you go from here? What should you do with this newfound talent?
Well, controls are a great way to encapsulate all your hard work and programming logic
into a simple widget you can throw onto a form. Or an Excel spreadsheet. Or a Word
document. Or whatever.
They allow you to take all the complicated stuff – such as the code we wrote for the Super
Cool Text Box control, the actual Text Box and so on – and turn it into something simple,
our end product.
Wondering where to go next? Here are a few control ideas I thought about whilst having a
shower this morning:
• Improved Timer Control – The current Timer that ships with Visual Basic fires
off, at the very least, once every 65535 milliseconds (just over a minute).
Sometimes I want a timer to fire every ten minutes or so and end up writing code
to increment a timer counter, fire off, reset the counter and start again from the
beginning. It gets very sticky – though all this work could be encapsulated into a
control.
• Date Picker Control - You could take Microsoft's existing Date Picker control
and add your own unique properties. For instance, IsWeekend (Boolean),
FirstDayOfMonth (Date) and LastDayOfMonth (Date). If you wanted to be really
groovy, I'm sure an IsPublicHoliday (Boolean) would also be greatly appreciated!
• Marquee Control – How about creating a control that scrolls text along a Text
Box or Label? I guess you'd use the Timer control to activate the movement, and
change the Interval depending on how fast you wanted the text to move.
• Do That API Thang – As the VB-World.net API section (www.vb-world.net/api/
<http://www.vb-world.net/api/>) shows, you can do a lot of groovy stuff with API
calls. For instance, you could spice up the Text Box control by adding new
features (<http://www.vb-world.net/controls/textboxex/>). Or include new
properties in the Tree View control, such as 'BackgroundColour' – currently only
changeable via API calls.
... and the list goes on!
So go ahead and let us know how you progress! Feel free to post your achievements right
here on our bulletin board.
If you're interested in what other programmers are getting up to, you might want to check
out:
• Progress Control <http://www.vbweb.co.uk/dev/?progress_control.htm> –
See how the guys at VBWeb created a progress control that throws Microsoft's
Progress Bar right out the window.
• Chart Control <http://www.vbsquare.com/articles/graph/> – Learn how our
very own Sam Huggil decided the Microsoft Chart control was too big to

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


distribute with his applications – so created his own version! (I'd also like to
mention that Sam has a couple of neat ActiveX control tutorials here
<http://www.vbsquare.com/activex/>.
• Hyperlink Control <http://www.vbweb.co.uk/dev/?progress_control.htm> -
Once again, the chaps behind VBWeb dress to impress with this groovy Hyperlink
control. (More controls from VBWeb here
<http://www.vbweb.co.uk/dev/controls.htm>).
• Visual Dice Control <http://www.vbexplorer.com/dice/dice_1.asp> – Check
out how VBExplorer knocked up a visual die for potential use in games.
Check these out, look at the source code, learn how they work. That's the best way to
continue exploring ActiveX controls.
You may also want to check out the VB-World.net Component Source store
<http://www.vb-world.net/php-bin/vbwstore.php?pid=51>, which lists dozens of
commercial third-party controls.
Conclusion
This week, we've figured out how you can pack your groovy ActiveX control into a neat
setup package.
We went on to tie up any loose ends – and discussed how to change the toolbar control
image, how class IDs work, figured out raising errors in code, took a peek at products to
help with resizing and creating trial programs, looked at the Ambient object, plus even
skimmed over how we can get our control online.
The tutorial then (finally) concluded with a look at what others have done with controls,
plus a roundup of ideas for future practice.
Whew, I think we need a rest!
Hopefully this tutorial has helped you understand how to create your own ActiveX
controls, plus given you an even greater knowledge of Visual Basic. I hope it gets you a
better job, a pay rise, and possibly a small island near Hawaii. A girlfriend wouldn't go
amiss neither.

Err, just don't forget me, OK?


But whatever you get up to, in and out of the Visual Basic realms, I'd like to wish you all
the very best – and thanks for joining me in our adventurous trip to ActiveX land.
So until the next time, this is Karl Moore signing off, hoping you all have a pleasant
evening, wherever you are. Goodnight!

ActiveX Control Tutorial - Part 2


By Karl Moore
Introduction
Bonjour and welcome to the second part in this jabber-wockingly cool ActiveX tutorial.
As ever, I'm your surprisingly sophisticated host Karl Moore – and this week we'll be
covering:

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


• Creating property procedures
• Enumeration (whoah!)
• Dealing with resizing
• Some other stuff
If you missed part one, it's probably a good idea to check it out before reading on - click
here!
I can see you're getting all giddy now, so let's don our anoraks and thick glasses as we hop
on the pink boat destined for the fluffy world of ActiveX controls...
[Ed: What?]
Size Matters
Today, we're going to start creating an advanced text box.
In just a few clicks of the mouse, we'll allow users of our control to dictate how the text
box works – perhaps it will restrict people to entering just numbers or mere text. This will
be done by setting properties.
We'll also make the text box automatically translate characters to upper case, lower case –
or any ol' case.
So let's get going...
• Start up Visual Basic
• Create a new 'ActiveX Control' project
• Add a text box to your workspace
For the moment, don't worry about sizing or positioning or whatever. These things do
matter – just ask my girlfriend – but we'll deal with them later.
• Rename the text box to 'txtTextBox'
• Remove 'Text1' from the Text property
We haven't really done much yet, but let's test it so far.
• Click File, Add Project
• Select 'Standard EXE'
• Add your 'UserControl1' control from the toolbox direct onto Form1
Your screen should look a little something like this:

Notice how the text box inside our control doesn't automatically resize itself?
• Right click on 'Project2' in the Project Explorer and click Remove Project, not
saving any changes
The text box doesn't automatically resize because as of yet, we haven't told it to. Oh, and
'cause Visual Basic is about as smart as the winner of last year's "World's Scruffiest Bloke"
competition.
• Click View, Code to enter the code window
• Select UserControl from the Object drop-down box
Don't forget that the UserControl is just your control. When something happens to it,
certain events fire – such as Initialize, Resize, LostFocus and so on. It's the equivalent of
the Form object in regular programming, where you have events such as Load and
Unload.
• Select Resize from the Procedure drop-down box
• Add the following code to your project:

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Private Sub UserControl_Resize()
With txtTextBox
.Height = UserControl.ScaleHeight
.Top = UserControl.ScaleTop
.Left = UserControl.ScaleLeft
.Width = UserControl.ScaleWidth
End With
End Sub
Here, we're resizing the dimensions of the text box depending on various properties of the
UserControl object.
The UserControl object is there to tell you how your user is playing with the control. So if
they resize it, the Resize event fires – and you grab the new ScaleHeight, etc. properties,
reorganising your controls as such.
In our project, we simply set the text box properties equal to the exact UserControl Scale
properties. Of course, if you had more than just one simple text box to resize – you'd have
to start with a few Einstein-like calculations – but for now, I'll spare you the pleasure.
Go ahead and test the control– just as we did earlier.
See what happens? Whenever the user resizes your control, the text box follows!
My test project looks like this:

Sure, it's about as stunning as Queen Elizabeth's bottom, but this is only the second
tutorial...
[Ed: So by the last instalment should we expect something akin to Pamela Anderson?]
Decisions, Decisions...
Now I want the person using this control to be able to decide whether the text box should
accept just letters, numbers or both – and whether letters entered should be converted to
upper or lower case.
So I've already determined two possible properties:
• AcceptType – should it hold just letters, numbers or both?
• ConvertCase – automatically convert to upper case, lower case or neither?
But how will the user tell me which they wish to use? I could perhaps tell them to set
AcceptType=1 if they wish to hold letters, 2 if they only require numbers and so on. Err,
but that ain't too user friendly. And you know how darn picky those users get.
This is where enumerations come into play. Yessiree, that's another geeky word designed
to scare off potential programmer types. But it's really very simple.
• Back in your project, open the code window
• Enter the General Declarations section
• Select (General) from the Object drop-down box and (Declarations) from the
Procedure drop-down box
• Type in the following code:
Public Enum CharacterType
All
Numbers
Letters
End Enum

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Let me explain what's happening here; the first line simply tells Visual Basic we're creating
an enumeration christened CharacterType. The Public bit just ensures our end users can
see the enumeration.
The next three lines list our options – no spaces allowed. The user can select All, Numbers
or Letters.
Top Tip: You can also assign numbers to each of our options, so All might equal zero,
Numbers might equal one and so on. Lookup the 'Enum Statement' in Visual Basic help
for more information!
That final line of code simply states that the enumeration ends here.
So we've just defined the 'options' for our planned 'AcceptType' property. Now let's add
another enumeration for the 'CaseConvert' property.
• Type in the following code:
Public Enum CaseType
All
UpperCase
LowerCase
End Enum
Hmm, I guess you're not impressed – in fact, I saw more impression the last time I drop a
1st class stamp onto a freshly produced ingot of 22 carat gold. But you will be, as soon as
we get these things working.
Still, that's it for enumerations. Let's add a few properties!
It's a Two-Way Thing
You've played around with properties before. Every time you say...
Text1.Text = "Hello World!"
... you're setting a property. And every time you say...
MsgBox Text1.Text
... you're reading a property.
Because you're now a supercool ActiveX programmer, you're going to have to provide all
this functionality to your end user too.
Now creating properties can get a little bit difficult – so let me try to explain. When you
set a property in code, it runs one bit of code. When you retrieve a property in code, it
runs another piece of code.
So even though you may be setting and retrieving the same property, behind the scenes
two different pieces of code actually fire up. And as you're now working behind the
scenes, you need to know about them.
• Open the code window
• Click Tools, Add Procedure
• In the Name box, type 'AcceptType'
• Click the Property option button
• Hit OK
You should notice the following added to your code window:
Public Property Get AcceptType() As Variant

End Property

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


Public Property Let AcceptType(ByVal vNewValue As Variant)

End Property
Here we have a let and a get. The let piece of code runs when a user tries to set the value
of our AcceptType property. And the get piece runs when someone tries to retrieve the
value of AcceptType.
Apart from that rather important difference, this property lark isn't that dissimilar from
regular subs and functions. You can imagine that the let piece of code is a sub, that
accepts the new value of AcceptType in the passed vNewValue. And the get piece of code
works just like a function – to send information back to the user, you simply set
AcceptType to a specific value.
Following me?
[Reader: Yeah, in the same way the King of Egypt followed Moses...]
Let's take a peek at an example property let and get pair...
Dim strUserName as String

Public Property Get UserName() As Variant


UserName = strUserName
End Property

Public Property Let UserName(ByVal NewUserName As Variant)


strUserName = NewUserName

End Property
Here, we have a local variable called strUserName.
When the property is set...
MyControl.UserName = "John"
... the let procedure runs and sets the value of strUserName.
When the property is retrieved...
MsgBox MyControl.UserName
... the get procedure runs and returns the value of strUserName.
That's exactly how most property procedures work. But we're using enumerations to make
life easier for our end user... yet alas, slightly more difficult for ourselves.
• Change the skeletal property procedures Visual Basic created for us to something
like this:
Public Property Get AcceptType() As CharacterType

End Property

Public Property Let AcceptType(ByVal CharType As CharacterType)

End Property
The only important thing we've done here is to change 'Variant' to 'CharacterType'. If the
user passes a variant, they could be sending anything our way. This way we're saying –

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


you will pass us one of the CharacterType options and nothing else. Haha, the power!!
Muhahaha!
<ahem>
Top Tip: If you wanted the user to just supply a True or False value, you could always
use 'As Boolean' in place of 'As CharacterType'. Or perhaps 'As Integer' or 'As String'.
Now let's add actual code to bring the property procedure to life:
• In the General Declarations section, declare the following:
Dim m_CharType as CharacterType
• Add a little more code to our AcceptType property procedures, changing them to:
Public Property Get AcceptType() As CharacterType
AcceptType = m_CharType
End Property
Public Property Let AcceptType(ByVal CharType As CharacterType)
m_CharType = CharType
End Property
Think about it for a short while. Do you understand what's happening here? The
m_CharType variable stores the actual value.
Top Tip: You're probably wondering why we're bothering to code all these Property
Get/Let statements – when it seems to do just the same job as a public variable. The
difference here is that you have the power to add code behind your Get/Let statements,
whereas with a public variable you have no control whatsoever. In other words, you
could have a property that accepts some usernames – but if they choose 'Admin', you
could tell them to go swizzle. Erm, programmatically speaking, of course.
• Now add the ConvertCase property to your project:
Dim m_CaseType As Integer

Public Property Get ConvertCase() As CaseType


ConvertCase = m_CaseType
End Property

Public Property Let ConvertCase(ByVal CsType As CaseType)


m_CaseType = CsType
End Property
Are you getting acquainted with properties yet? Hah, you see they're not that frightening –
in fact I was more petrified the last time I watched that epic of epic's, Hoger and
Rammerstein's the Sound of Music.
[Ed: So were we – it was your 538th visit!]
Go and Test It!
Now let's test your control!
• Click File, Add Project
• Select 'Standard EXE'
• From the toolbox, add your control to the form
Click on the control and take a peek at the properties window. Do you see the
'AcceptType' and 'ConvertCase' properties?

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html


If you click on any of our custom designed properties, you should be presented with a
combo box – enabling you to select any of our defined options!
Try changing the options. Does it work?
Note the numbers next to each option. These are automatically added by Visual Basic.
Now try adding a command button – and insert code behind it that changes our two
properties in code. Notice that just after you type...
Control.OurProperty =
... it allows you to select one of our options, making your code much easier to read. Isn't
that pleasing!?
Now, using the instructions I gave you last week, set the Standard EXE project as 'startup'
– then run it, both setting and reading our properties in code.
Did it all work? What happens when you read the properties?
'UserControl1' isn't a very professional name. Why not try changing it to something like
'TextBoxPro' using the techniques we explored last week?
Conclusion
This week we've started work on our wizzy intelligent text box control. We discussed
resizing and then explained properties.
We went on to put two of our own properties in place – both of which supported
enumerations, making it easier for the end developer and ensuring code is easy-to-read.
Next week, we'll build on what we started today – and will find out just how those
enumerations can start to make our life a lot easier. We'll also add a host of new
properties, code a few methods plus add our own custom events – the easy way!
But until next week, this is your fantabulous host Karl Moore, saying goodnight for
tonight. Goodnight!

No license: PDF produced by PStill (c) F. Siegert - http://www.this.net/~frank/pstill.html

Вам также может понравиться