在VC中動(dòng)態(tài)使用FoxPro數(shù)據(jù)庫(kù)
發(fā)表時(shí)間:2024-02-23 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]紫 瑗 前言 我們?cè)谟肰C++進(jìn)行基于數(shù)據(jù)的綜合開(kāi)發(fā)時(shí),會(huì)經(jīng)常訪問(wèn)到大量的物理存儲(chǔ)位置不可預(yù)見(jiàn)的FoxPro數(shù)據(jù)表(.DBF文件)。這時(shí),我們就要使用到動(dòng)態(tài)加載ODBC的技術(shù)去訪問(wèn)這些數(shù)據(jù)表! 黾夹g(shù)要點(diǎn)分析 使用ODBC技術(shù)時(shí),要求程序開(kāi)發(fā)人員能預(yù)先確定數(shù)據(jù)源的位置,利用“控制面板”中的...
紫 瑗
前言
我們?cè)谟肰C++進(jìn)行基于數(shù)據(jù)的綜合開(kāi)發(fā)時(shí),會(huì)經(jīng)常訪問(wèn)到大量的物理存儲(chǔ)位置不可預(yù)見(jiàn)的FoxPro數(shù)據(jù)表(.DBF文件)。這時(shí),我們就要使用到動(dòng)態(tài)加載ODBC的技術(shù)去訪問(wèn)這些數(shù)據(jù)表。
■技術(shù)要點(diǎn)分析
使用ODBC技術(shù)時(shí),要求程序開(kāi)發(fā)人員能預(yù)先確定數(shù)據(jù)源的位置,利用“控制面板”中的“ODBC管理器”手工加載數(shù)據(jù)庫(kù)。但在實(shí)際的開(kāi)發(fā)中,特別是基于Client/Server網(wǎng)絡(luò)環(huán)境的綜合開(kāi)發(fā)中,往往無(wú)法確定數(shù)據(jù)源的位置,而只能進(jìn)行動(dòng)態(tài)加載。對(duì)于這種情況,我們可以使用一個(gè)Windows API函數(shù) SQLConfigDataSource( )來(lái)完成這一操作。
■應(yīng)用舉例
先用FoxPro生成一張數(shù)據(jù)表Member.dbf,并設(shè)計(jì)好各項(xiàng)字段。注意字段名用英文,否則在VC++中使用時(shí)會(huì)出現(xiàn)錯(cuò)誤。
接著利用Visulal C++ 的向?qū)梢粋(gè)基于對(duì)話框的程序,命名為DBFDemo。修改主對(duì)話框,如圖所示。利用ClassWizard為程序加入一個(gè)基類(lèi)為CRecordset的名為CUserInfo的新類(lèi),按照向?qū)У闹甘,取得Member.dbf的表結(jié)構(gòu)。在類(lèi)CUserInfo的頭文件上加入兩個(gè)文件包含語(yǔ)句:
#include "afxdb.h"
#include "odbcinst.h"
下面給出范例程序的關(guān)鍵代碼:
BOOL CDBFDemoDlg::OnInitDialog()
//主對(duì)話框的初始化函數(shù)
{
……//省略部分機(jī)器生成代碼
//下面一句開(kāi)始動(dòng)態(tài)增加一個(gè)ODBC驅(qū)動(dòng)
SQLConfigDataSource(NULL,ODBC_ADD_DSN,"Microsoft Visual FoxPro Driver",
"DSN=UserInfo\0Description=UserInfo\
0SourceType=dbf\0Source=d:\\DBF\0");
Database.Open(_T("UserInfo"));
//打開(kāi)ODBC驅(qū)動(dòng),Database派生于CDatabase類(lèi)
UserInfo.m_pDatabase=&&Database;
//設(shè)置與CDatabase的連接,UserInfo派生于CUserInfo類(lèi)
UserInfo.Open(AFX_DB_USE_DEFAULT_TYPE, "SELECT FROM member",CRecordset::none);
return TRUE;
}
void CDBFDemoDlg::GetRecordValue()
{
//這個(gè)函數(shù)取得打開(kāi)的表中的記錄,并利用DDX/DDV機(jī)制相應(yīng)設(shè)置對(duì)話框中的各控件
m_Order=UserInfo.m_order;
//取得記錄中各字段的值,并設(shè)置相應(yīng)的控件值
m_Name=UserInfo.m_name;
m_Age=UserInfo.m_age;
m_Addr=UserInfo.m_addr;
if(UserInfo.m_sex==TRUE)
//典型的設(shè)置記錄中類(lèi)型為BOOL型的字段的操作
this-〉CheckRadioButton(IDB_MAN,IDB_WOMAN,IDB_MAN);
else this-〉CheckRadioButton(IDB_MAN,IDB_WOMAN,IDB_WOMAN);
UpdateData(FALSE);
//將記錄信息顯示在對(duì)話框中
}
void CDBFDemoDlg::OnNext()
//按鈕“下一個(gè)”的響應(yīng)函數(shù)
{
if(!UserInfo.IsEOF())
//測(cè)試記錄是否到底部
{
UserInfo.MoveNext();
//向下移動(dòng)一個(gè)記錄
GetRecordValue();
//設(shè)置對(duì)話框中的記錄顯示
} else
{
//報(bào)告到達(dá)最末記錄信息
::MessageBox(this-〉m_hWnd,"到達(dá)最末記錄","消息框",MB_OK);
UserInfo.MovePrev();
//若到最末記錄,上移一個(gè)記錄,避免空操作
}
}
void CDBFDemoDlg::OnPrev()
//按鈕“下一個(gè)”的響應(yīng)函數(shù)
{
if(!UserInfo.IsBOF())
//測(cè)試記錄是否到達(dá)頂部
{
UserInfo.MovePrev();
//向上移動(dòng)一個(gè)記錄
GetRecordValue();
//設(shè)置對(duì)話框中的記錄顯示
} else
{ //報(bào)告到達(dá)首記錄
::MessageBox(this-〉m_hWnd,"到達(dá)首記錄","消息框",MB_OK);
UserInfo.MoveNext();
}
}
void CDBFDemoDlg::SetRecordValue()
{//這個(gè)函數(shù)根據(jù)對(duì)話框中各控件的值設(shè)置數(shù)據(jù)表中的某個(gè)記錄的各字段值
UpdateData(TRUE);
//利用DDX/DDV機(jī)制取得控件中的值
UserInfo.m_order=m_Order;
UserInfo.m_name=m_Name;
UserInfo.m_addr=m_Addr;
UserInfo.m_sex=Sex;
//變量Sex可以取得“性別”一項(xiàng)中所選的值
UserInfo.m_age=m_Age;
UserInfo.Update(); //更新記錄的值
}
void CDBFDemoDlg::OnApply()
//按鈕“應(yīng)用”的響應(yīng)函數(shù)
{ //這個(gè)函數(shù)可以進(jìn)行用戶所選擇的如“新增用戶”、“修改用戶”、“刪除用戶”的操作
switch(Operator) //變量Operator的值由用戶的選擇而決定
{
case ADD:
//宏“ADD”已經(jīng)在程序開(kāi)頭時(shí)進(jìn)行了定義
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: //用戶沒(méi)有進(jìn)行操作選擇
::MessageBox(this-〉m_hWnd,"請(qǐng)選擇你所要進(jìn)行的操作","忘記選擇操作",MB_OK);
break;
}
}
限于篇幅,筆者只列出其主要代碼,讀者可以根據(jù)這些關(guān)鍵代碼完成這個(gè)范例程序。
程序在中/英文Windows 98、VC++ 6.0環(huán)境下編譯通過(guò),運(yùn)行正常。需要注意的是,由于范例中使用的是Visual FoxPro 6.0的ODBC驅(qū)動(dòng)器,所以要試驗(yàn)這個(gè)程序,請(qǐng)先安裝VFP 6.0。