Solved

Creating a homemade control at runtime

Posted on 2002-06-28
11
215 Views
Last Modified: 2008-02-26
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
Comment
Question by:MelissaEvans
  • 6
  • 4
11 Comments
 
LVL 22

Expert Comment

by:rspahitz
ID: 7117529
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
 
LVL 15

Expert Comment

by:ameba
ID: 7117615
>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
 

Author Comment

by:MelissaEvans
ID: 7117624
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
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 

Author Comment

by:MelissaEvans
ID: 7117625
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
 
LVL 15

Expert Comment

by:ameba
ID: 7117636
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
 
LVL 15

Expert Comment

by:ameba
ID: 7117660
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
 

Author Comment

by:MelissaEvans
ID: 7117662
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
 
LVL 15

Expert Comment

by:ameba
ID: 7117663
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
 
LVL 15

Accepted Solution

by:
ameba earned 100 total points
ID: 7117676
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
 

Author Comment

by:MelissaEvans
ID: 7117692
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
 
LVL 15

Expert Comment

by:ameba
ID: 7117854
Thanks for the points, I'm glad you solved it!
0

Featured Post

ScreenConnect 6.0 Free Trial

Explore all the enhancements in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question