技术文章 > 基于递归方法实现表单中元件的遍历访问

基于递归方法实现表单中元件的遍历访问

2018-05-22 16:01

文档管理软件,文档管理系统,知识管理系统,档案管理系统的技术资料:
C++Builder是一个可视化C++快速应用开发工具,具有极高的开发效率,在表单及各种基于可视元件库VCL或第三方的可视元件、元件对象命名、复制、编程事件管理方面非常成熟,目前广泛应用于Windows平台应用软件的开发。
在C++Builder中遍历表单中的各种元件,进而访问或修改元件属性可以给程序带来很大的灵活性。本文结合遍历并设置表单中所有可输入文本元件的默认输入方法为例来说明遍历表单中的各种元件的具体实现。
C++Builder中程序运行时可用于输入文本的元件有文本编辑框TEdit、文本型数据库字段编辑器TDBEdit、数据库显示网格TDBGrid等,这些元件都有一个用于指明其缺省文字输入法的属性ImeName。系统中的所有可用输入法可通过如下方法获得:
ComboBox1->Items->Text=Screen->Imes->Text;
VCL屏幕对象Screen在程序中是可以全局访问的,其Imes属性是系统输入法名称串列表。以上语句将系统所有可用输入法名显示称在一个下拉列表框中供用户选择,假定选择的输入法名称被赋给变量DefaultImeName。通过遍例表单中的所有元件,找出可用于输入文本的所有元件并将其ImeName属性设置为DefaultImeName即可实现目标。
C++Builder支持对元件容器中的元件进行遍历。元件容器是指可以为其指定子元件的元件,例如表单TForm、面板TPanel、多页元件TPageControl等,子元件只能在元件容器的区域中显示。通过元件容器的子元件个数ControlCount和子元件数组Controls[]可实现子元件的枚举。由于面板TPanel、多页元件TPageControl等元件容器之间可以互相包容,因此遍历表单中的元件只能够通过递归的方法实现。
基本方法是定义SetupImeName函数,判断一个容器元件中是否有可用于输入文本的元件,设置其缺省输入法属性;判断一个容器元件中是否有其他容器元件,如果有,调用相应类型容器元件的同名函数处理。如下例所示:
//---------------------------------------------------------------------------
void TDM1::SetupImeName(TForm * form)
{
AnsiString control;
for(int i=0;iControlCount;i++)
{
control=AnsiString(form->Controls[i]->ClassName());
if(control=="TDBEdit")
((TDBEdit*)form->Controls[i])->ImeName=DefaultImeName;
if(control=="TEdit")
((TEdit*)form->Controls[i])->ImeName=DefaultImeName;
if(control=="TComboBox")
((TComboBox*)form->Controls[i])->ImeName=DefaultImeName;
if(control=="TDBGrid")
((TDBGrid*)form->Controls[i])->ImeName=DefaultImeName;
if(control=="TTabSheet")
SetupImeName((TTabSheet*)form->Controls[i]);
if(control=="TPageControl")
SetupImeName((TPageControl*)form->Controls[i]);
if(control=="TPanel")
SetupImeName((TPanel*)form->Controls[i]);
if(control=="TDBCtrlGrid")
SetupImeName((TDBCtrlGrid*)form->Controls[i]);
}
}
//---------------------------------------------------------------------------
void TDM1::SetupImeName(TTabSheet * rq)
{
AnsiString control;
for(int i=0;iControlCount;i++)
{
control=AnsiString(rq->Controls[i]->ClassName());
if(control=="TDBEdit")
((TDBEdit*)rq->Controls[i])->ImeName=DefaultImeName;
if(control=="TEdit")
((TEdit*)rq->Controls[i])->ImeName=DefaultImeName;
if(control=="TComboBox")
((TComboBox*)rq->Controls[i])->ImeName=DefaultImeName;
if(control=="TDBGrid")
((TDBGrid*)rq->Controls[i])->ImeName=DefaultImeName;
if(control=="TTabSheet")
SetupImeName((TTabSheet*)rq->Controls[i]);
if(control=="TPageControl")
SetupImeName((TPageControl*)rq->Controls[i]);
if(control=="TPanel")
SetupImeName((TPanel*)rq->Controls[i]);
if(control=="TDBCtrlGrid")
SetupImeName((TDBCtrlGrid*)rq->Controls[i]);
}
}

处理其它类型元件容器的函数定义限于篇幅不予一一列出。
源程序中子元件数组Controls[]是TControl类型对象指针数组,其中的每个元素可根据其ClassName判断元件类型,并进行相应牵制类型转换。
在上例中,递归函数SetupImeName的定义体现了面向对象的函数的多态性。