If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Get type info for Parent.Controls items

I have been banging my head on this problem all night.

Let's say I have a form with 4 ActiveX controls on it. One of the controls
is supposed to cycle through the controls on the form (available through
the Parent.Controls collection of the control) and perform some action on
those controls depending on whether a certain interface is implemented by
the control. How do I do that?

Parent.Controls(i) returns refernces of type Object and I get a type mismatch
error if I set the Object reference to a variable I dimention typed to an
interface I know is implemented by the control. Also, executing a method
or property on a reference to an ActiveX control returned by the Parent.Controls
collection, which I know it supports, results in an error. I have tried
to access properties in the control through the Object property (eg, MyCustomControl.Object.Tag)
but that also causes an error.

I would even settle for simple type information for the controls, but the
type is "Object" and I can't figure out what the watch window seems to figure
out, which is the underlying type (in the watch window the type columns shows
as "Object/MyControlType"). Aargh, frustration.

Any help would be greatly appreciated, Mike.

Oh, and by the way, I don't want to cross post, but no one has answer my
question on VB.API:

Questions:
1. Can TAPI 3.0 be run on systems other than Windows 2000?
2. If it can, is it possible to just copy the TAPI3.dll file and register
it, or are there other dependency files that need to be installed as well?
3. Is there a place I can get info on using TAPI with VB. The Platform SDK
only includes examples of TAPI 3.0 and I might need to use 2.1 as well.

Re: Get type info for Parent.Controls items

Michael Bourns <mikeb@surfside.com> wrote in message
news:39dd504b$1@news.devx.com...
>
> I have been banging my head on this problem all night.
>
> Let's say I have a form with 4 ActiveX controls on it. One of the
controls
> is supposed to cycle through the controls on the form (available through
> the Parent.Controls collection of the control) and perform some action on
> those controls depending on whether a certain interface is implemented by
> the control. How do I do that?

Are these UserControls you're dealing with here? I'm assuming so. There's
a little gotcha with UserControls: interfaces that they implement are not
available directly through the UserControl reference; you have to use the
UserControl.Object property:

For Each ctl In Parent.Controls
If TypeOf ctl.Object Is XMyControl Then
...
End If
Next ctl

In the same vein, if you want to use a variable, or call methods, you need
to make sure to include the .Object method:

Re: Get type info for Parent.Controls items

"Colin McGuigan" <colin@chicor.com> wrote:
>Michael Bourns <mikeb@surfside.com> wrote in message
>news:39dd504b$1@news.devx.com...
>>Let's say I have a form with 4 ActiveX controls on it. One of
>>the controls is supposed to cycle through the controls on the
>>form (available through the Parent.Controls collection of the
>>control) and perform some action on those controls depending
>>on whether a certain interface is implemented by the control.
>>How do I do that?

Firstly, thanks a lot for the reply.
>Are these UserControls you're dealing with here?

Yes they are.
>There's
>a little gotcha with UserControls: interfaces that they implement are not
>available directly through the UserControl reference; you have to use the
>UserControl.Object property:

I have tried similar code to your example and couldn't get it to work. Specifically:

For Each ctl in Parent.Controls
If TypeOf ctl.Object Is XMyControl <--- This line causes a compiler
error because XMyControl is not a defined type! Apparently the typelib is
not visible, because after I type the "Is" the XMyControl does not show in
Intellisense. I don't understand this. All the controls are on the same
form, in the same project, a standard exe, and yet the typelib of the controls
is not visible (unlike a standard VB dll.)

Also, probably a silly question, but what did you type the loop variable
ctl to be? The reference returned by Parent.Controls is type Object (I see
from the watch window).
>For Each ctl In Parent.Controls
> If TypeOf ctl.Object Is XMyControl Then
> ...
> End If
>Next ctl

You read my mind, with respect to dimensioning variables of type control.
But, I also could not get this to work.

If I write code in a form such as:
Dim x as ProjectName.ControlName <<---No complaints here

lines of code here fail:
Set x.Object = New ControlName

Or

Set x = New ControlName

with an error "Invalid use of New keyword". Basically, what I think is happening
is that the control interface is Public Not Creatable.

Also, if I just Set (don't use New)
set x = ControlName <<-- All I get are the extender properties

Set x.Object = ControlName <<-- run-time error "object not set..." Even
though the form is already loaded, and the usercontrol sited.
>In the same vein, if you want to use a variable, or call methods, you need
>to make sure to include the .Object method:
>
>Set clsMyControl = ctl.Object
>
>ctl.Object.MyMethod
>

What I really want to do is from the Parent.Controls collection of a usercontrol
located on a form, get a reference to another MyUserControl located on the
same form, which I can then use to get a reference to a secondary interface
implemented by the same MyUserControl. Thanks again for your help. Mike.

Re: Get type info for Parent.Controls items

Michael Bourns <mikeb@surfside.com> wrote in message
news:39de07b3$1@news.devx.com...
> Firstly, thanks a lot for the reply.

You're welcome.
> I have tried similar code to your example and couldn't get it to work.
Specifically:
>
> For Each ctl in Parent.Controls
> If TypeOf ctl.Object Is XMyControl <--- This line causes a compiler
> error because XMyControl is not a defined type! Apparently the typelib is
> not visible, because after I type the "Is" the XMyControl does not show in
> Intellisense. I don't understand this. All the controls are on the same
> form, in the same project, a standard exe, and yet the typelib of the
controls
> is not visible (unlike a standard VB dll.)

Hrmm. This is odd. What I had posted before was vaporcode, and I see I made
a mistake; you don't need .Object to check the TypeOf. What I'm posting
here is actual code from one of my projects:

Public Sub WriteControlsToItem(clsItem As IDataItem, colControls As Object)
Dim strTag As String
Dim ctlAny As Control

colControls is a control collection (ie, Parent.Controls). XItemPicker,
XNumericTextBox, BRComboBox, and BRListBox are all UserControls of mine (two
are in the same project, two are in another OCX project), and this works
fine with them. But, anyways, this uses TypeOf against a Control object to
get it's type, and it works fine. If you have a problem with code like
this, there may be another issue with your project. VB can get very flaky.
> Also, probably a silly question, but what did you type the loop variable
> ctl to be? The reference returned by Parent.Controls is type Object (I
see
> from the watch window).

Sorry; should've mentioned. I'd typed 'ctl' as so: 'Dim ctl As Control'
> You read my mind, with respect to dimensioning variables of type control.
> But, I also could not get this to work.
>
> If I write code in a form such as:
> Dim x as ProjectName.ControlName <<---No complaints here
>
> lines of code here fail:
> Set x.Object = New ControlName
>
> Or
>
> Set x = New ControlName
>
> with an error "Invalid use of New keyword". Basically, what I think is
happening
> is that the control interface is Public Not Creatable.

We _are_ talking about controls (as in UserControls) here, right? You can't
use 'New' on a UserControl. However, if you're in VB6, you can use the
Controls.Add method:

Parent.Controls.Add "MyProject.XMyControl", "ctl1"

(where MyProject.XMyControl is the ProgID of the control, and ctl1 is the
name given for the newly created control)
> Also, if I just Set (don't use New)
> set x = ControlName <<-- All I get are the extender properties
>
> Set x.Object = ControlName <<-- run-time error "object not set..." Even
> though the form is already loaded, and the usercontrol sited.

Dim x As Project.ControlName
Set x = ControlName.Object
> What I really want to do is from the Parent.Controls collection of a
usercontrol
> located on a form, get a reference to another MyUserControl located on the
> same form, which I can then use to get a reference to a secondary
interface
> implemented by the same MyUserControl. Thanks again for your help. Mike.

Hrm. Not sure if I understand fully, but:

Dim ctl As Control
Dim clsMyControl As XMyControl

For Each ctl In Parent.Controls
If TypeOf ctl Is XMyControl Then
'Need some way to tell whether this is the same control, or a
different one. I'll use
' a spurious Key property.
Set clsMyControl = ctl.Object
'Can't remember if Me.Key is valid syntax from within a UserControl.
'You get the idea, though.
If clsMyControl.Key <> Me.Key
'You've found your other control. Do whatever.
End If
End If
Next ctl

Re: Get type info for Parent.Controls items

>Specifically:
>>
>> For Each ctl in Parent.Controls
>> If TypeOf ctl.Object Is XMyControl <--- This line causes a compiler
>> error because XMyControl is not a defined type! Apparently >>the typelib
is not visible, because after I type the "Is" the >>XMyControl does not show
in Intellisense. I don't understand >>this. All the controls are on the
same form, in the same >>project, a standard exe, and yet the typelib of
the controls
>> is not visible (unlike a standard VB dll.)

Actually, when you're inside the UserControl none of the other UserControls
on the form are visible in Intellisense. I looked at another project we're
doing that has several dozen controls and loaded the exe project and one
of the custom controls in a project group. Any control that's not a UserControl
appears(eg, DTPicker, Textbox,...) in Intellisense, but NONE of the UserControls
do. I just don't understand. The UCs are in the Toolbox, just like the
other standard Windows controls. I suppose that's how the reference to the
control is managed. I also find it strange that the control doesn't show
in the References dialog. Why not, it's a dll, doesn't it have a typelib?
>Hrmm. This is odd. What I had posted before was vaporcode, and
>I see I made a mistake; you don't need .Object to check the
>TypeOf. What I'm posting here is actual code from one of my
>projects:
...
>Public Sub WriteControlsToItem(clsItem As IDataItem, colControls As Object)
> Dim strTag As String
> Dim ctlAny As Control
>
> For Each ctlAny In colControls
> strTag = ctlAny.Tag
> If strTag <> STRING_EMPTY Then
> If TypeOf ctlAny Is Textbox Then
> clsItem(strTag) = ctlAny.Text

...
> End If
> End If
> Next ctlAny
>End Sub
>colControls is a control collection (ie, Parent.Controls).
>XItemPicker, XNumericTextBox, BRComboBox, and BRListBox are all
>UserControls of mine (two are in the same project, two are in
>another OCX project), and this works fine with them. But,
>anyways, this uses TypeOf against a Control object to get it's
>type, and it works fine. If you have a problem with code like
>this, there may be another issue with your project. VB can get
>very flaky.

I don't know what to say at this point:

1. If TypeOf ctlAny Is Textbox Then <<-- works fine
2. ElseIf TypeOf ctlAny Is XNumericTextBox Then <<-- compiler error.
>We _are_ talking about controls (as in UserControls) here,
>right? You can't use 'New' on a UserControl. However, if
>you're in VB6, you can use the Controls.Add method:

OOops. Humiliation...

I think if I could just get a hold of the typelib for the ocx that I would
be OK. I think I need to think a bit more.

Let me just ask. When you type "ElseIf TypeOf ctlAny Is", and after the
"Is" you hit a space, do your UserControls in the project show up in Intellisense?

Re: Get type info for Parent.Controls items

Michael Bourns <mikeb@surfside.com> wrote in message
news:39de2f7d$1@news.devx.com...
> I think if I could just get a hold of the typelib for the ocx that I would
> be OK. I think I need to think a bit more.
>
> Let me just ask. When you type "ElseIf TypeOf ctlAny Is", and after the
> "Is" you hit a space, do your UserControls in the project show up in
Intellisense?
>
> Thanks again for your help. Mike.

Yes. I hit space, and Intellisense immediately pops 'em up. The only
difference, listening to what you've said, is that my function's a in a BAS
module, and yours is in the UserControl. Move it out to a BAS module, and
pass it the controls collection (As Object) and see what happens.

Re: Get type info for Parent.Controls items

Can you do a control F5, because items sometimes don't show when there are
errors in code.

Are there any item marked as missing under references or components?

Can you give more details. Is the interface the control is implementing in
a typelib or the exe. Is there only the exe project.

Have you tried putting the controls into a seperate OCX project?

Michael Culley

"Michael Bourns" <mikeb@surfside.com> wrote:
>
>"Colin McGuigan" <colin@chicor.com> wrote:
>>Michael Bourns <mikeb@surfside.com> wrote in message
>>news:39de07b3$1@news.devx.com...
>
>
>>Specifically:
>>>
>>> For Each ctl in Parent.Controls
>>> If TypeOf ctl.Object Is XMyControl <--- This line causes a compiler
>>> error because XMyControl is not a defined type! Apparently >>the typelib
>is not visible, because after I type the "Is" the >>XMyControl does not
show
>in Intellisense. I don't understand >>this. All the controls are on the
>same form, in the same >>project, a standard exe, and yet the typelib of
>the controls
>>> is not visible (unlike a standard VB dll.)
>
>Actually, when you're inside the UserControl none of the other UserControls
>on the form are visible in Intellisense. I looked at another project we're
>doing that has several dozen controls and loaded the exe project and one
>of the custom controls in a project group. Any control that's not a UserControl
>appears(eg, DTPicker, Textbox,...) in Intellisense, but NONE of the UserControls
>do. I just don't understand. The UCs are in the Toolbox, just like the
>other standard Windows controls. I suppose that's how the reference to
the
>control is managed. I also find it strange that the control doesn't show
>in the References dialog. Why not, it's a dll, doesn't it have a typelib?
>
>>Hrmm. This is odd. What I had posted before was vaporcode, and
>>I see I made a mistake; you don't need .Object to check the
>>TypeOf. What I'm posting here is actual code from one of my
>>projects:
>...
>>Public Sub WriteControlsToItem(clsItem As IDataItem, colControls As Object)
>> Dim strTag As String
>> Dim ctlAny As Control
>>
>> For Each ctlAny In colControls
>> strTag = ctlAny.Tag
>> If strTag <> STRING_EMPTY Then
>> If TypeOf ctlAny Is Textbox Then
>> clsItem(strTag) = ctlAny.Text
>
>...
>
>> ElseIf TypeOf ctlAny Is XNumericTextBox Then
>> clsItem(strTag) = ctlAny.Value
>
>...
>
>> End If
>> End If
>> Next ctlAny
>>End Sub
>
>>colControls is a control collection (ie, Parent.Controls).
>>XItemPicker, XNumericTextBox, BRComboBox, and BRListBox are all
>>UserControls of mine (two are in the same project, two are in
>>another OCX project), and this works fine with them. But,
>>anyways, this uses TypeOf against a Control object to get it's
>>type, and it works fine. If you have a problem with code like
>>this, there may be another issue with your project. VB can get
>>very flaky.
>
>I don't know what to say at this point:
>
>1. If TypeOf ctlAny Is Textbox Then <<-- works fine
>2. ElseIf TypeOf ctlAny Is XNumericTextBox Then <<-- compiler error.
>
>>We _are_ talking about controls (as in UserControls) here,
>>right? You can't use 'New' on a UserControl. However, if
>>you're in VB6, you can use the Controls.Add method:
>
>OOops. Humiliation...
>
>I think if I could just get a hold of the typelib for the ocx that I would
>be OK. I think I need to think a bit more.
>
>Let me just ask. When you type "ElseIf TypeOf ctlAny Is", and after the
>"Is" you hit a space, do your UserControls in the project show up in Intellisense?
>
>Thanks again for your help. Mike.
>

Re: Get type info for Parent.Controls items

"Michael Culley" <m_culley@one.net.au> wrote:
>Are all the usercontrols in the exe?
Yes.
>Can you do a control F5, because items sometimes don't show when there are
errors in code.
I am aware of this. Actually, I have my options settings such that it compiles
every time I run the project (the "compile on demand" checkbox is not checked.)
>
>Are there any item marked as missing under references or components?
No.
>Can you give more details. Is the interface the control is implementing
in a typelib or the exe. Is there only the exe project.
The interface is in a separate dll that contains just interfaces. I was
just reminded, by rereading some of T. Pattison's book on "Distributed Applications
with COM..." that VB can create standalone .tlb files, and so I will be doing
that from now on.
>Have you tried putting the controls into a seperate OCX project?
Actually, the ocxs are all in their own ocx projects. All of them are compiled,
except the one I have in a project group with the exe which I am debugging.

To be honest, I think I'm making a really dumb mistake. From within the
ocx I am debugging (let's call it ocxDB) I guess I shouldn't be able to see
the other ocxs because the ocxDB doesn't have references to the typelibs
for the other ocxs. Withing the exe I have no problem viewing the ocxs.

I have tried adding references to the oca files to my ocxDB, and sure enough
I then get Intellisense support for the referenced ocxs, but... this code
still doesn't work:

For Each ctl In Parent.Controls
If TypeOf ctl.Object Is MYUserControl Then
nIdx = nCtr
Exit For
End If
Next

It doesn't work, because ctl.Object returns a reference of type "Object".
What I really need is to get the ctl.Object to agree with MyUserControl
for the given control.

Re: Get type info for Parent.Controls items

This is the problem. You can't reference a control that is in another project,
unless that control has a reference to the other project. There are a couple
of solutions:

1) Add a reference to the other project under Project-Components. This is
not a good solution as your 'master' OCX must have all the 'child' ocxs present
to work.

2) Put all the controls in the one OCX project.

3) Create a typelib that all the controls reference and put the interface
in there.

Either 2 or 3 are good solutions depending on your situation.

Michael Culley

"Michael Bourns" <mikeb@surfside.com> wrote:
>
>"Michael Culley" <m_culley@one.net.au> wrote:
>
>>Are all the usercontrols in the exe?
>Yes.
>
>>Can you do a control F5, because items sometimes don't show when there
are
>errors in code.
>I am aware of this. Actually, I have my options settings such that it compiles
>every time I run the project (the "compile on demand" checkbox is not checked.)
>
>>
>>Are there any item marked as missing under references or components?
>No.
>
>>Can you give more details. Is the interface the control is implementing
>in a typelib or the exe. Is there only the exe project.
>The interface is in a separate dll that contains just interfaces. I was
>just reminded, by rereading some of T. Pattison's book on "Distributed Applications
>with COM..." that VB can create standalone .tlb files, and so I will be
doing
>that from now on.
>
>>Have you tried putting the controls into a seperate OCX project?
>Actually, the ocxs are all in their own ocx projects. All of them are compiled,
>except the one I have in a project group with the exe which I am debugging.
>
>
>To be honest, I think I'm making a really dumb mistake. From within the
>ocx I am debugging (let's call it ocxDB) I guess I shouldn't be able to
see
>the other ocxs because the ocxDB doesn't have references to the typelibs
>for the other ocxs. Withing the exe I have no problem viewing the ocxs.
>
>I have tried adding references to the oca files to my ocxDB, and sure enough
>I then get Intellisense support for the referenced ocxs, but... this code
>still doesn't work:
>
> For Each ctl In Parent.Controls
> If TypeOf ctl.Object Is MYUserControl Then
> nIdx = nCtr
> Exit For
> End If
> Next
>
>It doesn't work, because ctl.Object returns a reference of type "Object".
> What I really need is to get the ctl.Object to agree with MyUserControl
>for the given control.

Re: Get type info for Parent.Controls items

"Michael Culley" <m_culley@one.net.au> wrote:
>
>Michael,
>
>>Actually, the ocxs are all in their own ocx projects.
>
>This is the problem. You can't reference a control that is in another project,
>unless that control has a reference to the other project. There are a couple
>of solutions:
>
>1) Add a reference to the other project under Project-Components. This is
>not a good solution as your 'master' OCX must have all the 'child' ocxs
present
>to work.
>
>2) Put all the controls in the one OCX project.
>
>3) Create a typelib that all the controls reference and put the interface
>in there.

Re: Get type info for Parent.Controls items

"Michael Bourns" <mikeb@surfside.com> wrote:
>
>I have been banging my head on this problem all night.
>
>Let's say I have a form with 4 ActiveX controls on it. One of the controls
>is supposed to cycle through the controls on the form (available through
>the Parent.Controls collection of the control) and perform some action on
>those controls depending on whether a certain interface is implemented by
>the control. How do I do that?
>
>Parent.Controls(i) returns refernces of type Object and I get a type mismatch
>error if I set the Object reference to a variable I dimention typed to an
>interface I know is implemented by the control. Also, executing a method
>or property on a reference to an ActiveX control returned by the Parent.Controls
>collection, which I know it supports, results in an error. I have tried
>to access properties in the control through the Object property (eg, MyCustomControl.Object.Tag)
>but that also causes an error.
>
>I would even settle for simple type information for the controls, but the
>type is "Object" and I can't figure out what the watch window seems to figure
>out, which is the underlying type (in the watch window the type columns
shows
>as "Object/MyControlType"). Aargh, frustration.
>
>Any help would be greatly appreciated, Mike.
>
>Oh, and by the way, I don't want to cross post, but no one has answer my
>question on VB.API:
>
>Questions:
>1. Can TAPI 3.0 be run on systems other than Windows 2000?
>2. If it can, is it possible to just copy the TAPI3.dll file and register
>it, or are there other dependency files that need to be installed as well?
>3. Is there a place I can get info on using TAPI with VB. The Platform
SDK
>only includes examples of TAPI 3.0 and I might need to use 2.1 as well.
>
>
>