技术文章 > C++Builder程序设计经验五则

C++Builder程序设计经验五则

2019-08-26 09:16

文档管理软件,文档管理系统,知识管理系统,档案管理系统的技术资料:
一、 数据库程序设计
---- Borland C++Builder与Delphi一样使用BDE(Borland
Database Engine)数据库接口,特别是它使用BDE Administrator统一管理数据库别名,使得数据库操作与数据库文件位置无关,从而使数据库开发更容易操作。但在发布应用数据库程序时我们不得不同时“发布”BDE,对于一些简单的数据库程序来说,可能BDE比我们的自己设计的程序还大,而且如使用InstallShield配置BDE,添加数据库别名,很可能会配置失败。所以我们可以采用如下方法:在程序设计阶段仍采用BDE管理数据库别名进行调试,但在程序初始化时(如在主窗体的OnCreate事件处理函数中)修改Table部件的DatabaseName属性,如使用类似如下语句:
Table1->DatabaseName = ExtractFilePath(Application->ExeName);或 Table1->DatabaseName
= ExtractFilePath(Application->ExeName+”DB”);
---- 这样,对调试阶段没有什么影响,发布应用程序时只要将Table1使用的数据库文件放在当前目录或其“DB”子目录下,数据库程序即可正常运行。甚至您还可以将数据库文件所在目录以字符串形式写入注册表(可在安装程序中设置),然后在程序初始化时从注册表获取目录名,赋值给DatabaseName属性即可。无论怎样,您不必强迫用户安装相对庞大的BDE了。
---- 二、 注册表存取
---- 在我们在设计Windows 9x/NT程序时经常需进行注册表信息的存取,如读取程序配置信息、保存配置信息等。写一个注册表存取子程序就很有必要。当需存取注册表时,直接调用此子程序即可,而不必每次都重复一些操作。下面的例程可用来存取整型、字符串型键值,并可在读取失败时返回缺省值Default。
----
#include < Registry.hpp >
int ReadIntFromReg(HKEY Root, AnsiString Key,
AnsiString KeyName, int Default) {
int KeyValue;
TRegistry *Registry = new TRegistry();
Registry->RootKey = Root;
Registry->OpenKey(Key, false);
try {
KeyValue = Registry->ReadInteger(KeyName);
}
catch(...) {
KeyValue = Default;
}
delete Registry;
return KeyValue;
}
void SaveIntToReg(HKEY Root, AnsiString Key,
AnsiString KeyName, int KeyValue) {
TRegistry *Registry = new TRegistry();
Registry->RootKey = Root;
Registry->OpenKey(Key, true);
Registry->WriteInteger(KeyName, KeyValue);
delete Registry;
}
char *ReadStringFromReg(HKEY Root, AnsiString Key,
AnsiString KeyName, char *Default) {
AnsiString KeyValue;
TRegistry *Registry = new TRegistry();
Registry->RootKey = Root;
Registry->OpenKey(Key, false);
try {
KeyValue = Registry->ReadString(KeyName);
}
catch(...) {
KeyValue = (AnsiString)Default;
}
delete Registry;
return KeyValue.c_str();
}
void SaveStringToReg(HKEY Root, AnsiString Key,
AnsiString KeyName, char *KeyValue) {
TRegistry *Registry = new TRegistry();
Registry->RootKey = Root;
Registry->OpenKey(Key, true);
Registry->WriteString(KeyName, (AnsiString)KeyValue);
delete Registry;
}
---- 我们可使用如下调用方法(获得Windows墙纸文件名):
AnsiString WallPaperFileName =
ReadStringFromReg(HKEY_CURRENT_USER,
"\\Control Panel\\Desktop", "Wallpaper", "");
---- 三、 显示/隐藏任务栏图标
---- 标准的Windows应用程序运行时一般都会在任务栏上显示任务图标,用户可直接用鼠标点击任务栏图标进行任务切换,但有些应用程序不使用任务栏图标,如典型的Office工具条,也有些程序可由用户定制显示方式显示或隐藏任务栏图标,如Winamp。我们的程序中也可以做到,只要调用Windows
API函数SetWindowLong即可,如下:
// 隐藏任务栏图标:
SetWindowLong(Application->Handle,
GWL_EXSTYLE, WS_EX_TOOLWINDOW);
// 显示任务栏图标:
SetWindowLong(Application->Handle,
GWL_EXSTYLE, WS_EX_APPWINDOW);
---- 四、 建立简单的“关于”窗口
---- 一个完整的Windows应用程序一般都包含一个“关于”窗口,用以显示版本信息等。通常我们是定制一个对话框作为“关于”窗口,当然这样的“关于”窗口可以自由定制,显示更多信息,甚至可包括超链接。但如只需显示简单版本信息等,Windows
Shell Library 函数ShellAbout已足够了,下面这行代码就可以显示“关于”对话框,而且是Windows标准的“关于”对话框,同时可显示程序图标和系统资源使用情况等。
ShellAbout(Handle, ("关于"+Application->Title+"#").c_str(),
("\n"+Application->Title+" V1.0\n\n"+"夏登城 版权所有!").c_str(),
Application->Icon->Handle);
---- 五、 选择目录的两种方法
---- 在我们的应用程序中经常需让用户选择目录,如杀毒软件中用户选择处理目录等。这就涉及目录的选择,我们可使用如下方法之一让用户选择目录:
---- 1、 使用SHBrowseForFolder和SHGetPathFromIDList函数;其函数原形申明如下:
WINSHELLAPI LPITEMIDLIST WINAPI SHBrowseForFolder(LPBROWSEINFO lpbi);
WINSHELLAPI BOOL WINAPI SHGetPathFromIDList(LPCITEMIDLIST pidl, LPSTR
pszPath); LPBROWSEINFO和LPITEMIDLIST的结构请参考Win32文档。这种方法选取目录可获得Windows桌面下所有可用的目录,包括网络邻居中其它计算机的共享目录等,但不可新建目录。下面的例程可让用户选择目录,该例程返回指向所选择目录的全路径字符串。
#include < shlobj.h >
char *GetDir(char *DisplayName, HWND Owner) {
char dir[MAX_PATH] = "";
BROWSEINFO *bi = new BROWSEINFO;
bi->hwndOwner = Owner;
bi->pidlRoot = NULL;
bi->pszDisplayName = NULL;
bi->lpszTitle = DisplayName;
bi->ulFlags = BIF_RETURNONLYFSDIRS;
bi->lpfn = NULL;
bi->lParam = NULL;
bi->iImage = 0;
ITEMIDLIST *il = SHBrowseForFolder(bi);
if(il!=NULL) {
SHGetPathFromIDList(il, dir);
}
delete bi;
return dir;
}
---- 我们可作如下调用得到选择的目录名:
AnsiString Dir = (AnsiString)GetDir("请选择目录:", Handle);
---- 2、 使用SelectDirectory函数。C++Builder提供的函数SelectDirectory可实现目录名的选择,它显示的是类似“打开”/“保存”的对话框,但其优点是可使用/不使用键盘输入目录名,并允许创建新目录。其原形定义如下:
extern PACKAGE bool __fastcall SelectDirectory(
AnsiString &Directory, TSelectDirOpts Options, int HelpCtx);
---- 下面的例程SelectDir允许您选择目录:
#include < FileCtrl.hpp >
AnsiString SelectDir(AnsiString Dir) {
if(SelectDirectory(Dir, TSelectDirOpts()
<< sdAllowCreate << sdPerformCreate << sdPrompt,0))
return Dir;
else
return "";
}
---- 可作如下调用,获取用户选择的目录:
AnsiString SelectedDir = SelectDir("C:\\My Documents");