首页    新闻    下载    文档    论坛     最新漏洞    黑客教程    数据库    搜索    小榕软件实验室怀旧版    星际争霸WEB版    最新IP准确查询   
名称: 密码:      忘记密码  马上注册
操作系统 :: windows

基于Linux和MiniGUI的嵌入式系统软件开发指南(三)


(略)
  作者:魏永明



  对话框和控件编程



  本文讲述 MiniGUI 中的对话框和控件编程。首先讲解 MiniGUI 中的控件类和控件实例的关系,并举例说明控件子类化的概念及应用;其次讲解 MiniGUI 对话框的编程技术,包括对话框模板的定义和对话框回调函数的编程;最后解释模态对话框和非模态对话框之间的区别。



  1 引言



  对话框编程是一个快速构建用户界面的技术。通常,我们编写简单的图形用户界面时,可以通过调用 CreateWindow 函数直接创建所有需要的子窗口,即控件。但在图形用户界面比较复杂的情况下,每建立一个控件就调用一次 CreateWindow 函数,并传递许多复杂参数的方法很不可取。主要原因之一,就是程序代码和用来建立控件的数据混在一起,不利于维护。为此,一般的 GUI 系统都会提供一种机制,利用这种机制,通过指定一个模板,GUI 系统就可以根据此模板建立相应的主窗口和控件。MiniGUI 也提供这种方法,通过建立对话框模板,就可以建立模态或者非模态的对话框。



  本文首先讲解组成对话框的基础,即控件的基本概念,然后讲解对话模板的定义,并说明模态和非模态对话框之间的区别以及编程技术。



  2 控件和控件类



  许多人对控件(或者部件,widget)的概念已经相当熟悉了。控件可以理解为主窗口中的子窗口。这些子窗口的行为和主窗口一样,即能够接收键盘和鼠标等外部输入,也可以在自己的区域内进行输出??只是它们的所有活动被限制在主窗口中。MiniGUI 也支持子窗口,并且可以在子窗口中嵌套建立子窗口。我们将 MiniGUI 中的所有子窗口均称为控件。



  在 Windows 或 X Window 中,系统会预先定义一些控件类,当利用某个控件类创建控件之后,所有属于这个控件类的控件均会具有相同的行为和显示。利用这些技术,可以确保一致的人机操作界面,而对程序员来讲,可以像搭积木一样地组建图形用户界面。MiniGUI 使用了控件类和控件的概念,并且可以方便地对已有控件进行重载,使得其有一些特殊效果。比如,需要建立一个只允许输入数字的编辑框时,就可以通过重载已有编辑框而实现,而不需要重新编写一个新的控件类。



  如果读者曾经编写过 Windows 应用程序的话,应该记得在建立一个窗口之前,必须确保系统中存在新窗口所对应的窗口类。在 Windows 中,程序所建立的每个窗口,都对应着某种窗口类。这一概念和面向对象编程中的类、对象的关系类似。借用面向对象的术语,Windows 中的每个窗口实际都是某个窗口类的一个实例。在 X Window 编程中,也有类似的概念,比如我们建立的每一个 Widget,实际都是某个 Widget 类的实例。



  这样,如果程序需要建立一个窗口,就首先要确保选择正确的窗口类,因为每个窗口类决定了对应窗口实例的表象和行为。这里的表象指窗口的外观,比如窗口边框宽度,是否有标题栏等等,行为指窗口对用户输入的响应。每一个 GUI 系统都会预定义一些窗口类,常见的有按钮、列表框、滚动条、编辑框等等。如果程序要建立的窗口很特殊,就需要首先注册一个窗口类,然后建立这个窗口类一个实例。这样就大大提高了代码的可重用性。



  在 MiniGUI 中,我们认为主窗口通常是一种比较特殊的窗口。因为主窗口代码的可重用性一般很低,如果按照通常的方式为每个主窗口注册一个窗口类的话,则会导致额外不必要的存储空间,所以我们并没有在主窗口提供窗口类支持。但主窗口中的所有子窗口,即控件,均支持窗口类(控件类)的概念。MiniGUI 提供了常用的预定义控件类,包括按钮(包括单选钮、复选钮)、静态框、列表框、进度条、滑块、编辑框等等。程序也可以定制自己的控件类,注册后再创建对应的实例。表 1 给出了 MiniGUI 预先定义的控件类和相应类名称定义。



  表 1 MiniGUI 预定义的控件类和对应类名称



  控件类 类名称 宏定义 备注



  静态框 "static" CTRL_STATIC



  按钮 "button" CTRL_BUTTON



  列表框 "listbox" CTRL_LISTBOX



  进度条 "progressbar" CTRL_PRORESSBAR



  滑块 "trackbar" CTRL_TRACKBAR



  单行编辑框 "edit"、"sledit" CTRL_EDIT、CTRL_SLEDIT



  多行编辑框 "medit"、"mledit" CTRL_MEDIT、CTRL_MLEDIT



  工具条 "toolbar" CTRL_TOOLBAR



  菜单按钮 "menubutton" CTRL_MENUBUTTON



  树型控件 "treeview" CTRL_TREEVIEW 包含在 mgext 库,即MiniGUI 扩展库中。



  月历控件 "monthcalendar" CTRL_MONTHCALENDAR 同上



  旋钮控件 "spinbox" CTRL_SPINBOX 同上



  在 MiniGUI 中,通过调用 CreateWindow 函数,可以建立某个控件类的一个实例。控件类既可以是表 1 中预定义 MiniGUI 控件类,也可以是用户自定义的控件类。与 CreateWindow 函数相关的几个函数的原型如下(include/window.h):



  904 HWND GUIAPI CreateWindowEx (const char* spClassName, const char* spCaption,



  905 DWORD dwStyle, DWORD dwExStyle, int id,



  906 int x, int y, int w, int h, HWND hParentWnd, DWORD dwAddData);



  907 BOOL GUIAPI DestroyWindow (HWND hWnd);



  908



  909 #define CreateWindow(class_name, caption, style, id, x, y, w, h, parent, add_data) 910 CreateWindowEx(class_name, caption, style, 0, id, x, y, w, h, parent, add_data)



  CreateWindow 函数建立一个子窗口,即控件。它指定了控件类、控件标题、控件风格,以及窗口的初始位置和大小。该函数同时指定子窗口的父窗口。CreateWindowEx 函数的功能和 CreateWindow 函数一致,不过,可以通过 CreateWindowEx 函数指定控件的扩展风格。DestroyWindow 函数用来销毁用上述两个函数建立的控件或者子窗口。



  清单 1 中的程序,利用预定义控件类创建控件。其中hStaticWnd1 是建立在主窗口 hWnd 中的静态框;hButton1、hButton2、hEdit1、hStaticWnd2则是建立在 hStaicWnd1 内部的几个控件,并作为 hStaticWnd1 的子控件而存在,建立了两个按钮、一个编辑框和一个静态按钮;而 hEdit2 是 hStaicWnd2 的子控件,是 hStaticWnd1 的子子控件。



  清单1 利用预定义控件类创建控件



  #define IDC_STATIC1 100



  #define IDC_STATIC2 150



  #define IDC_BUTTON1 110



  #define IDC_BUTTON2 120



  #define IDC_EDIT1 130



  #define IDC_EDIT2 140



  int ControlTestWinProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam)



  {



  static HWND hStaticWnd1, hStaticWnd2, hButton1, hButton2, hEdit1, hEdit2;



  switch (message) {



  case MSG_CREATE:



  {



  hStaticWnd1 = CreateWindow (CTRL_STATIC,



  "This is a static control",



  WS_CHILD | SS_NOTIFY | SS_SIMPLE | WS_VISIBLE | WS_BORDER,



  IDC_STATIC1,



  10, 10, 180, 300, hWnd, 0);



  hButton1 = CreateWindow (CTRL_BUTTON,



  "Button1",



  WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE,



  IDC_BUTTON1,



  20, 20, 80, 20, hStaticWnd1, 0);



  hButton2 = CreateWindow (CTRL_BUTTON,



  "Button2",



  WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE,



  IDC_BUTTON2,



  20, 50, 80, 20, hStaticWnd1, 0);



  hEdit1 = CreateWindow (CTRL_EDIT,



  "Edit Box 1",



  WS_CHILD | WS_VISIBLE | WS_BORDER,



  IDC_EDIT1,



  20, 80, 100, 24, hStaticWnd1, 0);



  hStaticWnd2 = CreateWindow (CTRL_STATIC,



  "This is child static control",



  WS_CHILD | SS_NOTIFY | SS_SIMPLE | WS_VISIBLE | WS_BORDER,



  IDC_STATIC1,



  20, 110, 100, 50, hStaticWnd1, 0);



  hEdit2 = CreateWindow (CTRL_EDIT,



  "Edit Box 2",



  WS_CHILD | WS_VISIBLE | WS_BORDER,



  IDC_EDIT2,



  0, 20, 100, 24, hStaticWnd2, 0);



  break;



  }



  .......



  }



  return DefaultMainWinProc (hWnd, message, wPara



  
<< Linux数据库大比拚 truncate,delete,drop的异同点 >>
API:
gipsky.com& 安信网络
网友个人意见,不代表本站立场。对于发言内容,由发表者自负责任。

系统导航

 

Copyright © 2001-2010 安信网络. All Rights Reserved
京ICP备14013333号-8