Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 554
  • Last Modified:

How to call VB AvtiveX with Visual C++

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
{
public:
      _ScpMngr() {}            // Calls COleDispatchDriver default constructor
      _ScpMngr(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
      _ScpMngr(const _ScpMngr& dispatchSrc) : COleDispatchDriver(dispatchSrc) {}

// Attributes
public:

// Operations
public:
      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
0
fbtcell
Asked:
fbtcell
  • 4
  • 4
1 Solution
 
NorbertCommented:
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.
0
 
fbtcellAuthor Commented:
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.
0
 
gashevCommented:
ActiveX EXE,DLL or Control?
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
fbtcellAuthor Commented:
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.
0
 
NorbertCommented:
yes id does. what you can do is following
LPDISPATCH Connect(LPCTSTR RegisteredNameOfActiveX)
{
            USES_CONVERSION;

            CLSID
                  ClsId
                  ;
            LPCOLESTR
                  OleStr=T2COLE(RegisteredNameOfActiveX);/*Uni-code*/
            HRESULT
                  hr;
            LPDISPATCH
                        Disp=NULL;
                  
            /* Get the class identifier from the program identifier */
            if((hr=CLSIDFromProgID(OleStr,&ClsId))==S_OK)
            {      

      hr=CoCreateInstance(ClsId,NULL,CLSCTX_ALL,IID_IDispatch,(void**)&Disp);


                  if(hr!=S_OK)
                  {
                        CString
                              String
                              ;
                        String.Format(_T("CoCreateInstance() returned error 0x%x\n"),hr);
                        AfxMessageBox((LPCTSTR)String);
                        Disp=NULL;
                  }
            }
            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.
0
 
NorbertCommented:
sorry for bad formatting EE strips out the tabs
0
 
fbtcellAuthor Commented:
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
0
 
NorbertCommented:
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
/Embedding
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.
0
 
fbtcellAuthor Commented:
Thanks, i have found with your help, Norbert



Finally, it works !!!

This is the code :

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



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

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

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

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


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
- AND ABOVE ALL, INSTALL SERVICE PACK 3 OF VISUAL STUDIO
  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).
0
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.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 4
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now