How to call VB AvtiveX with Visual C++

Posted on 2000-03-03
Last Modified: 2013-12-14
I wrote an ActiveX with Visual Basic 6.0.
I imported it in Visula C++ (6.0 again).
It created an header file (.h) and a
source file (.cpp) from this ActiveX.
The header file begins like this :

class _ScpMngr : public COleDispatchDriver
      _ScpMngr() {}            // Calls COleDispatchDriver default constructor
      _ScpMngr(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
      _ScpMngr(const _ScpMngr& dispatchSrc) : COleDispatchDriver(dispatchSrc) {}

// Attributes

// Operations
      void QuitScope();
      void AcqStop();

How can I launch the ActiveX (just creating an instance of the Class didn't work, may be I should use CreateDispatch, GetProperty or these kind of functions come from COleDispatchDriver Class).

Thank you
Question by:fbtcell
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
  • 4
  • 4

Expert Comment

ID: 2579987
How did you create the class _ScpMngr ?
because you derived it from COleDispatchDriver I know you are using MFC.
The easiest way to generate a wrapper for an OCX I know is using the classwizard but not using add class ->From a Type library - I guess you used that - it is much more easier to add an ActiveX control to a Dialog Resource and use classwizard to add a member variable for that control. Classwizzard will add header and cpp files wrapping the ActiveX creating is done automatically when the dialog is created.
if you do not need the control inside a dialog you still have a ready made class to use it.

COleDispatchDriver - as I know - is more useable for Automation objects.

Author Comment

ID: 2581007
The ActiveX i created with Visual Basic is in fact a standard EXE from which i added a Class (ScpMngr) to allow using it with a customize program.
In Visual Basic the type of this ActiveX is "EXE ActiveX".
I think i won't be able to add this ActiveX to a Dialog Resource.
That's why i added it using the classwizard.

Expert Comment

ID: 2588962
ActiveX EXE,DLL or Control?
Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.


Author Comment

ID: 2590655
As i said in my previous comment, it's an ActiveX EXE.
Anyway, Visual C++ seems to do the same with an EXE and with an OCX when i import it by classwizard.

Expert Comment

ID: 2590732
yes id does. what you can do is following
LPDISPATCH Connect(LPCTSTR RegisteredNameOfActiveX)

            /* Get the class identifier from the program identifier */


                        String.Format(_T("CoCreateInstance() returned error 0x%x\n"),hr);
            return Disp;
Now the function Connect returns a Dispatch Pointer.
You can use this returned pointer to setup your COleDispatchDriver derived class using
m_MyActiveX=new _ScpMngr(Connect(RegisteredNameOfActiveX);
this is verry similar to VB's
dim O as object
set o=CreateObject(RegisteredNameOfActiveX);

and like VB you now can call the member functions of the activeX using the wrapper functions classwizzard had generated for you.

Expert Comment

ID: 2590744
sorry for bad formatting EE strips out the tabs

Author Comment

ID: 2591581
Norbert, i didn't be able to run properely your example :

- I had to include afxpriv.h in my module
- CoCreateInstance returned 800401F0
(CO_E_NOTINITIALIZED : CoInitialize has not been called)

- In Connect function i called first CoInitializeEx with COINIT_APARTMENTTHREADED parameter (i had to include objbase.h and to define _WIN32_DCOM).
So Connect function seemed to run properely, by my object has not been well initialized (the EXE quit with an error at 0x0000000 when i call the first member function)

May be i didn't created well my project (it's a MFC AppWizard exe / Dialog based)

Thank you for your help

Accepted Solution

Norbert earned 30 total points
ID: 2591887
the code above is a peece of working code.
CoInitialize is called at an other place so in my code it is not inside the Connect function. but to be honest I never tried to start an outproc server written with VB.
My Servers are all written using Visual C++ some with ATL and some with MFC
The include of afxpriv.h I have added to stdafx.h
objbase.h should be included by afxdisp.h which is one of the standard files inside the stdafx.h.
That it is a dialog based app is don't care. I also have a dialog based app connectig to a com server that works very well.

Now to figure out what happens is not simple. First of all I would suggest
rebuild your VB program enabeling writing the pdb files ( you will found the checkbox to do that at
Project properties -> Compile->CreateSymbolicDebug Information)  
Enabeling PDB you will be able to debug VB code within the IDE of visual C.

Because the ide can't read the project file you are not able to open it. But you can open the EXE and your frm or what else files by hand. opening the exe you are able to debug the application. You are able to set breakpoints inside your vb APP using your source code.

goto project settigs and inside the debug section add
as program argument
set breakpoints anywhere you want. May be at beginning all functions you want to call from the client.

now press F5 and start debug session.

Now start an other copy of devStudio and load and start debugging your client application.

Have a look: is the breakpoint inside the first DevStudio reached ?
and is it the function you have expected?
if yes you are able to debug it and have a look what is going wrong

if not reached any breakpoint I am sorry to say that you have to step into MFC functions to see what is gong wrong.

if the wrong function is reached you probably changed someting inside the VB program after you have generated the wrapper class with class wizard.
regenerate the wrapper and all should be fine.

hope that helps.
I have a termin now so today I am unable to give you more support today but I am back tomorrow inside the office.
feel free to ask if something is unclear.

ps: Greetings from Germany

if the Connect function seems to work the application is already running at the end of the connect function.

Author Comment

ID: 2592560
Thanks, i have found with your help, Norbert

Finally, it works !!!

This is the code :

void CMyDlg::OnOK()
COleException e;
CLSID clsid;
CString String;
BOOL isok;

if ((hr = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED)) != S_OK)
      String.Format(_T("CoInitializeEx() returned error 0x%x\n"),hr);

if ((hr=CLSIDFromProgID(OLESTR("RegisteredNameOfActiveX"), &clsid)) != S_OK)
      String.Format(_T("CLSIDFromProgID() returned error 0x%x\n"),hr);

scope = new _ScpMngr;
isok=scope->CreateDispatch(clsid, &e);

if (isok == 0)
      String.Format(_T("CreateDispatch() returned error 0x%x\n"),e.m_sc);

Then use member functions of scope object ...

For people who want to try this kind of application, i had to :
- Include afxpriv.h and objbase.h files
- Define the preprocessor option : _WIN32_DCOM
  Without SP3, CreateDispatch(clsid, &e) returned with error at
  0x000005 or something like that ...
  and CreateDispatch("RegisteredNameOfActiveX", &e) returned
  error REGDB_E_CLASSNOTREG (Class not registered) !!!!
  (CLSIDFromProgID worked fine without SP3).

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

734 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