|            
紫 瑗
    前言
 
    我们在用VC++进行基于数据的综合开发时,会经常访问到大量的物理存储位置不可预见的FoxPro数据表(.DBF文件)。这时,我们就要使用到动态加载ODBC的技术去访问这些数据表。
 
    ■技术要点分析
 
    使用ODBC技术时,要求程序开发人员能预先确定数据源的位置,利用“控制面板”中的“ODBC管理器”手工加载数据库。但在实际的开发中,特别是基于Client/Server网络环境的综合开发中,往往无法确定数据源的位置,而只能进行动态加载。对于这种情况,我们可以使用一个Windows API函数 SQLConfigDataSource( )来完成这一操作。
 
    ■应用举例
 
    先用FoxPro生成一张数据表Member.dbf,并设计好各项字段。注意字段名用英文,否则在VC++中使用时会出现错误。
    接着利用Visulal C++ 的向导生成一个基于对话框的程序,命名为DBFDemo。修改主对话框,如图所示。利用ClassWizard为程序加入一个基类为CRecordset的名为CUserInfo的新类,按照向导的指示,取得Member.dbf的表结构。在类CUserInfo的头文件上加入两个文件包含语句:
    #include "afxdb.h"
    #include "odbcinst.h"
    下面给出范例程序的关键代码:
    BOOL CDBFDemoDlg::OnInitDialog()
    //主对话框的初始化函数
    {
     ……//省略部分机器生成代码
     //下面一句开始动态增加一个ODBC驱动
    SQLConfigDataSource(NULL,ODBC_ADD_DSN,"Microsoft Visual FoxPro Driver",
     "DSN=UserInfo\0Description=UserInfo\
    0SourceType=dbf\0Source=d:\\DBF\0");
    Database.Open(_T("UserInfo"));
    //打开ODBC驱动,Database派生于CDatabase类
    UserInfo.m_pDatabase=&&Database;
    //设置与CDatabase的连接,UserInfo派生于CUserInfo类
    UserInfo.Open(AFX_DB_USE_DEFAULT_TYPE, "SELECT  FROM member",CRecordset::none);
    return TRUE;
    }
    void CDBFDemoDlg::GetRecordValue()
    {
    //这个函数取得打开的表中的记录,并利用DDX/DDV机制相应设置对话框中的各控件
     m_Order=UserInfo.m_order;
    //取得记录中各字段的值,并设置相应的控件值
     m_Name=UserInfo.m_name;
     m_Age=UserInfo.m_age;
     m_Addr=UserInfo.m_addr;
     if(UserInfo.m_sex==TRUE)
    //典型的设置记录中类型为BOOL型的字段的操作
    this-〉CheckRadioButton(IDB_MAN,IDB_WOMAN,IDB_MAN);
     else this-〉CheckRadioButton(IDB_MAN,IDB_WOMAN,IDB_WOMAN);
     UpdateData(FALSE);
    //将记录信息显示在对话框中
    }
    void CDBFDemoDlg::OnNext()
    //按钮“下一个”的响应函数
    {
    if(!UserInfo.IsEOF())
    //测试记录是否到底部
     {
    UserInfo.MoveNext();
    //向下移动一个记录
    GetRecordValue();
    //设置对话框中的记录显示
     } else
     {
    //报告到达最末记录信息
    ::MessageBox(this-〉m_hWnd,"到达最末记录","消息框",MB_OK);
    UserInfo.MovePrev();
    //若到最末记录,上移一个记录,避免空操作
     }
    }
    void CDBFDemoDlg::OnPrev()
    //按钮“下一个”的响应函数
    {
    if(!UserInfo.IsBOF())
    //测试记录是否到达顶部
     {
    UserInfo.MovePrev();
    //向上移动一个记录
    GetRecordValue();
    //设置对话框中的记录显示
     } else
     { //报告到达首记录
    ::MessageBox(this-〉m_hWnd,"到达首记录","消息框",MB_OK);
    UserInfo.MoveNext();
     }
    }
    void CDBFDemoDlg::SetRecordValue()
    {//这个函数根据对话框中各控件的值设置数据表中的某个记录的各字段值
     UpdateData(TRUE);
    //利用DDX/DDV机制取得控件中的值
     UserInfo.m_order=m_Order;
     UserInfo.m_name=m_Name;
     UserInfo.m_addr=m_Addr;
     UserInfo.m_sex=Sex;
    //变量Sex可以取得“性别”一项中所选的值
     UserInfo.m_age=m_Age;
     UserInfo.Update(); //更新记录的值
    }
    void CDBFDemoDlg::OnApply()
    //按钮“应用”的响应函数
    { //这个函数可以进行用户所选择的如“新增用户”、“修改用户”、“删除用户”的操作
     switch(Operator) //变量Operator的值由用户的选择而决定
     {
     case ADD:
    //宏“ADD”已经在程序开头时进行了定义
     if(UserInfo.CanAppend()==TRUE)
    UserInfo.AddNew(); //新增用户
     SetRecordValue();
     this-〉OnAdd();
     break;
     case MODI: //修改用户信息
     UserInfo.Edit();
    SetRecordValue();
     break;
     case DELE: //删除用户
     if(UserInfo.IsDeleted()==FALSE)
     {
     UserInfo.Delete();
     this-〉OnPrev();
     }
     break;
     default: //用户没有进行操作选择
    ::MessageBox(this-〉m_hWnd,"请选择你所要进行的操作","忘记选择操作",MB_OK);
     break;
     }
    }
    限于篇幅,笔者只列出其主要代码,读者可以根据这些关键代码完成这个范例程序。
    程序在中/英文Windows 98、VC++ 6.0环境下编译通过,运行正常。需要注意的是,由于范例中使用的是Visual FoxPro 6.0的ODBC驱动器,所以要试验这个程序,请先安装VFP 6.0。  
 |