C++Builder 高手进阶 (三)用BCB设计DBTreeView组件

原创 2003年01月29日 13:58:00
 

C++Builder 高手进阶  <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

nxyc_twz@163.com

 

前段时间买了本书《C++ Builder深度历险》,暂且不论这本书写的如何,但其作者独特的写作角度令我折服。于是我就有了个想法,能不能将自己多年从事软件开发的经验写成一系列的文章在CSDN上与大家分享,这样不但可使自己的编程水平得到提高,同时又可与CSDN上众多的高手相互砌磋,又何乐而不为呢?在我的写作计划中,将主要包括C++Builder 高手进阶 》、《Interbase 使用技巧》、《ODAC使用详解》等一系列内容。其中C++Builder 高手进阶 将主要通过实例讲解API函数的应用、用BCB编写组件、BCBMIS系统中的应用等;Interbase 使用技巧》(我最喜欢用的数据库Server)则主要讲述其各种使用技巧;ODAC使用详解》(我用BCB连接ORACLE时的首选)主要是以翻译ODAC的帮助文件为主,并辅以我在实际应用中的技巧。希望我的想法能得到大家的支持!

 

(三)用BCB设计DBTreeView组件

 

一、         系统分析

现在使用BCB的以越来越多,可是你有没有意识到,你所使用的控件究竟有几个是用C++编写的?答案肯定让人无法忍受,既然无法忍受何不亲自操刀写一套属于BCB自己的组件呢?我希望从我开始,众位高手能同心协力,共同打造真正属于BCB自己的组件!我不想讲述BCB设计组件的基础知识,因为这些在《C++Builder 5开发人员指南》中有详细的介绍。

我们所设计的DBTreeView派生自TtreeView组件,因此它将具有TtreeView组件的一切特性,我们要做的就是使其具有数据感知能力,与数据直接连接进行直接通信。要构造Tree形结构,我们应使每一个节点具备如下特征:每个节点有一个唯一标识符ID和一个父标识ParentID,(最顶层节点的Parent为空)为了显示相关内容,则还需要一上显示字段FDisplayField。该组件的工作原理已经很清晰了:通过每个节点的IDParentID定位数据记录,然后将相关字段内容赋给FdisplayField显示。

二、         开发前沿

该组件中最重的技术莫过于数据感知了,下面就介绍一下数据感知 技术:

要使某个组件成为数据感知的,我们必须给它提供所需的数据连接以便和数据训数据成员通信,这个数据连接类是TFieldDataLink。数据感知组件有其自己的数据连接类,数据连接由组件负责创建、初始化和销毁。建立连接通常需要3步:

1.  将数据连接类(TFieldDataLink)声明为组件的成员;

2.  声明适当的读、写访问属性;

3.  初始化数据连接。

三、         设计流程

//DBTreeView头文件

/在头文件中添加以下三行,因为/数据连接类需要这三个头文件中的声明

#include <Db.hpp>     

#include <DbTables.hpp>

#include <DbCtrls.hpp>

//定义事件,用来响应设置节点位图事件

typedef void __fastcall (__closure *TDBTVSetImageIndexEvent)(System::TObject* Sender, int ID, int ParentID, int Level, int& ImageIndex, int& SelectedIndex);

//定义节点结构

struct TDBTreeNodeData

{

    int ID;        //节点唯一标识

    int ParentID;   //节点父标识,它为空时表示此节点是最顶层节点

};

 

class PACKAGE TDBTreeView : public TTreeView

{

private:

    TFieldDataLink* FDataLink;   //声明数据连接成员

    AnsiString FParentIDField;    //父标识字段

    AnsiString FPrimaryIDField;   //主标识字段

    AnsiString FDisplayField;     //显示字段

    bool FActive;               //是否为活动状态

    bool FAllowModifyDB;       //是否允许修改

    TDBTVSetImageIndexEvent   FOnSetImageIndex;   //声明事件

 

    void __fastcall SetActive(bool Value);   //设置状态

void __fastcall SetDataSource(Db::TDataSource* Value); //设置数据源

    TDataSource* __fastcall GetDataSource(); //取得数据源

 

    void __fastcall ClearAllNodes();  //删除所有节点

    void __fastcall FillTreeNodes(int ParentID, TTreeNode* Node); //填充节点

    void __fastcall FillChildTreeNodes(int ParentID, TTreeNode* Node, bool Nest = false); //填充子节点

    void __fastcall AddDataToNode(TTreeNode* Node, TDBTreeNodeData& Data);//追加数据到节点

protected:

//以下以个方法用来重载TreeView的相关方法

     virtual void __fastcall Loaded(void); //Load方法

     virtual void __fastcall Notification(Classes::TComponent* AComponent, Classes::TOperation Operation); //事件

     DYNAMIC void __fastcall Edit(const tagTVITEMA &Item);//Edit方法

     DYNAMIC void __fastcall Expand(TTreeNode* Node);//Expand方法

     DYNAMIC void __fastcall KeyDown(Word &Key, Classes::TShiftState Shift);//键盘事件

     DYNAMIC void __fastcall Change(TTreeNode* Node);//节点改变事件

     virtual bool __fastcall CustomDrawItem(TTreeNode* Node, TCustomDrawState State, TCustomDrawStage Stage, bool &PaintImages);//自绘节点事件

 

public:

    __fastcall TDBTreeView(TComponent* Owner);//构造函数

    __fastcall ~TDBTreeView();//析构函数

 

    TDBTreeNodeData __fastcall GetNodeData(TTreeNode* Node);//取得指定节点数据

void __fastcall FullExpand(void);  //展开所有节点

    __property bool Active = {read = FActive, write = SetActive};//属性活动状态

__published:

//以下定义在属性编辑器中用到的几个属性

    __property bool AllowModifyDB = {read = FAllowModifyDB, write = FAllowModifyDB};//是否允许编辑

    __property AnsiString ParentIDField = {read = FParentIDField, write = FParentIDField};//父标识

    __property AnsiString PrimaryIDField = {read = FPrimaryIDField, write = FPrimaryIDField};//主标识

    __property AnsiString DisplayField = {read = FDisplayField, write = FDisplayField};//显示字段

     __property TDataSource* DataSource = {read=GetDataSource, write=SetDataSource};//数据源

    __property TDBTVSetImageIndexEvent OnSetImageIndex = {read=FOnSetImageIndex, write=FOnSetImageIndex};//设置节点位图事件

};

//下面的类用来填充字段列表

class TFieldNameProperty : public TStringProperty

{

public:

    TPropertyAttributes __fastcall GetAttributes(void)

    {

        return TPropertyAttributes() << paValueList;

    }

 

     void __fastcall GetValues(Classes::TGetStrProc Proc);

};

 《未完待续》

 

 

 

BCB(C++ Builder)创建动态库(DLL,接口导出和调用),动态加载DLL

以前没有封装dll动态库,接触新的工作之后需要用,折腾了一整天,终于搞定了。 毕竟是生手,就简单分析注意点和遇到的一些问题及解决方案: (1)首先准备要生成DLL的工程。 (1.1)我用的是BC...
  • lushangqiushui
  • lushangqiushui
  • 2014年04月03日 22:40
  • 828

在C++Builder中安装odac组件

今天接手一个很久前开发的c++builder程序,要试运行,结果编译发现提示无法找到Ora.hpp文件,再细查发现系统中连接数据库多次调用了TOraSession,TOraQuery等类,经过查询,知...
  • mianli85
  • mianli85
  • 2014年03月28日 15:19
  • 482

BCB中的输入对话框和输出对话框(也就是消息对话框)

刚出去转了一下, 吹吹风, 回来继续写。 我们现在来说BCB中的输出对话框, 这个很常见: //--------------------------------------------...
  • stpeace
  • stpeace
  • 2015年07月26日 14:35
  • 1984

c++ builder 子窗口长期前置

【Write by wood 小汤——http://blog.csdn.net/tbwood  转载请说明出处,写下来不容易】 要真正的理解和解决这个问题,确实不容易。当我花了好几天时间才搞明白...
  • shang2468
  • shang2468
  • 2013年11月22日 13:36
  • 1794

关于BCB的安装过程

1、安装C++builder主程序; |——说明:安装过程序列号:HAAL-DANSGN-FZR5AG-M3BS。 2、打开DelphiDistiller.exe; |——说明:打开后选择T...
  • jinjunweina
  • jinjunweina
  • 2014年07月07日 22:44
  • 1285

BCB如何加载字符串资源文件(语言资源文件)?

如何在软件.exe中嵌入语言资源呢。常规的想法是, 将语言字符串放到一个文件中, 然后在程序中去读取。 然而这样做存在一个问题: 最后发布的.exe必须依赖于语言字符串文件, 比如lang.txt. ...
  • stpeace
  • stpeace
  • 2015年07月26日 12:45
  • 1582

BCB 动态生成控件

窗体上的所有对象与窗体本身都成为一个类:TForm1,我们就是将类成员与类成员函数写到TForm1类中,程序运行时,实际上就是通过TForm1 类生成Form1对象, 所以,Unit1.cpp...
  • u014438664
  • u014438664
  • 2015年03月29日 23:46
  • 494

C++ Builder初学问与答

一直以来都想写一点为BCB初学者快速入门的东西,前不久写了几篇《闲谈BCB》想把自己学习BCB中如何来解决难点的方法说给大家,没想到被骂得不成样子。本想不写了,但觉得这些东西留下来能做什么呢?还是用另...
  • wozengcong
  • wozengcong
  • 2014年01月04日 16:44
  • 1500

BCB6使用ReportMachine创建报表

RM(Report Machine)是一个功能强大的Delphi 报表控件包。使用它可以制作出非常复杂的报表。下面讲述最简单的用法:  在Form上放上两个数据库控件:ADOConnection和A...
  • limuyun
  • limuyun
  • 2014年05月16日 17:08
  • 1798

C++ Builder 的文件读写操作总结

这类函数完成对文件的读写相关的操作,这种类型的操作和C的基于I/O文件操作类似,下表列出这类操作常用的函数及其功能。   FileOpen() 打开文件   FileClose() 关闭文件  ...
  • C_S_D_N_USER
  • C_S_D_N_USER
  • 2014年09月02日 11:37
  • 3343
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++Builder 高手进阶 (三)用BCB设计DBTreeView组件
举报原因:
原因补充:

(最多只允许输入30个字)