Implements and CreateObject

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?.

Who is Participating?
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.


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

CesarGonAuthor Commented:
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

Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

CesarGonAuthor Commented:
(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?

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 !

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.
CesarGonAuthor Commented:
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?.

CesarGonAuthor Commented:
Great, Patrick. Are you giving seminars on VB & COM?
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 !

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.