C++ Builder数据库编程常见问题释疑
软件世界
C++ Builder中的数据库以功能强大、操作简单等特点而受到程序员们的青睐。然而数据库编程只是应用程序的一个方面,我们在使用过程中,发现了一些问题。本文就C++ Builder 4.0版中数据库部分的一些问题进行探讨,并提出了解决的办法。本文的全部程序和函数在C++ Builder4.0版上均调试通过。
改进中文处理能力
Data Controls页上的TDBNavigator元件可很方便地浏览数据集的记录,通常与TDBGrid元件或其他数据控件配合使用。但导航器默认的提示信息都是英文的,这可不是我们所需要的。
例1:当用户按下导航器上的Delete按钮试图删除当前记录时,C++ Builder4.0将显示一个英文界面的确认框,为此我们需要将它改为中文界面。
解决方法:首先应将导航器的ConfirmDelete特性设为false,然后在BeforeAction事件中编写如下代码:
if (Button==nbDelete)
if Application->MessageBox("确定删除当前记录吗?","确认"MB_OKCANCEL+MB_ICONQUESTION)==IDCANCEL)
Abort();
例2:导航器上的按钮具有默认的信息,但都是英文的。
解决方法:在设计期,可以单击Hints特性边上的省略号按钮来打开一个字符串列表编辑器,然后依次键入提示的内容。一个按钮的提示占一行。
如果要在运行期动态地指定提示信息,就要用到Tstrings对象。程序示例如下:
DBNavigator->Hints->Items->Add(‘库首’);
DBNavigator->Hints->Items->Add(‘前移一位’);
DBNavigator->Hints->Items->Add(‘后移一位’);
DBNavigator->Hints->Items->Add(‘库尾’);
注意:调用Add函数的顺序必须与导航器上按钮的顺序一一对应。
恢复原有数据
例:当用户修改了当前记录后把输入焦点移到另一条记录上,修改就会有效。另外,如果程序中调用了Next、MoveBy、Piror、First、Last等函数,也会使修改生效(即自动调用Post函数)。如果对修改后的数据不满意而想恢复原有数据(相当于Undo操作),该如何办呢?
解决方法:在数据库打开之后,我们首先存取该原始文件;在关闭数据库时,如果用户不想存盘,则将所存取的原始文件覆盖掉系统自动保存的文件即可。方法如下:
首先在该数据库表的AfterOpen事件中编写如下代码:
AnsiString sDBF,sDBT,sMDX,bDBF,bDBT,bMDX;
sDBF=Table->Database->Directory+"\\"+Table->TableName;//获得文件名
sDBT=sDBF.SubString(1,sDBF.AnsiPos(".")) +"DBT"; //形成备注文件路径和文件名
sMDX=sDBF.SubString(1,sDBF.AnsiPos(".")) +"MDX"; //形成索引文件
bDBF=sDBF.SubString(1,sDBF.AnsiPos(".")) +"~BF"; //形成数据库文件的备注文件
bDBT=sDBF.SubString(1,sDBF.AnsiPos(".")) +"~BT"; //形成备注文件的备注文件
bMDX=sDBF.SubString(1,sDBF.AnsiPos(".")) +"~DX"; //形成索引文件的备注文件
if (FileExists(sDBF))
CopyFile(sDBF.c_str(),bDBF.c_str(),false); //若数据库文件存在,则把原文件拷贝成备份文件
if (FileExists(sDBT))
CopyFile(sDBF.c_str(),bDBT.c_str(),false); //若备注文件存在,则把原文件拷贝成备份文件
if (FileExists(sMDX))
CopyFile(sMDX.c_str(),bMDX.c_str(),false); //若索引文件存在,则把原文件拷贝成备份文件
然后在AfterClose事件中编写如下代码:
if (FileExists(bDBF))
CopyFile(bDBF.c_str(),sDBF.c_str(),false);
if (FileExists(bDBT))
CopyFile(bDBT.c_str(),sDBT.c_str(),false);
if (FileExists(bMDX))
CopyFile(bMDX.c_str(),sMDX.c_str(),false);
显示当前记录号
例:当程序调用First、Last、MoveBy、Next、Prior、FindKey、FindFirst、FindNext、FindLast、FindPrior、Locate等函数改变了当前记录后,在状态条上显示应如何随之而变?
解决方法:当改变了记录后,就会触发AfterScroll事件,为此我们可以在这里编写如下代码:
StatBar->Panels->Items[0]->Text ="当前记录号:" +String(Table->RecNo);
StatBar->Panels->Items[1]->Text ="记录总数:" + String(Table-> RecordCount);