[quote:8fdf0da297]第八章 界面对象
表示窗口、对话框、和控件的对象称为用户界面对象,或简称为界面对象。本章讨论界面对象的要求和行为,以及与其它实际出现在屏幕上的窗口、对话框和控件的关系。
本章也讲述应用程序的不同界面对象之间的关系,以及对应用程序界面对象的响应方式。
8.1 TObject
TObject是一个基类,它对所有的窗口界面类TDialog、TWindow及其派生类:TControl,都是通用的。TObject定义了窗口、对话框和控件对象的共同行为。TObject的成员函数定义如下:
l 维护Object对象和窗口元素结构的双重性,包括构造函数和控件对象的父指针对象。
l 维护所有从基类派生的事件响应。
l 自动支持派生类的显示。
TObject是在幕后工作的。实际上很少从TObject直接导出新的类。在从TWindow和TDialog派生新类时,对象可以继承许多TObject定义的功能。
8.2 为何要用界面对象
既然基于UNIX文本curses环境的交互式应用程序已经有了直观窗口、对话框可控件了,为何还需要界面对象呢?
每个节对象豆油一个与之相关的界面元素,它不是对象,而是一个物理的窗口、对话框或控制,界面对象只是作为直观界面元素的面向对象代码。界面对象提供了用于生成、初始化、管理与之相关的界面元素。界面对象的数据成员保存有关的数据,包括其界面元素的指针,它的主窗口和子窗口。界面对象的成员函数能处理许多交互式应用程序的内部编程细节。
具有相关界面元素的界面对象的结构能根据情形正确地处理窗口、对话框和控件。例如,为了生成一个完全的界面对象,必须要调用两个成员函数。第一个是构造函数,它构造界面对象和设置对象的属性,如类型和菜单。
第二个成员函数是InitMainWindow和InitDialog,它把界面对象同新的界面元素联系到一起。InitMainWindow成员函数构造主窗口的特定的界面元素,而InitDialog则构造特定的对话框对象,组成包含用户自己需要的控件列表。通过调用各自不同对象的成员函数Show把界面元素在用户屏幕上显示出来。
InitMainWindow和InitDialog能够保证正确地构造界面对象的同时保证对象有足够的内存。
类似地,在删除界面对象时,系统自动释放对象的内存。但是,这只是在调用delete函数时,才删除界面对象,否则,界面对象一直在系统内存中保留着,直到退出应用程序系统,这样能够保证系统能在最短的时间内显示用户的屏幕对象。
应该注意到,生成界面对象和生成对应的直观界面元素并不一定意味着在屏幕上能看到什么东西。当建立直观元素时,Object UNIX Class Library将要检查控件的类型EnableFlag是否置为TRUE。EnableFlag和其它的窗口控件类型是在构造函数中对数据成员进行设置的。仅当各个属性成员数据都设置为TRUE时,界面元素才在生成后通过对象的成员函数Show显示出来。
任何时候,通过调用界面对象的成员函数Show可以显示或隐藏界面元素。
8.3 窗口父/子关系
在Object UNIX Class应用程序中,界面元素(窗口、对话框和控件)都是通过父/子链相联系的。
两个界面元素中若有一个是另一个的父窗口,那么它们两个便是相关联的。不是把这种父子关系同继承关系或事例拥属关系相混淆。后面两种都是对象关系。子窗口并不一定继承它的父窗口,亦或从父窗口继承任何属性。
子窗口是这样一种界面元素,它接受另一个界面元素的管理。例如,列表框是由其所在的窗口或对话框来管理的。只有当父窗口显示着的时候,子窗口才能显示出来。当关闭父窗口时,子窗口自动关闭。
8.3.1 控件列表
在构造一个界面元素时,系统自动默认当前的窗口或者对话框为控件的父窗口,子窗口控件对象通过它的数据成员Parent来记录它的父窗口的界面元素,并从父窗口的位置中计算该控件相对与父窗口的位置。而父窗口也通过成员数据ControlList来记录每个的子控件对象。ControlList是一个对象列表指针,它的结构实体是一个类结构,其中的数据成员指向一个通用的Tcontrol指针,这样保证以后对某个对象指针引用的正确性。
当定义一个新的带控件的对话框的界面类时,也要定义初始化函数来构造每个子控件对象。随后,当应用程序调用父窗口对话框的ExecDialog成员函数时,便生成父窗口对话框的界面元素。如果成功,在接着调用每个子控件对象的成员函数Show,以便显示每个子控件对象。显示与否,要看每个子控件对象的显示属性EnableFlag是否为TRUE。
通常还要重定义对话框的ExecDialog虚函数,以便在生成子控件对象之后能在执行某些设置任务,比如向列表框中填充表项。在重定义的成员函数ExecDialog中,一定要把调用当前对象基类的ExecDialog成员函数放在最后一句。
8.3.2 子对象控件的遍历函数
有时,可能需要编写这样的成员函数,它检查所有子控件对象的执行时当前属性以及取得一些子对象控件的成员数据,您必须遍历每个子对象控件的列表指针。当然,如果您把某个对象作为父窗口的数据成员,您就可以通过该指针直接引用。
ControlList作为TDialog类的一个数据成员,存放着指向所有控件列表的指针。通过该指针,您可以取得当前的某个控件。当然,为取得某个控件对象的上一个或下一个,您可以采用Next或者Prev指针。
建议在构造每个对话框对象的时候,对有键盘事件的控件,您都应该在父对话框对象类中定义该控件对象的指针,这样便于引用方便。
为了判断ControlList指向的控件是什么控件,您可以采用基类成员函数GetClassName来返回当前控件的名称,这样缩小判断范围。
8.4 消息处理
Object UNIX Class Library处理用户的键盘事件的方法是重定义派生类的KeyEvent成员函数。该函数提供给用户处理各自不同键盘事件接口。通过重定义该函数,您就可以得到所有对话框子对象控件的按键事件,通过类成员函数GetClassName来判断当前的控件类型,再根据定义好的对话框类对象数据的对象指针,进行比较,判断是否为该个对象。在定位好该个对象后,就可以设计响应该控件的业务处理。
8.4.1 对控件事件的响应
这里对控件事件的响应采用对虚函数PressEnterEvent的重载来响应控件时间。
int TUserDialog:ressEnterEvent(void)
{
TButton *Button;
if(strcmp(ControlList->Control->GetClassName(),"BUTTON")==0){
Button=(TButton *)ControlList->Control;
switch(Button->ButtonType) {
case SAVE_BUTTON:
//处理按下确认键,该段程序需要用户自己编写
break;
case EXIT_BUTTON:
//处理按下确认键,该段程序需要用户自己编写
break;
}
}
return 1;
}
对按钮事件的响应有别于其它控件,因为按钮控件有其唯一的ID标识,所以采用case语句比较用户按下哪个按钮控件。
8.4.2 对菜单事件的响应
前面已经说过,对每个菜单选项,都有一个可供调用的成员函数,包括用户自己定义的成员函数和Object UNIX Class Library本身继承的基类成员函数如上例按下退出系统子菜单选项执行的Close函数。
例如,对于菜单项文件|打开文件,对应有成员函数OpenFile将被调用。这里只是显示一个消息框。
void TLfrWindow::OpenFile(void)
{
MsgDialog(“信息窗口”,”打开一个文件”);
}
[/quote:8fdf0da297]
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/