Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help Request: "Class Not Registered"

11 views
Skip to first unread message

gheoop

unread,
Jun 23, 2010, 8:58:24 AM6/23/10
to
Hello,
I get this error after having run, from within the IDE, an application
which contains an OCX of mine (developed in VC and using MFC).
Please note that the component is regularly
recognized and can be added to the project toolbox. So I can use it
in my project and can even run the project a first time, without
problems. But when the program terminates, while going back to the development
environment VB produces the above mentioned error. The only solution
I have found, so far, is to exit the IDE and restart it, add again the OCX to
the
toolbox, etc.

ralph

unread,
Jun 23, 2010, 12:48:17 PM6/23/10
to
On Wed, 23 Jun 2010 07:58:24 -0500, gheoop <ghe...@domain-xyz.in>
wrote:

This is a particularily nasty error because of the way the IDE maps
external components through the vb6debug.dll and their current OCA -
thus due to the several layers of indirection it can be difficult to
isolate exactly what the IDE is complaining about.

But some suggestions:

Been awhile since I done the MFC COM model (perferring ATL myself) so
I can't be specific, but recheck your MFC component to make sure you
are not prematurely releasing it or otherwise doing anything too
creative when the state of the control is changing from 'running' back
to 'design'.

Make sure you are chewing on the animal you think you are.
Clean-up both projects.
Delete any .OCAs (VB will recreate as needed)
Make sure you have only one compiled component (*below).
Do a Registry Clean.
Make sure you have only one Registry entry and it points to the
correct component.
Reset the VB Project Reference/Components to that component.
Run a Dependency Walker to make sure it isn't perhaps another
component that is mis-matched.

* You can have several Registry entries, eg. a debug OCX and a release
OCX, but make sure your VB Reference/Components is pointing to the
correct component and that that component does exist. If you are using
this scenario insure the filesnames and Prog/App IDs are also unique -
not an issue with VC++ but can be with VB.

hth
-ralph

gheoop

unread,
Jun 24, 2010, 9:51:05 AM6/24/10
to
ralph wrote on 06/23/2010 12:48 ET :
> On Wed, 23 Jun 2010 07:58:24 -0500, gheoop
First of all thanks Ralph for the attention and interest over this
&quot;unpleasure&quot; question.
We are all over this problem, focused how to fix it. I have used
&quot;fix&quot;
'cause this entire situation is not present on VC++ and VB.Net version of the
exactly same ocx.
For giving a bit more details we are now focused on the analysis of the memory
during the execution of the ocx ( important note on this control is its
dimension, about 5 megabytes ). Some exceptions are founded about the way we
close some windows, but we trust is something else that make the mentioned
error
( We trust otherwise the correct execution on VC++ and B.Net is not
explainable).

GheoOp

ralph

unread,
Jun 24, 2010, 3:16:56 PM6/24/10
to
On Thu, 24 Jun 2010 08:51:05 -0500, gheoop <ghe...@domain-xyz.in>
wrote:

> We are all over this problem, focused how to fix it. I have used
>&quot;fix&quot;
> 'cause this entire situation is not present on VC++ and VB.Net version of the
> exactly same ocx.
> For giving a bit more details we are now focused on the analysis of the memory
> during the execution of the ocx ( important note on this control is its
> dimension, about 5 megabytes ). Some exceptions are founded about the way we
> close some windows, but we trust is something else that make the mentioned
>error
> ( We trust otherwise the correct execution on VC++ and B.Net is not
> explainable).
>

It is not uncommon for this to be the case for owner controls written
with other languages or frameworks. In fact I should probably say
*very common*.

[Note: I was a VC/VC++ programmer long before I dabbled in VB. So I
can understand a certain amount of superior thinking when experienced
with a "real" programming language and then having to work with ...
Ugh! ... VB! Been there, done that. However such feelings are
dangerous and will only lead to trouble. And here is why ...
<g>]

First off, appreciate that the 'basic rules' for how an ActiveX
Control should behave with a client came from the orginal VB product,
and mostly by adopting convenient conventions - ie, not from any
high-level scholarly brain-tank.

Therefore while us 'real' programmers know of multiple ways to manage
a COM component and COM interfaces, VB knows of only one (or rather
variations of a single theme).

Second, VB conveniently hides most of COM/OLE away from the User by
Design. Just like its Form Engine hides away the details of creating
windows, setting up WinProcs, etc. Therefore, a control must behave
as VB expects. If not, there is very little adjustment that can be
made on the VB side of things. Nor very little that can be done on the
control side to *force* VB to do something different.

Thus what VB wants is what VB needs to get. Or, to put it another way,
VB's management of ActiveX controls is THE defacto standard. No matter
if us 'real' COM programmers know a better way.

In the old days, it was common to create a "ransom note" VB
application to test our VC++ ActiveX COM components. Essentially a
blank VB app to plop the control on top of and test. If it worked
there it was good to go. We often did this before the actual object
code was written - just stubs.

The most common area where third-party controls go wrong is with
Interfaces and Interface Inheritance. By rule any published interface
can be derived from another. When working with a VC++ client we can
directly manipulate by simple casts/conversions/offsets etc. to get
any animal we need, or equally be assured we are dealing with the
correct animal. And as already noted - with raw COM - there is always
more than one way to get a result. VB on the other hand doesn't have a
facility for doing that - Interfaces are derived by its own built-in
coercion rules.

Also a common mistake is to pass non-VB OLE datatypes, or worse to
some MFC one. VC++/MFC and .Net have access to a greater variety than
VB does.

Thus, yes an ActiveX component build with MFC will work just fine with
a MFC client, because you had a programmer familar with both sides
writing it. Any problems and the programmer "fixes" it on the spot.

[Oops said derived above - meant it in its de-reference sense, but you
get the idea.]

Based on the error I highly doubt you will find any mysterious memory
or other internal issues with your component. The problem will be
found in how your component is presenting itself and an unexpected
(from VB's point of view) change in who VB thinks he is talking to
when you change from 'run-time' to 'design-time'. (Look carefully at
any aliasing or clever pointer handling.)

It has been ten years since I've worked with the MFC model for ActiveX
controls, but I vaguely remember it had a few Gotchas. They were IIRC
mostly concerned with Automation which should not be an issue in your
scenario. But ... ?

I've always preferred ATL. ATL has the advantage of direct
class/object templates for creating ActiveX components and Interfaces
classes VB and VBA expect to see. The MFC classes for the same support
is more of a bolt-on after-thought.

The actual Interface portion of your control is (or should be) rather
straight-forward, and like all COM components essentially separate
from the co-classes that support it. If you can't find the problem -
you might consider simply creating a ATL component with the published
interface (and stubbed objects beneath) and test it with a VB/VBA
applications. If it works - it would be a simple process to migrate
your MFC objects over.

Whew! Sorry I'm so windy.
Hth
-ralph

gheoop

unread,
Jun 25, 2010, 5:33:00 AM6/25/10
to
ralph wrote on 06/24/2010 15:16 ET :
> On Thu, 24 Jun 2010 08:51:05 -0500, gheoop
> wrote:
>
>> We are all over this problem, focused how to fix it. I have used
>> &amp;quot;fix&amp;quot;

>> 'cause this entire situation is not present on VC++ and VB.Net version of
the
>> exactly same ocx.
>> For giving a bit more details we are now focused on the analysis of the
memory
>> during the execution of the ocx ( important note on this control is its
>> dimension, about 5 megabytes ). Some exceptions are founded about the way we
>> close some windows, but we trust is something else that make the mentioned
>> error
>> ( We trust otherwise the correct execution on VC++ and B.Net is not
>> explainable).
>>
>>
>>
>>
> It is not uncommon for this to be the case for owner controls written
> with other languages or frameworks. In fact I should probably say
> *very common*.
>
> [Note: I was a VC/VC++ programmer long before I dabbled in VB. So I
> can understand a certain amount of superior thinking when experienced
> with a &quot;real&quot; programming language and then having to work with ...

> Ugh! ... VB! Been there, done that. However such feelings are
> dangerous and will only lead to trouble. And here is why ...
> &lt;g&gt;]

>
> First off, appreciate that the 'basic rules' for how an ActiveX
> Control should behave with a client came from the orginal VB product,
> and mostly by adopting convenient conventions - ie, not from any
> high-level scholarly brain-tank.
>
> Therefore while us 'real' programmers know of multiple ways to manage
> a COM component and COM interfaces, VB knows of only one (or rather
> variations of a single theme).
>
> Second, VB conveniently hides most of COM/OLE away from the User by
> Design. Just like its Form Engine hides away the details of creating
> windows, setting up WinProcs, etc. Therefore, a control must behave
> as VB expects. If not, there is very little adjustment that can be
> made on the VB side of things. Nor very little that can be done on the
> control side to *force* VB to do something different.
>
> Thus what VB wants is what VB needs to get. Or, to put it another way,
> VB's management of ActiveX controls is THE defacto standard. No matter
> if us 'real' COM programmers know a better way.
>
> In the old days, it was common to create a &quot;ransom note&quot; VB

> application to test our VC++ ActiveX COM components. Essentially a
> blank VB app to plop the control on top of and test. If it worked
> there it was good to go. We often did this before the actual object
> code was written - just stubs.
>
> The most common area where third-party controls go wrong is with
> Interfaces and Interface Inheritance. By rule any published interface
> can be derived from another. When working with a VC++ client we can
> directly manipulate by simple casts/conversions/offsets etc. to get
> any animal we need, or equally be assured we are dealing with the
> correct animal. And as already noted - with raw COM - there is always
> more than one way to get a result. VB on the other hand doesn't have a
> facility for doing that - Interfaces are derived by its own built-in
> coercion rules.
>
> Also a common mistake is to pass non-VB OLE datatypes, or worse to
> some MFC one. VC++/MFC and .Net have access to a greater variety than
> VB does.
>
> Thus, yes an ActiveX component build with MFC will work just fine with
> a MFC client, because you had a programmer familar with both sides
> writing it. Any problems and the programmer &quot;fixes&quot; it on the spot.
I appreciate a lot your judgement and you suggestions.
However, an ATL re-writing would be probably too engaging,
as you will apreciate better from the details I
supply here below.

I have done some experimentation creating a new
OCX and incrementally adding some of the features
of the 'real' one. Among these: ODBC connection to
Postgres, libpq (native) connection to Postgres/Postgis,
intensive usage of Stingray Studio librarie, etc.
So far, the 'dummy' version DOES work properly and comes
back to design mode without problems.
Unfortunately, it is not easy to go ahead this way,
as the OCX is quite complex, both in size (several hundred
thousand lines of code) and in structure. The single OCX
contains in fact 3 components and all 3 of them have been
used for more than 10 years in several MFC-based containers.
However the VB6 issue remains even when I #ifdef out 2 of
the 3 components.

In addition, one of the 3 components implements a
COM Automation, which we have been using for long time
to develop customized solutions written, you guess, in VB6 !

The big difference is that now we need to use the
WHOLE ocx from VB6, and not only the Automation interface.
Pleas note this too: from a VB.NET 2008 client there are no
registration issues. It works (with the help of some
AxImp generated support).

By the way, while investigating this issue, I found
some memory leaking and (maybe) occasional heap corruption.
Though these seem not too damaging, judging from the
acceptable stability of our C++ containers, I intend to
get rid of them as soon as possible. Are you aware of
any good, possibily open-source, tool to track this kind
of problems in a Visual C environment ? In the very remote
past I bought a commercial library (MemCheck) which seems
gone by now.

Thank you again for you precious help ralph.

ralph

unread,
Jun 25, 2010, 9:43:37 AM6/25/10
to
On Fri, 25 Jun 2010 04:33:00 -0500, gheoop <ghe...@domain-xyz.in>
wrote:

>
> By the way, while investigating this issue, I found
> some memory leaking and (maybe) occasional heap corruption.
> Though these seem not too damaging, judging from the
> acceptable stability of our C++ containers, I intend to
> get rid of them as soon as possible. Are you aware of
> any good, possibily open-source, tool to track this kind
> of problems in a Visual C environment ? In the very remote
> past I bought a commercial library (MemCheck) which seems
> gone by now.
>

I'm going back through my notes and the dusty drafting parts of my
memory to see if I can remember anything that might help with that
error.

As for Memory Leaks - I'm in the same boat. (Ghod I miss NuMega. <g>)

I've tried a few commercial products ($$$+) but have found that using
C++ built-in debug memory methods,
http://www.codeguru.com/forum/showthread.php?t=312742), WinDbg, and
then grinding it out one damn line/block at a time is the only thing
that seems to work in the end. <g>

-ralph


ralph

unread,
Jun 25, 2010, 10:07:00 AM6/25/10
to
On Fri, 25 Jun 2010 04:33:00 -0500, gheoop <ghe...@domain-xyz.in>
wrote:


Still chewing ...

In the meantime take a look at this
http://edndoc.esri.com/arcobjects/9.0/ArcGISDevHelp/DevelopmentEnvs/COM%5CVB6%5CVBEnvGeneral.htm#Working_With_HRESULTs
(Tried to find a better site, but this will give you a clue on the
basics.)
Scroll down to "Working With HRESULTS".

This is not referring to the same problem (you are not writting in
VB), but the point is VB is catching an COM error and passing it on,
but hiding the actual HRESULT - letting you know only that it is
annoyed.

You might do the same with your OCX, log or raise what might be
"minor" errors. For example, in VC++/.Net we have the luxury of
ignoring returns - VB doesn't.

[OR I may only be delusional. <g>]

Also it is apparent it is not the primary component interface that is
the problem - it lies with something lower.

hth
-ralph

0 new messages