How to access a Visual Basic ActiveX DLL in Visual C++
SUMMARY
This article shows three ways to access a Visual Basic ActiveX DLL
from a Visual C++ executable. The information in this article applies
to: Microsoft Visual C++, 32-bit Editions, version 6.0 (Method 1 &
2 also for v5.0)
Steps to Create the Visual Basic Server
Create a Visual Basic ActiveX DLL project. Class1 is created by default.
Add the following code to Class1:
Public Function testdll(para As String) As
String
MsgBox "Parameter passed in: " & para
testdll = para
Exit Function
Err_Handler:
testdll = Err.Description
End Function
Compile the DLL as c:\Project1.dll and exit Visual Basic.
Method 1 - CreateDispatch:
1. Start Visual C++ and choose MFC AppWizard (Exe) to create a MFC(exe)
project tst1.
2. Select ClassWizard on the View menu, pick Ctst1App in the Class
Name box, and double-click InitInstance in the Messages box. Click
Edit Code to bring up the code for BOOL CTst1App::InitInstance(),
find the line AfxEnableControlContainer();, and add the following
line before it:
AfxOleInit();
Note: you also can do this through AppWizard. When create the project,
click the 'Automation' option.
3. Select ClassWizard from the View menu and click the Automation
tab. Click AddClass and select "from a TypeLibrary". Specify Project1.dll
(the Visual Basic DLL).
4. Open your AppName.cpp file and add the line #include "Project1.h".
You need to include Project1.h wherever you have code that accesses
project1.dll.
5. Open the ClassWizard again. On the Message Maps tab, select CAboutDlg
in the Class Name box and IDOK in the Object IDs box, and then double-click
BN_CLICKED. Click OK in response to the dialog box and OK again to
close the ClassWizard.
Open AppName.cpp, scroll to the bottom to theCAboutDlg::OnOK(), and
replace it with the following code:
void CAboutDlg::OnOK() {
CString retStr;
CString inputStr = "Hello!"
BSTR bstrVal = inputStr.AllocSysString();
_Class1 p;
p.CreateDispatch("testdll.Class1");
retStr = p.testdll(&bstrVal);
MessageBox(retStr);
CDialog::OnOK();
}
6. Compile
your .exe file (F7).
Run the .exe file and select About on the Help menu. Click OK on the
About box and the message box that was specified in project1.dll appears.
Click the Close button to dismiss the dialog box. And another message
box specified in VC++ appears.
Method 2 - #IMPORT:
Start Visual C++ 6.0 and create a Win32 Console Application. To add
a new C++ source file to the project. Add the following code into
the new source file:
#include <afx.h> // This is the path
for your DLL. Make sure that you specify the exact path.
#import "c:\windows\system\testdll.dll" no_namespace
void main() {
BSTR bstrDesc;
try {
CoInitialize(NULL);
CString str("Hello!");
BSTR bstrVal = str.AllocSysString();
BSTR strReturn;
char *strDisp;
_Class1Ptr ptr;
ptr.CreateInstance(__uuidof(Class1));
strReturn = ptr->testdll(&bstrVal);
strDisp = _bstr_t(strReturn);
MessageBox(NULL, strDisp,"VC++", MB_OK);
} catch(_com_error &e) {
bstrDesc = e.Description();
}
CoUninitialize();
}
Compile and run your project.
The message box from Project1.DLL and VC++ should appear.
The #import method can be used in a Win32 Application, a Console Application,
or in MFC as well.
Method 3 - Pure COM Interface
Start Visual C++ and select New from the File menu. Choose MFC AppWizard
(Exe), name the project tst1, and click OK. When the MFC Appwizard
dialog box appears, select Dialog Based and click Finish. Click OK
when the next dialog box appears.
The Resource Editor is started by default. Delete all the controls
on the dialog box and add a Command button on it, retaining the default
caption "Button1".
Double-click Button1 to display the Add Member Function dialog box.
Click OK to accept the name OnButton1.
Click OLE/COM Object Viewer on the Tools menu. Select View Typelib
from the File menu and choose the Project1.dll you created earlier.
Click Open to display the ITypeLib Viewer, which contains the .idl
file for your DLL.
Copy the contents of your .idl file (contents of the right pane) to
the Clipboard.
Click New on Visual C++ File menu. Select Text File on the New dialog
box, name the file test1.idl, and click OK.
A blank text file appears. Paste the data from the Clipboard into
it and save the file.
Select Settings from the Project menu, expand the tst1 and Source
Files nodes of the tree view, and select test1.idl. Click the MIDL
tab, enter test1.h in the "Output header file name" box, and click
OK.
Open tst1Dlg.cpp and add the following files to the includes section:
#include <initguid.h>
#include "test1.h"
Click the ClassWizard on the View menu, select Ctst1App in the Class
Name box, and double-click InitInstance in the Messages box. Click
Edit Code to bring up the code for:
BOOL CTst1App::InitInstance()
Find the line:
AfxEnableControlContainer();
Add the following line before it:
AfxOleInit();
Open the ClassWizard again. On the Message Maps tab select CTst1Dlg
in the Class Name box and IDC_BUTTON1 in the Object IDs box. Double-click
BN_CLICKED in the Messages box, and click Edit Code to bring up the
code for void CTst1Dlg::OnButton1(). Replace the OnButton1() function
with the following code:
void CTst1Dlg::OnButton1() {
// TODO: Add your control notification handler code here.
_Class1 *pClass = NULL;
IUnknown *pUnk = NULL;
// HRESULT hr = CoCreateInstance(CLSID_Class1,NULL
// CLSCTX_INPROC_SERVER,IID__Class1,(void **)&pClass);
// You can directly get the Interface ID as in the previous line or
// you can do a QueryInterface on IUnknown to get the IID
// as in the following three lines:
HRESULT hr = CoCreateInstance(CLSID_Class1,NULL,CLSCTX_INPROC_SERVER,
IID_IUnknown,(void **)&pUnk);
hr = pUnk->QueryInterface(IID__Class1,(void **)&pClass);
pUnk->Release();
// Once you have the IID, you can make use of the interface pointer
// to access our Visual Basic DLL.
CString cstrVal("Hello");
BSTR st1;
BSTR st = cstrVal.AllocSysString();
hr = pClass->MyVBFunction(&st,&st1);
pClass->Release();
}
Compile your .exe file (F7) and run your application (F5). Click Button1
in the dialog box. The message box from the Visual Basic DLL appears.
|
|