Watch, Follow, &
Connect with Us

Welcome, Guest
Guest Settings
Help

Thread: Why so many problems getting my ActiveX working in RS 10 Seattle???


This question is not answered. Helpful answers available: 1. Correct answers available: 1.


Permlink Replies: 5 - Last Post: Jan 15, 2016 3:36 PM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
Robert Miller

Posts: 6
Registered: 9/2/01
Why so many problems getting my ActiveX working in RS 10 Seattle???  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 14, 2016 12:50 PM
Since about 2003, I have been selling my product that generates USB code for both Embarcadero and Microsoft compilers. I have a VCL component that does all the heavy Windows API calls, and from the beginning, I supplied the VCL version (in precompiled form) for my Delphi users, and for users of other compilers, I have supplied this same component as an ActiveX control, made by Delphi from my VCL control. Until now, the ActiveX control has been strictly 32-bit.

This approach has been working well for years. It used to be extremely easy to convert a (32-bit) VCL control to a (32-bit) ActiveX control with legacy products like Delphi 7.

But nowadays, my customers want me to supply a 64-bit ActiveX as well, since M$ Visual Studio requires a 64-bit ActiveX if they want to compile their code for 64-bits.

I have managed to successfully compile and run both 32-bit and 64-bit versions of my VCL control in RS 10 Seattle Update 1. I have gone through the exercise of making both a 32-bit and a 64-bit ActiveX controls with this compiler -- conversions of the working VCL control installed in this IDE.

Delphi tells me that these ActiveX's compile and install and import OK, but they don't actually WORK.

For example, even the simpler 32-bit control imports OK, and it shows up in the list of registered ActiveX controls in the Import ActiveX wizard, but when I try to place the imported wrapper component onto a Delphi form, I get an error message "Class not registered" -- even after I register it again!

And yes, I know I have to use TLibImp.exe to import the 64-bit ActiveX.

I have spent days doing this, and meticulously documenting each step that I take, but I must be missing something.

I'd like to start out by asking a set of questions that the documentation never gets around to clearing up.

1) Even the 32-bit Wizard no longer automatically handles licensing. The documentation doesn't tell you how to add licensing to your ActiveX control. It looks as if all you need to do is to add a GUID to the 6th one of the arguments of the call to TActiveXControlFactory.Create() in the initialization section of the .pas unit that the ActiveX wizard generates. Is that sufficient, or is there something else I need to do.

(FWIW, even if I leave the generated empty string in this argument, making the ActiveX control unlicensed, it still doesn't work. That's the 32-bit version that gives the "Class not registered" error message. )

2) If I provide both 32-bit and 64-bit versions of the ActiveX, should these use the SAME licence string (GUID), or should the 64-bit version use a DIFFERENT license string (GUID) to avoid conflict with the 32-bit version?

3) I see that the Import Wizard cannot work automatically to make a VCL wrapper from a 64-bit ActiveX, so we have to use TLibImp.ex instead of the Import Wizard. But can we use the ActiveX wizards to successfully make a 64 bit ActiveX from a working VCL control? Or do we have to use external command line utilities like GenTLB.exe as part of the process? If so, what do we DO?

4) Since the Import Wizard does not work automatically for importing a 64-bit ActiveX control, we are expected to perform more steps, involving external command line utilities. The documentation is sketchy on the details, so it is very easy to slip up and end up with something that doesn't work. I have not found any better information online, so can anyone here provide a set of steps to follow that will actually work?

I sure would appreciate any suggestions anyone could make... Thanks in advance for any help offered!

Edited by: Robert Miller on Jan 14, 2016 12:53 PM
Remy Lebeau (Te...


Posts: 8,201
Registered: 12/23/01
Re: Why so many problems getting my ActiveX working in RS 10 Seattle???[Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 14, 2016 1:27 PM   in response to: Robert Miller in response to: Robert Miller
Robert wrote:

But nowadays, my customers want me to supply a 64-bit ActiveX as
well, since M$ Visual Studio requires a 64-bit ActiveX if they want to
compile their code for 64-bits.

Only if the ActiveX control is an in-process server (loaded into the calling
process). 64bit code can use a 32bit out-of-process server (running in its
own process).

If your ActiveX control is 32bit in-process, and you are having trouble updating
it to 64bit, you could always just keep it as 32bit and then register a 32bit
DLL Surrogate to host it as an out-process server.

DLL Surrogates
https://msdn.microsoft.com/en-us/library/windows/desktop/ms695225.aspx

Windows even provides a default DllSurrogate for this propose. Or you can
write your own custom surrogate.

64bit code can then talk to the 32bit surrogate, which will delegate to your
32bit control.

For example, even the simpler 32-bit control imports OK, and it shows
up in the list of registered ActiveX controls in the Import ActiveX
wizard, but when I try to place the imported wrapper component onto a
Delphi form, I get an error message "Class not registered" -- even
after I register it again!

HOW are you registering it? ActiveX registration is sensitive to many factors
- user account, 32bit/64bit, which in turn is senstive to Registry virtualization,
etc.

--
Remy Lebeau (TeamB)
Robert Miller

Posts: 6
Registered: 9/2/01
Re: Why so many problems getting my ActiveX working in RS 10 Seattle???[Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2016 8:36 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Robert wrote:

But nowadays, my customers want me to supply a 64-bit ActiveX as
well, since M$ Visual Studio requires a 64-bit ActiveX if they want to
compile their code for 64-bits.

Only if the ActiveX control is an in-process server (loaded into the calling
process). 64bit code can use a 32bit out-of-process server (running in its
own process).

If your ActiveX control is 32bit in-process, and you are having trouble updating
it to 64bit, you could always just keep it as 32bit and then register a 32bit
DLL Surrogate to host it as an out-process server.

DLL Surrogates
https://msdn.microsoft.com/en-us/library/windows/desktop/ms695225.aspx

Windows even provides a default DllSurrogate for this propose. Or you can
write your own custom surrogate.

64bit code can then talk to the 32bit surrogate, which will delegate to your
32bit control.

For example, even the simpler 32-bit control imports OK, and it shows
up in the list of registered ActiveX controls in the Import ActiveX
wizard, but when I try to place the imported wrapper component onto a
Delphi form, I get an error message "Class not registered" -- even
after I register it again!

HOW are you registering it? ActiveX registration is sensitive to many factors
- user account, 32bit/64bit, which in turn is senstive to Registry virtualization,
etc.

--
Remy Lebeau (TeamB)

First of all, Remy, I hope that somebody out there is paying you about a million bucks a year for the help you continue to provide to everyone. I have always gotten great help from reading your replies to me or anyone else. Thanks, for all you do!

My ActiveX was originally created by the ActiveX Wizard of the legacy compilers like Delphi 7. So it has been my understanding, from explanations in Eric Harmon's book Delphi Com Programming, that this was an in-process com server.

I will certainly study your link about DLL Surrogates. However, Embarcadero claims that RAD Studio 10 Seattle Pro is capable of producing 64-bit ActiveX controls, Since all of my code generators are set up to use those, I would prefer not to have to rewrite a dozen code generators at this time. I would greatly prefer to produce a 64-bit in-process ActiveX that can work with my existing generated code.

By the way -- I still have the Delphi source code that was originally generated by the legacy compiler. Several years ago, I found that compiling this for Win32 in Delphi XE2 produced a working Win32 ActiveX. Is it possible that compiling that legacy code for Win64 could produce a working 64-bit ActiveX?

HOW are you registering it? ActiveX registration is sensitive to many factors
- user account, 32bit/64bit, which in turn is senstive to Registry virtualization,
etc.

What I tried to do was to copy the 64-bit OCX (that Delphi compiled) to C:\Windows\System32, which I believe uses Microsoft's 64-bit regsvr32.exe to do the registration. I believe this is supposed to registers the ActiveX for all users. Here is the error message I get from Microsoft regsvr32.exe:

"The module 'HAX_1_4_10S.ocx' failed to load.

Make sure the binary is stored at the specific path or
debug it to check for problems with the binary or
dependent .DLL files.

Invalid access to memory location."

(The Microsoft error message is not very informative. WHAT memory location has the invalid access?)

I have not tried to use RAD Studio's TRegSvr.exe to register the 64-bit ActiveX. I should do that, in hopes that it might produce some more useful information than Microsoft did.

Please note that I have even tried to get RAD Studio 10 Seattle to make a new 32-bit version of my ActiveX from my working VCL control that I had installed into 10 Seattle. I used the menu item to register the new Win32 ActiveX, and then after I closed that project, I used menu item Component | Import to import the 32-bit ActiveX and make a wrapper control.

The next time I started RS 10 Seattle, I saw the wrapper control on the Component Palette. However, when I tried to USE that wrapper control by placing it on the main form of a little test program, the IDE gave me an error message "Class not registered."

This is one of those ambiguous error messages that drives me crazy. WHICH class is not registered? Not registered with WHAT? Is the ActiveX not registered with Windows? Or is it the wrapper class that is not registered with Delphi?

Re-registering the ActiveX did not change this, so it would seem that it is the class of the wrapper control itself that is (somehow) not registered with Delphi.

By the way, I then ran Microsoft's AxImp.exe to import this 32-bit ActiveX into Microsoft land, and used Visual Studio 2013 to verify that the 32 bit ActiveX works -- which also shows that it was in fact registered.

So I am blocked in 2 ways.
1) The 64-bit ActiveX fails to register with Windows, for reasons unknown. If it cannot register with Windows, I cannot even test it.
2) The 32-bit ActiveX seems to register with Windows, but it fails to register with Delphi.

By the way, lest anyone think that I am a Delphi hater, I most definitely love Delphi, and I have found it to be the most productive programming platform on the planet.

For a client, I have even tried to port this control to C#, so they could compile their apps for "any platform" in Visual Studio. But in trying to port this, I have run into dozens of concrete ways that Delphi makes things much easier for you than .NET. Generally, I find that when I run into some problem that I don't know how to handle, Delphi already has a 1-line solution, but Microsoft makes you write 20 lines or more, AFTER it takes up a lot of your time just trying to find out HOW to write that 20-line solution at all. Embarcadero's claim that "RAD Studio speeds development by up to 5X" is true, and probably an understatement.

If I ever get this thing working, I will post what I did here, so others can help. It looks to me as if ActiveX is kind of a dusty corner that most people don't come to anymore, and the Delphi documentation is kind of sketchy in spots.

Thanks again for your help. Any further suggestions would be most appreciated!
Remy Lebeau (Te...


Posts: 8,201
Registered: 12/23/01
Re: Why so many problems getting my ActiveX working in RS 10Seattle???[Edit]
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2016 11:34 AM   in response to: Robert Miller in response to: Robert Miller
Robert wrote:

First of all, Remy, I hope that somebody out there is paying you about
a million bucks a year for the help you continue to provide to
everyone. I have always gotten great help from reading your replies
to me or anyone else. Thanks, for all you do!

Sadly, no.

My ActiveX was originally created by the ActiveX Wizard of the legacy
compilers like Delphi 7. So it has been my understanding, from
explanations in Eric Harmon's book Delphi Com Programming, that this
was an in-process com server.

If it is compiled into a DLL or OCX, yes. If it is compiled into an EXE,
no.

Embarcadero claims that RAD Studio 10 Seattle Pro is capable of
producing 64-bit ActiveX controls, Since all of my code generators
are set up to use those, I would prefer not to have to rewrite a dozen
code generators at this time. I would greatly prefer to produce a
64-bit in-process ActiveX that can work with my existing generated
code.

Sorry, I can't help you there. I have never made any 64bit ActiveX controls,
and I don't do very much ActiveX development nowadays (I still use BCB6 for
it), certainly nothing new since Delphi changed to its new DAX framework
anyway.

By the way -- I still have the Delphi source code that was originally
generated by the legacy compiler. Several years ago, I found that
compiling this for Win32 in Delphi XE2 produced a working Win32
ActiveX. Is it possible that compiling that legacy code for Win64
could produce a working 64-bit ActiveX?

I have no idea.

What I tried to do was to copy the 64-bit OCX (that Delphi compiled)
to C:\Windows\System32

You really should not be putting anything into the system folder at all.
Put it under Program Files instead, or a custom folder.

which I believe uses Microsoft's 64-bit regsvr32.exe to do the registration.

You don't need to put the file in Windows' 64bit system folder just to run
the 64bit regsvr32 app.

The next time I started RS 10 Seattle, I saw the wrapper control on
the Component Palette. However, when I tried to USE that wrapper
control by placing it on the main form of a little test program, the
IDE gave me an error message "Class not registered."

The ActiveX control is likely not registered in a section of the Registry
that the user account running the IDE has access to. This is why I asked
how you were registering the ActiveX control. You have to take All-User
vs Per-User registration into account, and also Registry virtualization when
dealing with 32bit vs 64bit. Remember that the IDE itself is 32bit, and
as such can only load 32bit VCL components and 32bit ActiveX controls at
design-time.

This is one of those ambiguous error messages that drives me crazy.
WHICH class is not registered? Not registered with WHAT? Is the
ActiveX not registered with Windows? Or is it the wrapper class
that is not registered with Delphi?

"Class not registered" is a COM/ActiveX error that says the requested CLSID
is not registered with Windows for the calling user.

1) The 64-bit ActiveX fails to register with Windows, for reasons
unknown. If it cannot register with Windows, I cannot even test it.

You can test it, if you load it manually at runtime. In your 64bit code,
you can bypass CoCreateInstance() and call your OCX's exported DllGetClassObject()
function directly. Request the IClassFactory interface from it, and then
call IClassFactory.CreateInstance() to create your ActiveX control. Now,
whether you can do that inside of whatever you are using to wrap the ActiveX
control, I have no clue. But just for testing purposes, you can use this
approach to exercise your ActiveX's interfaces directly. If they work as
intended, they should work within the wrapper should CoCreateInstance() be
able to find the registration correctly (which is a separate issue).

--
Remy Lebeau (TeamB)
Robert Miller

Posts: 6
Registered: 9/2/01
Re: Why so many problems getting my ActiveX working in RS 10Seattle???[Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2016 1:44 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Robert wrote:

First of all, Remy, I hope that somebody out there is paying you about
a million bucks a year for the help you continue to provide to
everyone. I have always gotten great help from reading your replies
to me or anyone else. Thanks, for all you do!

Sadly, no.

It's a pity. You deserve it.


My ActiveX was originally created by the ActiveX Wizard of the legacy
compilers like Delphi 7. So it has been my understanding, from
explanations in Eric Harmon's book Delphi Com Programming, that this
was an in-process com server.

If it is compiled into a DLL or OCX, yes. If it is compiled into an EXE,
no.

Hmm. How would I compile it into an EXE? And is this in any way related to how I might create a DLL Surrogate in Delphi?

Or can that DLL Surrogate stuff only be done in Visual Studio?

What I tried to do was to copy the 64-bit OCX (that Delphi compiled)
to C:\Windows\System32

You really should not be putting anything into the system folder at all.
Put it under Program Files instead, or a custom folder.

I used to think that as well. We originally delivered and registered our ocx in a subdirectory of our product installation.

But suddenly we started getting strange tech support emails, saying that they were able to compile their
generated code the first day that they installed it, but the very next day, their IDE could no longer access
our ActiveX control.

It turns out that Windows really, really wanted our ActiveX to be installed in C:\Windows\System32\ . It wanted that
so much, that Windows would MOVE our ocx file to System32\ -- but Windows would NOT automatically move our
.lic file, so the .lic file was still in the old directory, and NOT in the same directory as the .ocx. So our ActiveX
would now look like it was unlicensed !

The only fix was to change the install program to install both the .ocx and the .lic file into C:\Windows\System32\
directory. Doing that made the problem go away, never to return.



which I believe uses Microsoft's 64-bit regsvr32.exe to do the registration.

You don't need to put the file in Windows' 64bit system folder just to run
the 64bit regsvr32 app.

But since the 64bit regsvr32 app is located there, and because of what I said above, it seemed like the right thing to do.


The next time I started RS 10 Seattle, I saw the wrapper control on
the Component Palette. However, when I tried to USE that wrapper
control by placing it on the main form of a little test program, the
IDE gave me an error message "Class not registered."

The ActiveX control is likely not registered in a section of the Registry
that the user account running the IDE has access to. This is why I asked
how you were registering the ActiveX control. You have to take All-User
vs Per-User registration into account, and also Registry virtualization when
dealing with 32bit vs 64bit. Remember that the IDE itself is 32bit, and
as such can only load 32bit VCL components and 32bit ActiveX controls at
design-time.
Yeah, I am aware of the ramifications of the 32-bit IDE.

I tried using Delphi's menu item to do an all-user registration. It didn't help.

This is one of those ambiguous error messages that drives me crazy.
WHICH class is not registered? Not registered with WHAT? Is the
ActiveX not registered with Windows? Or is it the wrapper class
that is not registered with Delphi?

"Class not registered" is a COM/ActiveX error that says the requested CLSID
is not registered with Windows for the calling user.

OK, thanks, I'll keep trying, based on your information about this.

1) The 64-bit ActiveX fails to register with Windows, for reasons
unknown. If it cannot register with Windows, I cannot even test it.

You can test it, if you load it manually at runtime. In your 64bit code,
you can bypass CoCreateInstance() and call your OCX's exported DllGetClassObject()
function directly. Request the IClassFactory interface from it, and then
call IClassFactory.CreateInstance() to create your ActiveX control. Now,
whether you can do that inside of whatever you are using to wrap the ActiveX
control, I have no clue. But just for testing purposes, you can use this
approach to exercise your ActiveX's interfaces directly. If they work as
intended, they should work within the wrapper should CoCreateInstance() be
able to find the registration correctly (which is a separate issue).

Very interesting! I will have to figure out how to do all that, but it is definitely worth doing battle with.


--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 8,201
Registered: 12/23/01
Re: Why so many problems getting my ActiveX working in RS10Seattle???[Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 15, 2016 3:36 PM   in response to: Robert Miller in response to: Robert Miller
Robert wrote:

How would I compile it into an EXE?

Create a new blank Application project, and then add an Automation Object
or COM Object to it.

And is this in any way related to how I might create a DLL Surrogate in
Delphi?

If you want to write a custom surrogate, yes. The surrogate is itself a
COM object, just running in an EXE.

Or can that DLL Surrogate stuff only be done in Visual Studio?

I'm sure it can be done with Delphi as well, since it is just standard COM
functions, interfaces, and Registry value. I have not tried it myself, though.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02