PalmOS开发教程-4
第四章 窗体的编程 |
在本章中,我将通过为上一章的Contacts程序添加一个About对话框,继续向读者展示Palm OS简单有效的程序风格。你将学会如何创建含有位图、文本和按钮的窗体。你可在Contacts程序中加入菜单和代码使你可以访问About对话框并重新回到Contacts主窗体。
在此过程中,我们将先了解应用程序的基本设置,将为Contacts程序创建一个大的和一个小的应用程序图标。 程序设置 首先,为你的程序做一个备份: 创建大小应用程序图标 注意: 2.在Contacts.rsrc窗口的底部找到工程设置图标。如果在窗口的底部只有一个指向右方箭头,单击则工程设置就会弹出。在工程设置中一般要改变的有:应用程序图标的名字、版本字符串和应用程序图标。在上一章节中你已经改变了应用程序图标的名称。表4-1列出了所有设置极其功能: 名称 描述 Application Icon Name 应用程序的名称 Version String 应用程序的版本号。当对你的应用程序做出有意义修改后,你应该提高版本号表示不同版本。 Application Icon 定义了黑白的程序大图标,这是为Palm OS 2.0和更早版本准备的,在这里不用。 Auto Generate Header File 资源构造器自动生成头文件。选中。 Include Details in Header 资源构造器向头文件中添加 Keep Ids in Sync 使资源构造器在控件ID改变时自动更改ID。如果你在程序中不大改变ID,你可以不选;但在一般情况下,选中会更好。 表4-1:资源构造器中工程设置的选项。 4.双击新图标,弹出一个编辑窗口,你现在就可以在里面画图了。通过选择编辑窗口右端的两个图标,确定颜色为黑白(black and white)还是2位的灰度级。编辑窗口内的编辑控件和Windows下的画图(Paint)及其它作图程序都很相似。当完成后,按窗口顶部右端的X即可关闭窗口。图4-1是本人所画的大图标; 图4-1 一个Contacts程序中的大图标 5. 接下来创建一个应用程序小图标。它只能在Palm OS 3.0或更高版本显示。打开Contactas.rsrc窗口,在Resource Type 和Name面板上选择Multibit Icons; 6. 按下CTRL-K创建一个新图标; 7. 点击ID,将其改为1001,这一步十分重要; 8. 点击新图标。弹出图标编辑窗口,由于Palm OS只显示上部9象素和最左端的15象素,在设计时要注意。本人所画的小图标如图4-2所示; CodeWarrior集成开发环境中的工程设置 这部分所讲的是如何在使用应用程序的设置: 注意: 如前所述,在Palm设备中所有东西都是以数据库的形式保存的,应用程序也不例外。每个数据库都必须有唯一的名称,否则就会出现问题。Contacts-PPGU就是和它的唯一原始(creator)ID相关联的文件名,这样命名可以保证唯一性。有关更多原始ID的内容,请参看下一章。 在Contact Settings子树下还有很多其他的设置属性,但是这时候还没必要去设置它们。如果你感兴趣的话,可以参考CodeWarrior集成开发环境指南(Guide)的有关内容。 多窗体界面 Contacts.rsrc文件中内容的添加 表4-2 窗体属性 Left Origin 窗体的左侧位置的象素数,整个屏幕为160象素。 Top Origin 窗体的顶部位置的象素数,整个屏幕从上到下为160象素。 Width 窗体的宽度,窗体不一定占满整个屏幕。 Height 窗体的高度。 Save Behind 如果选中,窗体关闭后,对窗体操作前的屏幕上窗体后的内容将被保存。 Form ID 窗体的ID号,ID唯一标识窗体。 Help ID 如果窗体为Modal,可填入代表帮助信息资源文件的ID字符串,在窗体的右上角会出现一个“i”图标。如果按下,则帮助信息就会被调出。在Date Book应用程序中的Details窗体有一个这样的例子可供参考。 Menu Bar ID 窗体菜单栏的ID号,在最后一章节中,我们将利用这一属性添加一个菜单拦。 Default Button ID 如果提供了此ID号,当用户切换的其它应用程序时,Palm OS在退出前会自动按下此按钮。这对Modal窗体来说尤其方便,经常使用的缺省按钮为Cancel。 添加位图 Object ID 在窗体中标识位图唯一的ID号。此号不能和应用程序中其它任何的ID号相同。 Object Identifier 位图的名称。 Left Origin 位图左边位置的象素数,全屏幕左右长度为160象素。 Top Origin 位图顶部位置的象素数,全屏幕上下长度为160象素。 Bitmap Resource ID 决定位图的资源文件的ID号。 Usable 决定位图的可见与否。只有当标识为Usable时,位图才可见。 添加标签 现在创建一个包含Contacts信息的标签。你可以从Catalog窗口把一个标签拖到窗体上。表4-4列出了标签对象的属性。 Object Identifier 标签名。构造器在Contacts_res.h文件中创建的变量就来源于此名。 Label ID Palm OS用来识别该对象的唯一ID号。 Left Origin 标签左边位置的象素数。全屏幕左右长度为160象素。标签的长度由它包含的文字数决定。 Top Origin 标签顶端位置的象素数。全屏幕上下长度为160象素。标签包含文字的行数和字体的大小将决定标签的高度。 Usable 决定标签是否在窗体上可见。如果未选中的话,标签为不可见。当你想不改变窗体而使控件可见或不可见时,就要用到此设置。 Font 标签内文字字体的大小。你可以通过Windows Key Caps 实用工具查找你所需字体。 Text 标签内显示的文字。 在标签中的内容一般为应用程序的名字、你或你的公司的名称、版权信息和程序的版本号等。我创建了两个标签是为了使Contacts的字体比剩下的字体大一些。 添加按钮 Object Identifier 按钮的名称。构造器在 Contacts_res.h文件中创建的变量就来源于此名。 Button ID Palm OS用来识别该对象的唯一ID号。 Left Origin 按钮左边位置的象素数。全屏幕左右长度为160象素。由于按钮的左侧边到窗体的边框至少需一个象素,所以按钮的最左端也应置1。对bold按钮来说,要需二个象素。 Width 按钮的宽度。而实际的宽度,对普通按钮来说应加2,对bold按钮来讲应加2。 Height 按钮的高度。而实际的宽度,对普通按钮来说应加2,对bold按钮来讲应加2。 Anchor Left 决定当应用程序运行时,在改变标签长度时,按钮的大小怎样作自我调整。当被选中时,则按钮的右端会做相应的伸长或缩短;否则,按钮的左侧作相应的伸长或缩短。 Frame 如果被选中,则按钮有一边框。 Non-Bold Frame 如果选中,则按钮边框占一象素;否则,边框占二象素宽。 Font 按钮上文字字体的大小。你可以通过Windows Key Caps 实用工具查找你需要的字体。 Label 按钮上显示的文字。 添加菜单 向Contracts.c添加代码 Form-Loading代码更广的应用 // Prototypes for our event handler functions myHandleEvent()函数的头部应修改如下: // Our Contact DETAIL form event handler functions 下一步,我们处理一个名为frmOpenEvent的事件。当从一个窗体切换到另一个窗体时,该事件被发送。在修改事件处理器以切换窗体之后,我要说明怎样修改窗体。 Word index; // CH.3 A general purpose index // CH.3 Get our form pointer // CH.4 Parse events // CH.3 Get the pointer to our field // CH.3 Set the editable text // CH.2 Draw the form // CH.3 Set the focus to our field frmOpenEvent块中,剪切从PilotMain()至事件循环的代码,把代码放到这里。这样,当我们在窗体之间切换时,每当窗体被显示时这段代码将被执行。在执行应用程序时,这 在我们切换窗体之前,最好先获取源窗体文本框中的内容。这是因为当我们切换到一个新的窗体时,与原窗体相关的所有内存都将被释放。这样一旦我们返回原窗体时就会碰到大麻烦。 我们通过对frmCloseEvent的处理来获取文本句柄。在切换到另一个窗体时,当前窗体被注销前,frmCloseEvent事件被触发。 // CH.4 Form close event // CH.3 Get the pointer to our field // CH.4 Unlink our handle from the field 我们在这里所做的一切是获取指向域的指针,将它的文本句柄设为NULL。 我们需要用一个将导致frmOpenEvent被发送的调用来替换我们从PilotMain()中剪切下来的代码。如果我们不这样做,什么事情都不会发生。我们将永远盯着一个空白屏幕,因为第一个窗体永远不会被加载。你用来发送frmLoadForm和frmOpenForm事件来切换窗体的函数是FrmGotoForm()。在PilotMain()中FrmGotoForm()之外的代码如下: //CH.3 Release the string resource //CH.4 Go to our starting page //CH.2 Our event loop 用于推广窗体加载的最后一点代码是将事件处理函数从一个窗体切换至另一个窗体。每一个窗体有它自己的事件处理。一个好的方法是应答frmLoadForm事件,即使是在主事件循环中。代码如下: // CH.3 Handle menu events // CH.4 Handle form load events // CH.4 About form // CH.2 Handle form events 对每一个我们要加载的窗体,我们在switch语句中增加case语句来初始化窗体并设置对应的事件处理。 现在是为我们在上一章中分配的内存在做一些工作的时候了。尽管当应用进程从内存卸下时我们的文本句柄将被释放,我们最好还是在PilotMain()末尾显式卸载它,因为关闭窗体不再释放其内的文本句柄。 // CH.4 Deallocate memory // CH.2 We're done 程序的整洁性是与应用进程是否崩溃的相关的重要因素。当你的程序变得越来越复杂,你的程序代码到处搬动时,有序地分配和释放内存将为你免去应用程序崩溃之灾,为你节约大量时间。 处理Options菜单 // CH.3 Erase the menu status from the display // CH.4 Handle options menu // CH.3 Handle graffiti help 在调用MenuEraseStatus()之后在MenuEventHandler()中增加的代码将正常运转。你检查新选择项的ID,然后调用FrmPopusForm()。FrmPopusForm()与FrmGotoForm()相似,除了旧的窗体从不关闭。这在About窗体中是恰当的,因为我们知道我们将从About窗体中返回到Contact Detail窗体中。除此之外没有别的路径。 这意味着我们不需要作我们在上一章所做的通用的窗体变换工作。尽管如此,我们最好加上窗体变换代码,这样我们不必担心在加入窗体时使Contact Detail窗体的行为变乱。 注意:在这里我们在处理代码中原本为了处理edit菜单的options菜单。这是怎么回事?原来,Contructor(构造器)给所有菜单的所有菜单项赋予唯一的ID号。因此,没必要单独处理某一组菜单项。 为About窗体加入一个事件处理 每一个窗体应有它自己的时间处理,因此我们为新的About窗体添加一个事件处理。首先,为About窗体的事件处理函数添加一个函数原型,称之为aboutHandleEvent()。代码如下: // CH.3 Prototypes for our event handler functions 然后,在处理frmLoadEvent的事件循环中加入代码。这段代码将对About窗体初始化并以FrmDispatchEvent()为目标加入事件处理函数。 // CH.4 Initialize our form // CH.4 About form 剩下的所有的事就是加入时间处理函数aboutHandleEvent()。 // CH.4 Our About form event handler function // CH.4 Get our form pointer // CH.4 Respond to the Open event // CH.4 Return to the calling form // CH.4 Always return true in this case 事件处理函数对frmOpenEvent应答以唯一的显示窗体基本调用:FrmDrawForm()。它也像我们的第一个Hello应用程序一样应答ctlSelectEvent,除了在这一次,它不发送告警,而是调用FrmReturnToForm()。FrmReturnToForm()函数使About窗体被消灭,该窗体的调用窗体(在这里是Contact Detail窗体)被重激活。 注意:在返回调用窗体时返回true是十分重要的。原因是否则Palm OS试图全面处理cltSelectEvent事件,处理工作包括处理在调用FrmReturnToForm中被你消灭的结构。为了避免这些内存恶作剧,在FrmReturnToForm之后总是返回true, 这样窗体会立即消失。 调试 如同以前一样,程序在PilotMain()开始执行,按照它通常的路径走下去。当frmLoadEvent 接下来讲什么? 源代码 // CH.2 The super-include for PalmOS // CH.3 Our resource file // CH.3 Prototypes for our event handler functions // CH.3 Our field memory handle // CH.4 Constants for ROM revision // CH.2 The main entry point // CH.4 Get the ROM version // CH.4 If we are below our minimum acceptable ROM revision // CH.4 PalmOS 1.0 will continuously re-launch this app // CH.2 If this is not a normal launch, don't launch // CH.3 Get the initialization string resource handle // CH.3 Lock the resource, get the pointer // CH.3 Allocate our field chunk // CH.3 Lock the memory, get the pointer // CH.3 Initialize it // CH.3 Unlock the field's memory // CH.3 Unlock the resource's memory // CH.3 Release the string resource // CH.4 Go to our starting page // CH.2 Our event loop // CH.2 Handle system events // CH.3 Handle menu events // CH.4 Handle form load events // CH.4 About form // CH.2 Handle form events // CH.2 If it's a stop event, exit // CH.4 Deallocate memory // CH.2 We're done // CH.4 Our Contacts form handler function // CH.3 Get our form pointer // CH.4 Parse events // CH.3 Get the pointer to our field // CH.3 Set the editable text // CH.2 Draw the form // CH.3 Set the focus to our field // CH.4 Form close event // CH.3 Get the pointer to our field // CH.4 Unlink our handle from the field // CH.3 Parse menu events // CH.2 We're done // CH.4 Our About form event handler function // CH.4 Get our form pointer // CH.4 Respond to the Open event // CH.4 Return to the calling form // CH.4 Always return true in this case // CH.4 We're done // CH.3 Handle menu events // CH.3 Get our form pointer // CH.3 Erase the menu status from the display // CH.4 Handle options menu // CH.3 Handle graffiti help // CH.3 Get the index of our field // CH.3 If there is no field selected, we're done // CH.3 Get the pointer of our field // CH.3 Do the edit command // CH.3 Cut // CH.3 Copy // CH.3 Paste // CH.3 Select All // CH.3 Sound an error if appropriate // CH.3 Select the whole string // CH.3 Bring up the keyboard tool // CH.3 We're done |
PalmOS开发教程-4相关推荐
- PalmOS开发教程-5
第五章 数据库 Palm OS的所有内容在其存储器中都表现为数据库形式,下面我们就开始学习创建和使用数据库.我们将继续编写Contacts程序,把它写入一个数据库. 删除工作 为准备向Con ...
- PalmOS开发教程-12
第十二章 专业编程技巧 随着程序变得越来越大,我们会发现很多问题.这些问题或许在编制几千行代码时不会出现,但是当编到上万行或更多时并且程序由不同的程序员来编写,在运行时问题就出现了. 这就要 ...
- PalmOS开发教程-2
第二章 建立一个应用程序 无论你是一位编程专家还是初学者,通过本章的学习,你都将很快的学会Palm OS的编程.在这个过程中你首先要创建一个能稳定工作的开发环境.值得一提的是,开发环境并不仅 ...
- PalmOS开发教程-1
第一章 关于Palm 本章将对Palm这个新奇的东西进行一些简单的介绍.对于有一定的嵌入式软件开发基础,又想尽快开始编程的读者,我建议你跳过本章,直接从第二章开始阅读,等闲暇时间再回到本章浏 ...
- PalmOS开发教程-7
第七章 列表框和排序 在这一章中,将接触到一些新的控件和数据库操作技巧.我们先生成一个窗体来显示contact数据库中的所有记录,然后创建一个下拉框供选择排序标准,最后添加代码进行排序,并使 ...
- PalmOS开发教程-8
第八章 表和滚动条 在这一章中,我们将讨论Palm OS的两个很重要的用户界面元素:表和滚动条.表能够显示或编辑较大的数据量.在嵌入式应用程序中都它使用的很广泛.滚动条的功能很出色,但由于滚 ...
- PalmOS开发教程-9
第九章 分类和查找 在这一章中,我们在Contacts程序中添加分类.分类允许把Contacts分成组,如Business和Personal.你可以分别或统一查看这些组.你还可以为Conta ...
- PalmOS开发教程-13
第十三章 再论用户界面 在这一章和下一章中,我们将创建一个完整的计算器应用程序.从中我们将学到怎样使用公共函数库,特别是如何使用MathlLib,我们还会学到许多编程的细节及如何改善用户界面 ...
- PalmOS开发教程-3
第三章 文本框中的乐趣 在本章节中,我们将通过讨论第二章中Hello应用程序的副本,来研究文本框的属性和事件.涉及的内容包括文本框如何调用Palm OS存储器和处理它们之间的关系等.我们也将 ...
最新文章
- 洛谷P4016 负载平衡问题
- java stopwatch 功能
- 在pl/sql中使用exp/imp工具实现oracle数据导出/导入
- html_5_小作业1_超链接练习
- shell 杂记一(笨鸟)
- java基础学完_学完Java基础应该继续学什么?
- 【SCOI2005】【BZOJ1083】繁忙的都市(MST模板)
- feign multipartfile 多文件上传_Spring Cloud Alibaba 实战(六) - 声明式HTTP客户端-Feign
- python好用的模块_Python中好用的模块们
- 揭秘马云帝国内幕:马云的野心有多大
- cicso+RHEL7实践——小型校园网的搭建
- Base64原理和转换会变大33%左右的原因
- 十月下旬腾讯,网易游戏,百度迅雷校园招聘笔试题集锦(第271-330题)
- oracle外部表报错ora29400,报错ORA-29913 ORA-29400
- 北语计算机基础知识作业1,【图】- 北京语言大学20秋《计算机基础》作业1 - 昆山经济开发区其他教育培训 - 昆山百姓网...
- Vite+Vue3+TypeScript
- 提交微信小程序代码到微信代码管理git上
- MySQL 真·常用函数
- C++ 打怪小游戏3.1
- 绿地深蓝机器人_人工智能国家队再获加持,国有世界五百强绿地控股战略投资深兰科技...