Introduction
If you have ever used Data Access Objects (DAO) both in Visual Basic and Visual C++ with MFC, you must have noticed that in Visual Basic, manipulating Microsoft Access MDB files is a more enjoyable way of spending time than doing it in Visual C++ with MFC. And, you must have thought whether a workaround exists to make working with MDB in Visual C++ as flexible as in Visual Basic.
To solve this problem, let's try to use in Visual C++ the same mechanism as is used in Visual Basic. This mechanism assumes that you should work directly with type libraries. Unlike Visual Basic, which is more adapted for rapid application development and has its own methods for accessing type libraries, in Visual C++, working with type libraries is more preferable through converting the content of the type library into C++ classes with the #import
directive.
The best way to understand this is by reading a sample source:
#import <C:\Program Files\Common Files\Microsoft Shared\DAO\dao360.dll>
#include <stdio.h>
#include <tchar.h>
void dump_com_error(_com_error &e)
{
_tprintf(_T("Oops - hit an error!\n"));
_tprintf(_T("\tCode = %08lx\n"), e.Error());
_tprintf(_T("\tCode meaning = %s\n"), e.ErrorMessage());
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
_tprintf(_T("\tSource = %s\n"), (LPCTSTR) bstrSource);
_tprintf(_T("\a\tDescription = %s\n"), (LPCTSTR) bstrDescription);
}
struct StartOle {
StartOle() { CoInitialize(NULL); }
~StartOle() { CoUninitialize(); }
} _inst_StartOle;
void main()
{
DAO::_DBEnginePtr Dbe(__uuidof(DAO::DBEngine));
DAO::DatabasePtr CurrDB;
char stmp[1024];
try {
CurrDB = Dbe->CreateDatabase("test.mdb",
";LANGID=0x0419;CP=1251;COUNTRY=7;", _variant_t((short) DAO::dbVersion40));
CurrDB = Dbe->OpenDatabase("test.mdb");
strcpy(stmp,"CREATE TABLE Test ( \
ARTIST Char(40), \
TITLE1 Char(60), \
FORMAT1 Char(9), \
CATNO Numeric, \
PRICE Numeric, \
DATEIN DateTime, \
NOTES Char(10) \
);");
CurrDB->Execute(stmp);
strcpy(stmp,"INSERT INTO Test VALUES( \
\"Artist\", \
\"Title\", \
\"Format1\", \
1223, \
3231.54, \
'21.09.04', \
\"Notes\" \
);");
CurrDB->Execute(stmp);
for (int i=0; i < CurrDB->TableDefs->Count; i++)
{
_variant_t vI = _variant_t((long) i);
printf("%s\n", (char *) CurrDB->TableDefs->Item[vI]->Name);
}
} catch(_com_error &e) {
dump_com_error(e);
}
}
Compile this example in the command line as:
cl -GX daocpp.cpp
and run daocpp.exe. The database file test.mdb will be created. This file will contain the table Test with one record of data.
As you can see, the types DBEngine
and Database
are mapped to the DAO::_DBEnginePtr
and DAO::DatabasePtr
C++ classes after incorporating information from the type library. The type TableDef
will be mapped to _TableDefPtr
.
Note: Using DAO requires converting C++ types to the variant type. In this sample, you can see that the C++ type long
is converted to the type _variant_t
:
_variant_t vI = _variant_t((long) i);
In the same way, for example, the logical values True
and False
of the bool
type will be converted to the type _variant_t
as:
_variant_t vTrue = _variant_t((bool) -1);
_variant_t vFalse = _variant_t((bool) 0);
I hope this short article will help you to write more efficient code in your applications.