[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 237
  • Last Modified:

Creating a homemade control at runtime

I have an app that uses a home-made active X control.  This control uses certain tools that require a dongle for it to work properly.  All well and good.  The problem I am facing is that not all of my users want/have paid for the added functionality this control gives.  I need for this control not to be on my form unless certain conditions are met.  If the conditions are met, then I need it to be created.  

I found a tutorial here: http://www.vbexplorer.com/VBExplorer/vb_feature/april2000/april2000.asp.  The first method it mentions is using a control array.  This won't work for me, because you have to have a template control on the form.  That defeats my purpose.  The other method that is mentioned seems to allow for the spontanious creation of generic controls (i.e. text boxes, combo boxes, check boxes, etc).  

I've seen references to GetObject/CreateObject, but that doesn't seem to apply to controls.  I'd be happy to be wrong in this guess though.  =)

Does anyone have a way to create a non-generic control at run time without needing one to be on the form originally?

0Thanks for any ideas.
~Melissa
0
MelissaEvans
Asked:
MelissaEvans
  • 6
  • 4
1 Solution
 
rspahitzCommented:
I'm not sure why it's a problem having one on the form...it's just a matter of setting its visible property = True or False.

Otherwise, the CreateObject method should work if the object is registered (although I haven't specifically tried it)

Dim xxxMyControl as Object
Set xxxMyControl = CreateObject("MyObjectsRegisteredName")
...
If AllowedToShowMyControl then
  xxxMyControl.visible = true
End If
...

Maybe you can show some of your non-working code if the above does not work.
0
 
amebaCommented:
>other method that is mentioned seems to ...

So, you didn't try the other method (Controls.Add).

CreateObject doesn't work for normal controls.  Controls are special type of objects, which usually has to 'sit' on some container - it cannot be created without container.
0
 
MelissaEvansAuthor Commented:
I have tried to add the item to the controls collection, but I'm not sure how to tell it what it is.  The tutorial mentions how to get to VB library stuff (textbox, comobox...), but not something my coworker made.  

I got a test version to work by creating a dinky usercontrol and using

Dim ctlMyTest As ctlTest
Set ctlMyTest = Form1.Controls.Add("Project2.ctlTest", "ctlTest")
ctlMyTest.Visible = True

But the real one isn't going to be in a project I can get to (it was made in VC++ and all I have access to is the finished .ocx file).  

The making invisible idea doesn't work because it looks for the dongle somewhere in initialization.  If it doesn't find the dongle, it dies even if the ocx isn't used at all.  I'm looking through the source code for the control to see what it's doing in the init to make it want to see the dongle, and I don't see anything besides a stub for the init.  I'm not sure why it looks so soon, but I don't think I can make it not do that.

~Melissa
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
MelissaEvansAuthor Commented:
In the bit of code that I said I got to work, I copied the wrong version.  The first line should read
Dim ctlMyTest As VBControlExtender

~Melissa
0
 
amebaCommented:
If you have OCX, this string: "Project2.ctlTest" will be different.  First part "Project2" is Library name.

If you add reference to OCX, you can press F2, and in Object Browser, first select Library in the first Combo - initially that combo shows "<All Libraries>".

When library is selected, you'll see a list of classes... and that makes the second part of your string (class name).
0
 
amebaCommented:
Hope you know the name of your control.  Here is some code, which also handles event:

Option Explicit
Dim WithEvents ctlDynamic As VBControlExtender

Private Sub ctlDynamic_ObjectEvent(Info As EventInfo)
    ' test for the click event
    If Info.Name = "Click" Then
        Caption = "You clicked " '& ctlDynamic.object.selecteditem.Text
    End If
End Sub

Private Sub Form_Load()
    'Licenses.Add "AmPic.AmPictureBox"
    Set ctlDynamic = Controls.Add("AmPic.AmPictureBox", _
        "myctl", Form1)
    ' set the location and size of the control.
    ctlDynamic.Move 0, 0, ScaleWidth, ScaleHeight
    Set ctlDynamic.object.Picture = LoadPicture("g:\sve\amoeba1.gif")
    ctlDynamic.Visible = True
End Sub

Private Sub Form_Resize()
    On Error Resume Next
    ctlDynamic.Move 0, 0, ScaleWidth, ScaleHeight
End Sub
0
 
MelissaEvansAuthor Commented:
Thanks for getting me started.  I need to play with it some more to make it work for the moment though.  The first error I get says:

"Cannot add control '<library>.<class>'.  Dynamically adding ActiveX Controls requires the use of the ProgID which can be different from LibraryName.Class for some controls.  The ProgId for this control is '<newlib>.<newclass>'."

I was all excited, it looks like an actully *useful* error message!  So I try to use that newlib.newclass and I get the error:

"The ProgId is too long.  The ProgId must be 39 characters or less."

Sure enough, the new one is 40 characters long.  I'll talk my coworker into renaming his control so hopefully this'll go away and I'll award points.  =)

~Melissa
0
 
amebaCommented:
Or, if you can have reference to OCX, this is better (it has different declaration):

Option Explicit
Dim WithEvents ctlDynamic As AmPic.AmPictureBox

Private Sub ctlDynamic_Click()
    Beep
End Sub

Private Sub Form_Load()
    'Licenses.Add "AmPic.AmPictureBox"
    Set ctlDynamic = Controls.Add("AmPic.AmPictureBox", _
        "myctl", Form1)
    ' set the location and size of the control.
    ctlDynamic.Move 0, 0, ScaleWidth, ScaleHeight
    Set ctlDynamic.object.Picture = LoadPicture("g:\sve\amoeba1.gif")
    ctlDynamic.Visible = True
End Sub

Private Sub Form_Resize()
    On Error Resume Next
    ctlDynamic.Move 0, 0, ScaleWidth, ScaleHeight
End Sub
0
 
amebaCommented:
ProgID can be different - version number added e.g. "MSComctlLib.ListViewCtrl.2" or completely different.

You can try 1 thing:
- add reference and use my last sample - maybe you will be able to use LibraryName.Class and it will be correctly resolved if there is a reference.

Or use 2 versions of the form - one with control and one without.  Control will not Initialize if Form is not loaded.

Or, maybe try re-parenting the control:
Load another form with the control, and use SetParent to move it to the right form.
0
 
MelissaEvansAuthor Commented:
I tried to add the .ocx as a reference, but I had to remove it from the components first.  I got the same error.  

Putting the control on a seperate form that isn't loaded worked though!  Thank you!

~Melissa
0
 
amebaCommented:
Thanks for the points, I'm glad you solved it!
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now