Solved

Creating a homemade control at runtime

Posted on 2002-06-28
11
206 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
Comment Utility
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
Comment Utility
>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
Comment Utility
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
 

Author Comment

by:MelissaEvans
Comment Utility
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
Comment Utility
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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 15

Expert Comment

by:ameba
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Thanks for the points, I'm glad you solved it!
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…

772 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now