Implements and CreateObject

Posted on 2000-03-03
Last Modified: 2008-02-26
I have written an ActiveX EXE that exports a IExtender class so I can write DLLs that extend my app later. This class declares a Run method (with empty body) that extensions will need to implement. During initialization, this app looks in the Registry for a specific key indicating what extensions are present and must be loaded. For each one, my app reads from the Registry their progid (Server.Class) in a strProgId variable and does a 'Set ext = CreateObject(strProgId)' to create the extension object and be able to later invoke its Run method. Notice that ext is declared 'Dim ext As IExtender'.

I have created am ActiveX DLL that has a MyExtension class that implements IExtender. I have registered it. My app detects it and reads its progid. The, the CreateObject fails because error 13, Type Mismatch.

MyExtension implements IExtender, so what's not working ok?.

Question by:CesarGon
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Expert Comment

ID: 2581114
If you use CreateObject to make an instance of the IExtender you will write

Dim ext as IExtender
Set ext=CreateObject("MyExtension.IExtender")

There is other way to instanciate a class:

Dim ext as new IExtender

Now you don´t need use the CreateObject


Author Comment

ID: 2581215
I know, but:

- I cannot use CreateObject with "MyExtension.IExtender" because componen MyExtensions does not have an IExtender class. Its typelib does not has it so I will get an error if I try. COM won't event create the object.

- I cannot use "Dim ext As New IExtender" because that creates a IExtender object, and I want a MyExtension object. IExtender is an abstract interface (therefore it starts with an 'I') andis not intended to be instatiated.

The thing is: CreateObject works ok, and if I write


Author Comment

ID: 2581225
(sorry, I go on from the previous interrupted comment)

....if I write

Dim ext As Object
Set ext = CreateObject("MyExtension.ExtensionClass")

it works ok, but I cannot statically check that the object created implements the IExtender interface.

Any ideas?
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 2581474

I quickly created a similar project in order to test exactly what you are trying to do (without the registry access, but hardcoding the ProgID in the )... In my case it worked perfectly! So you are doing nothing wrong, at least not architecturally speaking...

I don't think that the 'Type Mismatch' error is coming from the interface implementations ...
My best guess is that you probably have a type mismatch error which is caused during your Class_Initialize() of the ExtentionClass ! You must know that this WILL be executed whenever you try to access the implemented interface like you do in your 'Set ext = CreateObject("MyExtention.ExtentionClass")' statement.

Another possibility might be that you are not using the same version of the IExtend in the MyExtention dll... But I assume you are referencing the ActiveX EXE (project references setting) from within the MyExtention DLL ? And I hope you have the binary compatibility set in the ActiveX EXE also ? So this is less likely to be the problem....

I hope this will help you out !


Expert Comment

ID: 2583017
It sounds to me like there is some reason why you don't want to get a reference to the EXE server. Is this correct? Otherwise, why would you want to be screwing around with prog ID's and such. I've never tried to get VB to reference a server with just progids and such so I have no idea what you are doing. However, I had the same problem problem you did recently. And it has to do with references. If you want to implement an interface from a server, you will definately have to have a refernece to the server from the project by which you want to use the server. In my case, I had three projects. I was referencing the actual EXE when I actually should have been referencing the VBP. I felt pretty stupid when I figured it out, but it is not hard to do when you have multiple projects involved.

Author Comment

ID: 2587639
PatrickVD, please re-post your comment as an answer so I can give you the points: in fact, the problem was with the binary compatibility of the EXE server.

I had project compatibility set, because is VB's default and I never care to think about that. What's really the difference?.


Accepted Solution

PatrickVD earned 350 total points
ID: 2589018
Hi César,

Well, because you so kindly request it ..

<< Snippet of my previous comment >>
A possibility might be that you are not using the same version of the IExtend in the MyExtention dll... But I assume you are referencing the ActiveX EXE (project references setting) from within the MyExtention DLL ? And I hope you have the binary compatibility set in the ActiveX EXE also ?
<< End of snippet >>

I'm happy to see you finally managed to figure out what was going wrong !

As an extra...

The compatibility setting is something very important when it comes to releasing your components to the 'outside world'.
Actually, as you probably know, VB does a lot of things behind the scenes... Especially when it comes to COM object/components.
As a matter of fact, this compatibility setting has a direct impact on the way VB generates the UUID's for the classes (CLSID) and interface (IID).

NO COMPATIBILITY: In this situation, each time you compile your component, VB will generate NEW CLSIDs and IIDs for each public classmodule in your ActiveX component. When a client was already using it before, and you compile a new version, the client will not be able to use this new version. Nevertheless, in this mode the old version remains configured in the Registry, and if you kept the original DLL/EXE/OCX, the client will continue to work with the old version. The new version will never be usable unless you recompile the client application with a reference (Project-References) to the new version.

PROJECT COMPATIBILITY: By default VB sets itself into Project compatibility, which is not a bad thing when you are still developing the component before releasing it for usage by clients. Whenever you compile a new version with this compatibility mode, VB6 will keep the CLSIDs constant only, as long as you keep the classmodule methods and property prototypes constants. Nevertheless, for the IID, this is not the case. This is what might cause a problem with a client application, because in order to have a completely compatible component, both the CLSID and IIDs must remain constant !
There is still one advantage to this mode compared to 'No Compatibility': when you recompile, VB will UNREGISTER the previous version from the registry before registering the newly compiled version. Still, as far as the client applications are concerned, you will have to recompile with a reference to the new version (you will see the old one mentioned as 'MISSING' in Project-References).
[Sidebar: If you where using Project Compatibility in VB5, the both CLSID and IIDs would be generated. Only the advantage of un-registering the previous version would be usefull for this setting.]

BINARY COMPATIBILTY: This is actually the only right setting for a component if you want to expose it to the outside world, and guarantee compatibility with future versions of the component that you will build. In this situation, VB will keep both CLSIDs and IIDs constant for the existing classmodules (no new ones are created, unless you added a new class/interface). Additionally, VB will first perform a check to see that any modification you made might 'break' this compatibility with previous versions of the component... This also means that whenever you compile a new version of your component (as long as you respect the compatibility of your classmodules' properties/methods) you will NOT have to recompiled the older client applications for them to continue working. The new applications can use the newly added classmodules/interface in the new version, but old applications will continue working on the old interfaces.

How does this relate to your problem ? Quite simply, if you have project compatibility set, (In VB6) whenever you recompiled your ActiveX EXE, the CLSIDs where the same but not the IIDs. Since you 'implement INTERFACES (IIDs) and those are changing on each compile, you can now understand why you got the error. :-)

Hope this gives you a good idea about the compatibility settings.. If you want more info just let me know.



Author Comment

ID: 2590892
Great, Patrick. Are you giving seminars on VB & COM?

Expert Comment

ID: 2590971
Hi César,

Thanks for accepting.

I'm not at all in the seminar business... I'm just another freelance developer on the market... who knows quite a lot on VB/COM/MTS/SQL7/etc...

Hope to see ya around !


Featured Post

MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

Question has a verified solution.

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

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…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
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…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

726 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