马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
总的来说,Microchip Graphic
Library是一个相当不错的图形库。占用资源少,实现简单但功能很全面,适用于一些不需要复杂GUI显示、资源不多的应用场合。对于像我这样的学习者而言,其代码量少、结构清晰、易于学习更吸引我的注意。在阅读这个图形库的源码时,有一些心得体会,一一纪录在此。
1.1 存在的问题
在分析图形库的源码及编写简单的应用代码时,发现存在着若干的问题。部分问题已经在各层的源码分析中有说明,这里再做一些补充。
1.1.1 通用性不如µC/GUI
这个图形库是Microchip针对自家的产品设计的,用于PIC24F, PIC24H, dsPIC,
PIC32系列处理器,并且使用自家的开发工具。也就是说,这个图形库的设计时就不像µC/GUI那么通用了。并且其License限定只能在Microchip的芯片上免费使用,天下没有白费的午餐。
1.1.2 编码问题
整体上感觉该图形库的代码虽然少、结构清晰,但是在其它的平台编译,有时会报错,或者警告一大堆。难道说只能在Microchip的开发环境上无警告、无错的编译?问题举例如下:
1、 返回值问题:如程序清单6.1所示的代码,
WORD为无符号类型,但RbGetCheck()最后返回的值却是有符号值-1。虽然-1就是0xffff,但在Visual C++
6.0环境下编译时会出现警告。在该图形库中还有其它地方存在同样类型的代码,所以如果编译整个图形库,会出现不少的警告。这让我很不舒服。
程序清单6.1 返回值问题代码
?
0102
0304
0506
0708
0910
1112
1314
1516
1718
19 |
typedef unsigned short int WORD; // 16-bit unsigned WORD RbGetCheck(RADIOBUTTON *pRb) { RADIOBUTTON *pointer; pointer = (RADIOBUTTON *)pRb->pHead; while(pointer != NULL) { if(GetState(pointer, RB_CHECKED)) { return (pointer->hdr.ID); } pointer = (RADIOBUTTON *)pointer->pNext; } return (-1); } |
2、
无法同时使用触摸屏和按键设备:如程序清单6.2所示,如果我们在GraphicsConfig.h中同时作如下定义,然后编译该图形库,编译将失败。
?
12 |
#define USE_TOUCHSCREEN // Enable touch screen support. #define USE_KEYBOARD // Enable key board support. |
造成编译失败的代码如程序清单6.2。很明显,红色部分的代码造成了该问题。不知道是Microchip在设计该GUI时就决定不能同时使用按键设备和触摸设备,还是编码者在设计时没有做过代码测试?
程序清单6.2 同时使用按键和触屏设备引起问题的代码
?
0102
0304
0506
0708
0910
1112
1314
1516
1718
1920
21 |
WORD RdiaTranslateMsg(ROUNDDIAL *pDia, GOL_MSG *pMsg) { #ifdef USE_TOUCHSCREEN SHORT touchRadius, touchX, touchY; static SHORT prevX = -1, prevY = -1; WORD messageID = OBJ_MSG_INVALID; if(GetState(pDia, RDIA_DISABLED)) return (OBJ_MSG_INVALID); #endif #ifdef USE_KEYBOARD SHORT newValue; // 编译出错 if(GetState(pDia, RDIA_DISABLED)) return (OBJ_MSG_INVALID); #endif return (OBJ_MSG_INVALID); } |
3、
令我费解的switch-case结构:程序清单6.3中的代码是该结构的表现。我不明白为何可以在if结构内嵌套一个case?既然代码能够正常工作,相信这种结构也是正确的。但是受限于个人水平,我很难理解这种结构。也许我该查看该代码的汇编语言,了解其执行流程。
程序清单6.3 令我费解的switch-case结构
?
0102
0304
0506
0708
0910
1112
1314
15 |
WORD WndDraw(WINDOW *pW) { case WND_REMOVE: if(GetState(pW, WND_DRAW_CLIENT)) { state = WND_CLIENT; break; case WND_CLIENT: } |
4、
GOTO语句的使用:这里并不讨论什么结构化编程的问题。只是受限于自己的编程水平和代码编写习惯,自己还从未在C中用过GOTO,在汇编语言中倒是用的不少。看这样的代码,对我来说,还真不习惯。
程序清单6.4 GOTO语句使用
?
0102
0304
0506
0708
0910
11 |
WORD RbDraw(RADIOBUTTON *pRb) { switch(state) { case REMOVE: goto rb_draw_check; rb_draw_check: } } |
1.1.3 不支持多任务环境
这个图形库只能使用在前后台系统中。或者是在多任务环境下,仅能由一个任务使用该图形库,不能像µC/GUI能同时被多个任务所使用。该图形库没有对多任务环境做出支持,可能Microchip在设计该图形库时仅仅考虑的是针对自己的产品,所以认为没必要支持。在一些物件的绘制函数中,可以发现很多静态变量,这些函数是不可重入的。
1.1.4 不支持窗口重叠
当多个物件相互之间有重叠时,这时的显示问题就得由用户自行处理了。不像µC/GUI那样内部会自动进行处理。
另外,已经创建的部件之间的关系是比较松散的。在GOL层中仅维护了一个“活动链表”。
1.2 关于GUI的杂谈
1.2.1 为什么要使用GUI?
我觉得使用GUI,其目的就是增强产品的易用性。可想早期的DOS系统与之后的WINDOW系统,其易用性的差别是非常明显的。
GUI无非就是服务人的手、眼。简单易用的界面,按下按触摸屏即可实现控制,不必再敲命令,减少了手的劳动量;更美观、更炫、更丰富的界面,让人的视觉上感觉相当舒服,用户使用时感觉更爽。所以俗一点说,GUI的出现,就是为了满足人的偷懒欲望。而开发人员使用GUI,是为了让自己的产品卖得更好,为那些懒惰的人服务。
不过,正是这种方式,才有了今天现在社会的进步!哈哈哈~~~
1.2.2 资源占用少以牺牲性能为代价
Microchip Graphic
Library占用资源少,是因为它设计的简单性。相对于µC/GUI来说,其资源占用要少很多,并且也易于理解。Microchip在其介绍该图形库的PPT中着重强调了这点。对于像我这样少的初学者而言,这是令人兴奋的。但是不容忽视的是,资源占用少,意味着其功能会弱很多。µC/GUI中的很多特性,Microchip是没有实现的。在使用一个GUI时,应当根据所应用的场合来选择,而不是单纯地强调某个方面。很多公司在宣传其产品时,往往是故意强调某个比较突出的特性,并以此特性与其它公司同类产生相比较,而没有进行更全面的比较。这是一种推广策略。据说,在向客户推销产品时,其中要做的一点便是挖掘客户的“痛苦点”,将其“无限放大”,然后再将自己公司的产品推销给客户。 |