Solved

How to call VB AvtiveX with Visual C++

Posted on 2000-03-03
9
518 Views
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
{
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
Comment
Question by:fbtcell
  • 4
  • 4
9 Comments
 
LVL 3

Expert Comment

by:Norbert
Comment Utility
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
 
LVL 1

Author Comment

by:fbtcell
Comment Utility
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
 

Expert Comment

by:gashev
Comment Utility
ActiveX EXE,DLL or Control?
0
 
LVL 1

Author Comment

by:fbtcell
Comment Utility
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
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 3

Expert Comment

by:Norbert
Comment Utility
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
 
LVL 3

Expert Comment

by:Norbert
Comment Utility
sorry for bad formatting EE strips out the tabs
0
 
LVL 1

Author Comment

by:fbtcell
Comment Utility
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
 
LVL 3

Accepted Solution

by:
Norbert earned 30 total points
Comment Utility
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
 
LVL 1

Author Comment

by:fbtcell
Comment Utility
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

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

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…
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org (http://seleniumhq.org) Go to that link and select download selenium in the right hand columnThat will then direct you to their downlo…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

771 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now