From: Webbiz on
This is sort of a branch off of my original quest to create a
contained (drop-in) solution to creating objects for drawing charts
and indicator panels.

Searching through the books and internet on the subject of User
Controls in VB6, what I've learned is this is what is called Active X
controls. I believe it is one and the same. Correct me if I'm wrong.

While testing out the Wizard for creating a User Control, I am
presented with the task of knowing right there and then what methods
and properties I will need. This stopped me in my tracks.

You see, when I was starting to work on the CLASS (cCanvas) itself, I
didn't know what methods or properties I would need until I came to a
problem that needed solving. Only then did I figure I needed this
Property, and this Method, etc. In short, it evolved as I went along.

Sitting there staring at a window (in the Wizard) asking me to tell it
right there and then what Methods or Properties to include was simply
overwhelming.

So why this post?

Because I'd like to know from the User Control pros here whether they
started out first creating a Class Module, tweaking it here and there,
BEFORE finally deciding it was ready for prime time and to turn it
into a User Control. Or what process usually precedes the User Control
Wizard step?

Thanks.

Webbiz


From: mayayana on
>
> Searching through the books and internet on the subject of User
> Controls in VB6, what I've learned is this is what is called Active X
> controls. I believe it is one and the same. Correct me if I'm wrong.
>

It can be. You can compile it to be an ActiveX
control. (OCX) But that's often not relevant if
you're not trying to create something to sit on
a webpage.

> Because I'd like to know from the User Control pros here whether they
> started out first creating a Class Module, tweaking it here and there,
> BEFORE finally deciding it was ready for prime time and to turn it
> into a User Control. Or what process usually precedes the User Control
> Wizard step?
>

You don't need any wizards. Just add a new
UserControl to your project. The UC then shows
up in the "toolbox". (There's an odd bug in the IDE
such that you have to close the UC form window
(as in View Form/View Code) in order to use a UC
from the toolbox.)

I use UCs for subclassing controls, creating
simple compound controls, and providing a base
for API-created controls. If you have them in
your project they get compiled right into the EXE,
so they're highly efficient and don't create an extra
dependency the way that a compiled OCX would.

You can think of a UC as a blank window. VB gives
you size and placement properties, an hWnd, etc.
So a UC can be handled at "design-time" like any
other GUI control. But it does have a few aspects
that are unique. See here for info. about that:

http://pntpm3.ulb.ac.be/Info/Activex/ch17.htm



From: Larry Serflaten on

"Webbiz" <nospam(a)forme.thanks.com> wrote

> While testing out the Wizard for creating a User Control, I am
> presented with the task of knowing right there and then what methods
> and properties I will need. This stopped me in my tracks.
>
> You see, when I was starting to work on the CLASS (cCanvas) itself, I
> didn't know what methods or properties I would need until I came to a
> problem that needed solving. Only then did I figure I needed this
> Property, and this Method, etc. In short, it evolved as I went along.


Unfortunately, designing as you go is a recipe for convoluted code.
Suffice it to say that fixing errors in design is far easier to do before
you have hundreds of lines of code already written....

But for just playing around, it can't hurt to go ahead try this or that
and see how far you get.

The wizard is a helper, it is going to gather some information from you
and then generate the code module from the information gathered.
If you don't know what you'll need, you haven't got the information
to give it. That's OK, move on to the next screen, and keep going
until finished.

When you hit the Finish button, the wizard will fill the code module
with properties and methods, as was indicated during the information
gathering stage. From there on out, the wizard goes away, and anything
else you need you have to add yourself. Its just there to help save on
typing, you still have to write the code that gives your control its functionality....

Just for an example, lets say all you wanted to expose was a BackColor
property and a Draw method to the form, the rest would be handled inside
the control. Start a new project and add a User control, then call up the
interface wizard. On the screen that says "Select Interface Members" hit
the bottom button [ << ] to remove all their selected names, and go find
BackColor in the list on the left. Highlight BackColor, and press the top
button [ > ]

Now hit Next to move on to the next screen.

Viewing the "Create Custom Interface" screen is probably where you got
hung up before, right? Let's say you want to give your control a Draw
method so the form can tell it to draw whatever its supposed to draw.
I don't kow if you really need it, but lets just say thats one method you
want to add....

To add a new method press the New button, type in the name (Draw)
select the Method option and hit OK. With the Draw method showing
in the list, hit the Next button. That brings you to the "Set Mapping"
screen.

Now lets suppose, for that BackColor property you are exposing to
the form, all you are really going to do with that is set the BackColor
of the User Control itself. In the proper terminology, the exposed
property is being mapped to the User Control (it can be any control
you include on the User Control designer).

On that Set Mapping screen, highlight the BackColor method in
the list, and in the Maps To section, select the User Control. The
User Control's own BackColor property is selected automatically,
so leave it there, and hit Next.

On the Set Attributes screen, all the added methods and properties
that didn't get mapped are shown in the list for you to describe
them further. If they take parameters, enter them in the Arguments
section like: "This As Long, That As String" (without quotes)

By default Draw will be a Function, if you want it to be a Sub,
select a return type of Empty. And, just to see where it shows up,
add a description; "Forces a repaint." and hit Next, then hit Finish.

When you get done the wizard will have filled the code module
with the code needed to provide the Draw method and BackColor
property.

You can add more if you want, but imagine how much typing you
would have to do if you wanted to expose all the typical control
properties from Appearance to TextWidth, (about 75 methods,
events, and properties).

That's where the wizard really helps out. You build the control
interface using a GUI, and the wizard types it all out in the code
module.

Take note that exposed properties are handled a bit differently
than normal class properties. That is because they need to be saved
to the FRM file (via a PropertyBag) and loaded again when the
form is loaded.

When you put that control on your form and open the Object
Browser, you'll find that your Draw sub has a description, just
like all the other members in the list. If you plan to give out
an ActiveX control, it is helpful to the programmer to have
those descriptions....

This was only an example, a test to get through the wizard and
see the results. It is still a good idea to know what you are going
to build, before you actually try to build it! :-)

See if that gets you farther along.....
LFS





From: Nobody on
"Webbiz" <nospam(a)forme.thanks.com> wrote in message
news:6e75a55tcm64v5giedolkavrglarn4t7ff(a)4ax.com...
> While testing out the Wizard for creating a User Control, I am
> presented with the task of knowing right there and then what methods
> and properties I will need. This stopped me in my tracks.

Don't be overwhelmed. To quickly learn how they are created(learning by
example), just do it in a new project, and leave the default properties and
methods selections as they are, and just click Next until all is done, then
view the source code generated. Later, place the UserControl on Form1, and
see the list of properties. You can also type in "UserControl1" followed by
"." in Form_Load to see the list of properties and methods. You don't even
have to save the project, just close VB.

In reality, you will need to add the properties and methods that you need.
The wizard allows you to add more later. If you already added properties and
methods, and want to add more, you can use the wizard, or you can copy and
paste from other properties or methods, or create a new dummy UserControl
with the new properties or methods that you want to add, and copy them back
to the original UserControl.

Also, there is a "Map to" feature in the wizard. If you put a PictureBox on
the UserControl, you can "map" some UserControl properties to properties in
the PictureBox. For example, if you map UserControl.BackColor to
Picture1.BackColor, the wizard would generate code so that when
UserControl.BackColor is set, it's forwarded to Picture1.BackColor. This is
done in source code format, there is no mapping settings that is saved in VB
or the project somehow, it's entirely in the source code. You don't have to
use a PictureBox, but if you do, your software would use more system
resources.

Finally, like mayayana suggested, you don't have to create an OCX(ActiveX
Control Project), you can just add the UserControl to your standard EXE
project, and it will be compiled inside the EXE, without needing to ship
additional files.


From: Ralph on
Webbiz wrote:
> This is sort of a branch off of my original quest to create a
> contained (drop-in) solution to creating objects for drawing charts
> and indicator panels.
>
> Searching through the books and internet on the subject of User
> Controls in VB6, what I've learned is this is what is called Active X
> controls. I believe it is one and the same. Correct me if I'm wrong.
>

Not quite, but very similar.
(mayanyana mentioned it as well as the others, but here is some detail to
clarify any misunderstanding over the differences.)

ActiveX is MS's term for any component that supports a COM interface. (Note:
COM is a protocal, OLE is the implementation.) There are many 'standard'
interfaces presented by OLE, and one of them is the ability for an
application to use 'outside' widgets or controls. To create a control using
'raw' COM, a component would need to supply support for things like ...
IOleControl
IOleObject
IOleINPlaceObject
IViewObject
IPersistStreamInit
IProvideClassInfo
IOleInPlaceActiveObject
and so on.
Also consider that an application would have to know what and how to call
these items to use 'outside' OLE Controls.
[Note I provided this list for a reason to be uncovered below.]

Back in the day when OLE Controls were first introduced, they could only be
created by C, and you can imagine what a major undertaking that was. As well
as giving your app the ability to use them. VB, while it couldn't create
them, had the ability to use them. And like everything else "VB" hid all the
details away from the programmer.

[Actually 'controls' and 'custom controls' were first implemented using DDE
and OLE 1. But we mercifully won't go there. lol]

Meanwhile, various developments platforms, such as VC++ MFC, and ATL
encapsulated these elements into 'user control' objects to spare the
developer all the tedious grunt work.

With VB5 VB programmers also gained the ability to create user controls and
VB supplied a new object called, <wait for it ...>, a UserControl! A
UserControl is analogous to a VB Form or VB Class object. Just as those
objects encapsulate and conveniently hide away all the sordid COM/OLE
messaging and event details, the UserControl does the same. UserControl
objects are created with code in a separate .ctl module. (Again analogous to
a .cls or .frm module.)

You can use a UserControl object in your application without resorting to
publishing it in a separate ActiveX component, just as you can use a class
object without publishing it as a DLL. In order to create an ActiveX OLE
Control in VB you must supply at least one UserControl (duh! <grin>).

The reasons you might create an external component is has mayayana noted you
want to resuse the same control in other applications (or web pages). If you
are only using a custom control within a single application, then naturally
you will want to avoided the overhead.

The reason it is important to note that a VB UserControl and an ActiveX OLE
Control are not exactly the same, is because different development platforms
provide slightly different behavior and present a 'sub-set' of the possible.
For example, VB and ATL support composite controls, MFC doesn't (though can
be done with extra work). MFC supports IPersistMemory, ATL and VB don't. And
so on.

And then of course there is the usual exceptions you run into when running
an object as part of your application code and when running it separately
inproc.

> While testing out the Wizard for creating a User Control, I am
> presented with the task of knowing right there and then what methods
> and properties I will need. This stopped me in my tracks.
>

You have two Wizards. One to create a VB ActiveX component which needs at a
very minimum one UserControl, and one to create a VB UserControl. Note that
again this is analogous to creating an internal Class or creating an ActiveX
DLL - the default for the latter is to open an empty Class object (you have
to have one class).

> You see, when I was starting to work on the CLASS (cCanvas) itself, I
> didn't know what methods or properties I would need until I came to a
> problem that needed solving. Only then did I figure I needed this
> Property, and this Method, etc. In short, it evolved as I went along.
>
> Sitting there staring at a window (in the Wizard) asking me to tell it
> right there and then what Methods or Properties to include was simply
> overwhelming.
>
> So why this post?
>
> Because I'd like to know from the User Control pros here whether they
> started out first creating a Class Module, tweaking it here and there,
> BEFORE finally deciding it was ready for prime time and to turn it
> into a User Control. Or what process usually precedes the User Control
> Wizard step?
>

I usually create a UserControl object in an application and then chew and
abuse it until it works the way I want and then either leave it in situ or
migrate to an ActiveX Control.

Note: What mayayana refers to as a 'bug' is defined behavior. Any OLE
control actually has two lives. One is its design-time or 'InPlace'
behavior, and when the control is running within an application. When you
are creating a UserControl object in VB you are actually using the
design-time of the UserControl "builder". You can not test or "use" the
control you are building until you shut-down the UserControl module. (close
the file) After you do that - THEN you can plop your created control on a
Form and test and abuse *its* design-time.

You can run into essentially the same kind of confusion when debugging a
control project with other projects. It is always useful to understand just
exactly who's design-time is running at the time you are peeking. <grin>

hth
-ralph