没有合适的资源?快使用搜索试试~ 我知道了~
首页面向对象技术在MiniGUI 中的运用(魏永明)
资源详情
资源评论
资源推荐

知识库[Article: Artical/WeiYongming/3 | 讨论 ]
面向对象技术在 MiniGUI 中的运用
魏永明 (2001/01/14)
注: 本文最初发表在《程序员》杂志 2001 年第二期上。版权所有,未经允许,请勿
转载。
MiniGUI 是国内出现的比较早的几个自由软件项目之一,其目的是开发一个面向实时
嵌入式系统的小型图形用户界面支持系统。目前,MiniGUI 已经成功地应用于机床数
字控制系统、PDA 等实时嵌入式系统上。
为了保持 MiniGUI 良好的可移植性以及运行效率,MiniGUI 中 99% 以上的代码是 C
代码。同时,为了保证 MiniGUI 具有良好的灵活性和可扩展性,我们在 MiniGUI 的
开发中使用了许多面向对象的技术。本文将通过控件类、GAL/IAL 的结构以及
MiniGUI 中多字符集和多字体的支持等实例,向读者介绍面向对象技术在 MiniGUI 的
运用。通过对这些实例的分析,读者将会对 C 语言中面向对象的编程技术有一个更加
深入的了解。
1.1 控件和控件类
许多人对控件(或者部件,widget)的概念已经相当熟悉了。控件可以理解为主窗口
中的子窗口。这些子窗口的行为和主窗口一样,即能够接收键盘和鼠标等外部输入,
也可以在自己的区域内进行输出――只是它们的所有活动被限制在主窗口中。
MiniGUI 也支持子窗口,并且可以在子窗口中嵌套建立子窗口。我们将 MiniGUI 中的
所有子窗口均称为控件。
在 Windows 或 X Window 中,系统会预先定义一些控件类,当利用某个控件类创建
控件之后,所有属于这个控件类的控件均会具有相同的行为和显示。利用这些技术,
可以确保一致的人机操作界面,而对程序员来讲,可以像搭积木一样地组建图形用户
界面。MiniGUI 使用了控件类和控件的概念,并且可以方便地对已有控件进行重载,
使得其有一些特殊效果。比如,需要建立一个只允许输入数字的编辑框时,就可以通
过重载已有编辑框而实现,而不需要重新编写一个新的控件类。
如果读者曾经编写过 Windows 应用程序的话,应该记得在建立一个窗口之前,必须
确保系统中存在新窗口所对应的窗口类。在 Windows 中,程序所建立的每个窗口,
都对应着某种窗口类。这一概念和面向对象编程中的类、对象的关系类似。借用面向
对象的术语,Windows 中的每个窗口实际都是某个窗口类的一个实例。在 X
1

Window 编程中,也有类似的概念,比如我们建立的每一个 Widget,实际都是某个
Widget 类的实例。
这样,如果程序需要建立一个窗口,就首先要确保选择正确的窗口类,因为每个窗口
类决定了对应窗口实例的表象和行为。这里的表象指窗口的外观,比如窗口边框宽度,
是否有标题栏等等,行为指窗口对用户输入的响应。每一个 GUI 系统都会预定义一些
窗口类,常见的有按钮、列表框、滚动条、编辑框等等。如果程序要建立的窗口很特
殊,就需要首先注册一个窗口类,然后建立这个窗口类一个实例。这样就大大提高了
代码的可重用性。
在 MiniGUI 中,我们认为主窗口通常是一种比较特殊的窗口。因为主窗口代码的可重
用性一般很低,如果按照通常的方式为每个主窗口注册一个窗口类的话,则会导致额
外不必要的存储空间,所以我们并没有在主窗口提供窗口类支持。但主窗口中的所有
子窗口,即控件,均支持窗口类(控件类)的概念。MiniGUI 提供了常用的预定义控
件类,包括按钮(包括单选钮、复选钮)、静态框、列表框、进度条、滑块、编辑框
等等。程序也可以定制自己的控件类,注册后再创建对应的实例。
采用控件类和控件实例的结构,不仅可以提高代码的可重用性,而且还可以方便地对
已有控件类进行扩展。比如,在需要建立一个只允许输入数字的编辑框时,就可以通
过重载已有编辑框控件类而实现,而不需要重新编写一个新的控件类。在 MiniGUI 中,
这种技术称为子类化或者窗口派生。子类化的方法有三种:
一种是对已经建立的控件实例进行子类化,子类化的结果是只影响这一个控件实例;
一种是对某个控件类进行子类化,将影响其后创建的所有该控件类的控件实例; 最后
一种是在某个控件类的基础上新注册一个子类化的控件类,不会影响原有控件类。在
Windows 中,这种技术又称为超类化。 在 MiniGUI 中,控件的子类化实际是通过替
换已有的窗口过程实现的。清单 1 中的代码就通过控件类创建了两个子类化的编辑框,
一个只能输入数字,而另一个只能输入字母:
清单 1 控件的子类化
#define IDC_CTRL1 100
#define IDC_CTRL2 110
#define IDC_CTRL3 120
#define IDC_CTRL4 130
#define MY_ES_DIGIT_ONLY 0x0001
2

#define MY_ES_ALPHA_ONLY 0x0002
static WNDPROC old_edit_proc;
static int RestrictedEditBox (HWND hwnd, int message, WPARAM wParam,
LPARAM lParam)
{
if (message == MSG_CHAR) {
DWORD my_style = GetWindowAdditionalData (hwnd);
/* 确定被屏蔽的按键类型 */
if ((my_style & MY_ES_DIGIT_ONLY) && (wParam '9'))
return 0;
else if (my_style & MY_ES_ALPHA_ONLY)
if (!((wParam >= 'A' && wParam <= 'Z') || (wParam >= 'a' && wParam <= 'z')))
/* 收到被屏蔽的按键消息,直接返回 */
return 0;
}
/* 由老的窗口过程处理其余消息 */
return (*old_edit_proc) (hwnd, message, wParam, lParam);
}
static int ControlTestWinProc (HWND hWnd, int message, WPARAM wParam,
LPARAM lParam)
{
switch (message) {
case MSG_CREATE:
{
HWND hWnd1, hWnd2, hWnd3;
CreateWindow (CTRL_STATIC, "Digit-only box:", WS_CHILD | WS_VISIBLE |
SS_RIGHT, 0,
10, 10, 180, 24, hWnd, 0);
hWnd1 = CreateWindow (CTRL_EDIT, "", WS_CHILD | WS_VISIBLE |
WS_BORDER, IDC_CTRL1,
200, 10, 180, 24, hWnd, MY_ES_DIGIT_ONLY);
3
剩余11页未读,继续阅读










安全验证
文档复制为VIP权益,开通VIP直接复制

评论0