ActiveX Data Objects (ADO) In Visual C++ - Writing the Function

Started by ganeshbala, Apr 21, 2008, 12:43 PM

Previous topic - Next topic

ganeshbala

Writing the Function

Load the <componentname>.cpp file. There you will see your method but with an empty body. This is the place where you will need to write your method.

We start like this:

CoInitialize(NULL);

... to initialize the COM library.

_ConnectionPtr con(__uuidof(Connection));

Make an object of the Smart Pointer of the Connection Interface. It's called _ConnectionPtr. It asks for the CLSID of the Connection class, which is returned to us by the __uuidof method.

con->Open(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source = D:\Work\OnlineBanking\ObFinal\onlinebanking.mdb),_T("user"),_T("pass"),adOpenUnspecified);

We use the Open method of the _ConnectionPtr smart pointer, which is again a part of the Connection interface. We just call it through the Smart pointer. The open method takes the Connection String as the first parameter. This includes the provider name. The data source is the full path to the Access (.mdb) file. Next we have the username and password parameters. Last,y, we have the cursor type.

_CommandPtr cmd(__uuidof(Command));

This makes a Smart Pointer object of the Command Interface. It's called _CommandPtr. It asks for the CLSID of the Command class, which is returned to us by the __uuidof method.

cmd->ActiveConnection = con;

We then initialize ActiveConnection property of the _CommandPtr smart pointer, which is again a part of the Command interface. We call it through the Smart pointer. The ActiveConnection property asks you for the object of the _ConnectionPtr Smart Pointer.

CString sqlstat;
_bstr_t sql(actorName);
sqlstat.Format("select * from '%s'",sql.operator char * ());

Again, all of these are various String types. On the first line we declare a variable sqlstat of CString Type. Next, we declare a variable, sql, of _bstr_t type. This string class takes the value of the string as a parameter in its constructor and that's exactly what we send to it. We send the fieldname string, which is of the BSTR type passed to us by the caller of this Com Component. Next, we use CString's Format function, which will help us create the SQL statement. The .operator char* function helps us put the value of the tablename in place of the %s in the sqlstat CString.

cmd->CommandText = sqlstat.operator LPCTSTR();

Rhere is property called CommandText in the command object. This property must contain the SQL statement that will be executed. We use the .operator LPCTSTR method to typecast our sqlstat CString (which contains the SQL statement) to a type which is accepted by this property.

_RecordsetPtr rtr(__uuidof(Recordset));
rtr->PutRefSource(cmd);

The code above makes an object of the Smart Pointer of the Recordset Interface. It's called _RecordsetPtr. It asks for the CLSID of the Recordset class, which is returned to us by the __uuidof method. We then use the recordset's PutRefSource method to connect our recordset object with our command object.

_variant_t nuller(DISP_E_PARAMNOTFOUND,VT_ERROR);

Next, we declare a variable nuller of the _variant_t type.

rtr->Open(nuller, nuller, adOpenDynamic, adLockOptimistic, adCmdText);

We then use the open method to open our recordset. The open method takes the Source and the Active Connection as its first two parameters. We have supplied the same information in other places so it's fine if we supply NULL variant values here.

The next parameter of the recordset is the cursor type, then we have the lock type. Following on, we have the SQL statement type. This is what type of statement the database should expect. In this case it is adCmdText. It would vary if we were executing a stored procedure or anything else but a simple SQL statement.

rtr->QueryInterface(__uuidof(_Recordset),(void **) ptr);

We use the QueryInterface method of the Recordset object to put the value of the current Recordset into ptr, which must be returned back to the caller of the Com Component. The first parameter is the Interface id of the object we are sending back. The next parameter is an output parameter where the value of the same object must be applied. We typecast it to void** type because that's the data type this method accepts.

The entire contents of <Component>.cpp looks like this:

// adoNow.cpp : Implementation of CadoNow
#include "stdafx.h"
#include "AdoAccess.h"
#include "adoNow.h"

// CadoNow

STDMETHODIMP CadoNow::getRecordSet(BSTR fieldname, _Recordset **ptr)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())

// TODO: Add your implementation code here

CoInitialize(NULL);

_ConnectionPtr con(__uuidof(Connection));
con->Open(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source = D:\Path\Of\Database\onlinebanking.mdb;Persist Security Info=False"),_T("username"),_T("password"),adOpenUnspecified);

_CommandPtr cmd(__uuidof(Command));
cmd->ActiveConnection = con;

CString sqlstat;
_bstr_t sql(fieldname);
sqlstat.Format("select * from '%s'",sql.operator char * ());

cmd->CommandText = sqlstat.operator LPCTSTR();

_RecordsetPtr rtr(__uuidof(Recordset));
rtr->PutRefSource(cmd);

_variant_t nuller(DISP_E_PARAMNOTFOUND,VT_ERROR);
rtr->Open(nuller,nuller,adOpenDynamic,adLockOptimistic,adCmdText);
rtr->QueryInterface(__uuidof(_Recordset),(void **) ptr);

CoUninitialize();

return S_OK;
}

After you have followed the steps described above, compile the entire project.

To test our component, we could write some code in Visual Basic, like this:

Dim recordset As Recordset
Dim adocom As YourComponentLibrary

Private Sub Form_Load()
Set recordset = new Recordset
Set adocom = New YourComponentLibrary
End Sub

Private Sub UseAdoCom()
Recordset = adocom.getRecordSet("tablename")
End Sub

This code makes an object of the Recordset type and an object of the Com Component we have created. Then in the UseAdoCom method, we firstly call the getRecordSet method and pass the tablename as a parameter. The same method returns a valid recordset object with all the contents of the table from the database.

Don't forget to add these two references to your Visual Basic test project:

   1. Active X Data Objects Library 2.1 (or above)
   2. The ADO COM component created by you. If it doesn't appear in the list click on browse and choose the dll file.