65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在没有 MFC 的情况下使用 Visual C++ 中的 DAO

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.29/5 (6投票s)

2005年8月8日

CPOL

1分钟阅读

viewsIcon

105126

使用 #import 指令并发现 DAO 类型库。

引言

如果您曾经在 Visual Basic 和使用 MFC 的 Visual C++ 中使用过数据访问对象 (DAO),您一定注意到,在 Visual Basic 中,操作 Microsoft Access MDB 文件比在带有 MFC 的 Visual C++ 中更令人愉快。而且,您一定想过是否存在一种解决方法,使在 Visual C++ 中使用 MDB 的灵活性与在 Visual Basic 中一样。

为了解决这个问题,让我们尝试在 Visual C++ 中使用与 Visual Basic 相同的方式。这种方式假定您应该直接使用类型库。与更适合快速应用程序开发并具有访问类型库自身方法的 Visual Basic 不同,在 Visual C++ 中,通过使用 #import 指令将类型库的内容转换为 C++ 类来操作类型库更为可取。

理解这一点最好的方法是阅读一个示例源代码

// daocpp.cpp
// Describe the full path to dao360.dll file. Interface files dao360.tlh and
// dao360.tli will be generated automatically during compilation.
// The #import directive creates "DAO" namespace to avoid name conflicts with 
// other libraries. So, all DAO members must be referenced with "DAO::" prefix,
// e.g. DAO::DBEngine

#import <C:\Program Files\Common Files\Microsoft Shared\DAO\dao360.dll>
#include <stdio.h>
#include <tchar.h>

// The following procedure dump_com_error and structure StartOle are borrowed from
// MSDN samples.
// Dump all COM errors to console

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);
}

// If this is placed in the scope of the smart pointers, they must be
// explicitly Release(d) before CoUninitialize() is called. If any reference
// count is non-zero, a protection fault will occur.

struct StartOle {
    StartOle() { CoInitialize(NULL); }
    ~StartOle() { CoUninitialize(); }
} _inst_StartOle;

// From this line everything will be commented with its VB analogue

void main()
{
    // Dim Dbe As DBEngine
    DAO::_DBEnginePtr Dbe(__uuidof(DAO::DBEngine));
    // Dim CurrDB As Database
    DAO::DatabasePtr CurrDB;
    // Dim stmp As String

    char stmp[1024]; // wide chars not used here for simplicity
    // (COM errors must be handled by C++ try/catch block)

    try {
        // Dbe.CreateDatabase("test.mdb", ";LANGID=0x0419;CP=1251;COUNTRY=7;", 
        // dbVersion40). 
        // (";COUNTRY=7" expression allows using "dd.mm.yy" date format in queries.
        // dbVersion40 constant creates a database with Access 2000 file format.
        // The value for Access 97 format is dbVersion30)

        CurrDB = Dbe->CreateDatabase("test.mdb", 
         ";LANGID=0x0419;CP=1251;COUNTRY=7;", _variant_t((short) DAO::dbVersion40));
        // Set CurrDB = Dbe.OpenDatabase("test.mdb")

        CurrDB = Dbe->OpenDatabase("test.mdb");
        // stmp = "CREATE TABLE ....."

        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)

        CurrDB->Execute(stmp);
        // stmp = "INSERT INTO ....."

        strcpy(stmp,"INSERT INTO Test VALUES( \
                        \"Artist\", \
                        \"Title\", \
                        \"Format1\", \
                        1223, \
                        3231.54, \
                        '21.09.04', \
                        \"Notes\" \
                        );");
        // CurrDB.Execute(stmp)

        CurrDB->Execute(stmp);
        // for i=0 to CurrDB.TableDefs.Count

        // (for all tables in database including system tables)

        for (int i=0; i < CurrDB->TableDefs->Count; i++)
         {
            // Debug.Print CurrDB.TableDefs(i).Name

            _variant_t vI = _variant_t((long) i);
            printf("%s\n", (char *) CurrDB->TableDefs->Item[vI]->Name);
         }
    } catch(_com_error &e) {
        dump_com_error(e);
    }
}

在命令行中编译此示例,如下所示:

cl -GX daocpp.cpp

并运行 daocpp.exe。数据库文件 test.mdb 将被创建。该文件将包含表 Test,其中包含一条数据记录。

如您所见,在合并类型库中的信息后,类型 DBEngineDatabase 被映射到 C++ 类 DAO::_DBEnginePtrDAO::DatabasePtr。类型 TableDef 将被映射到 _TableDefPtr

注意:使用 DAO 需要将 C++ 类型转换为变体类型。在本示例中,您可以看到 C++ 类型 long 被转换为类型 _variant_t

_variant_t vI = _variant_t((long) i);

同样,例如,bool 类型的逻辑值 TrueFalse 将被转换为类型 _variant_t,如下所示:

_variant_t vTrue = _variant_t((bool) -1);
_variant_t vFalse = _variant_t((bool) 0);

我希望这篇文章能帮助您在应用程序中编写更高效的代码。

© . All rights reserved.