打印

xwj优化的通用菜单程序

[复制链接]
楼主: xwj
手机看帖
扫描二维码
随时随地手机跟帖
21
xf.zhu| | 2007-11-2 13:58 | 只看该作者 回帖奖励 |倒序浏览

菜单结构稍差一点,通用性不强

使用特权

评论回复
22
xwj|  楼主 | 2007-11-2 14:13 | 只看该作者

晕~~~ 这菜单还算“菜单结构稍差”???

菜单就是菜单,程序就是程序,
特殊情况干嘛要做到通用菜单里?为什么不用末端子程序特殊处理?

19楼所说的问题也根本就不成问题:
关键的是一些特殊情况,比如:
1、参数输入
--参数输入属于非菜单部分的特殊程序,不管是显示、还是操作都不相同,为什么不作为一个“参数输入”的子程序
2、单选菜单
--何为“单选菜单”?菜单不都是“单选”的吗?有问题吗?
3、菜单选择对应具体功能的错误提示及错误处理
--增加typedef struct中的项啊,你想挂什么图片、文字、文件什么的自己加啊

使用特权

评论回复
23
夜风灯| | 2007-11-2 15:18 | 只看该作者

抄下来不如现在看,楼主不要介意我乱说呵

如果单是做菜单,我觉得很好。
1,菜单要变化,改数组KeyTab。19项?你要多少可以改为多少。程序菜单动也不要动。
2,按键增多,多个case就行了。如多了数字键,按数字直接跳到那个菜单,那就多个case:key_num。(估计按键的改变可能不大吧)
3,使用的变量很少,Menu_tree[],Menu_tree_ptr,Menu_item_ptr,就这几个吧。另外还有子程序调用时堆栈用的几个了。 

我提出几点:
1,如何把菜单按键与应用按键分开?
在现实中,up,down, ok, esc,这几个键一般菜单操作会和其它处理的用在一起呵。比如设置项,会用到OK或ESC吧。这样,菜单按键和处理中的按键,如果区分开。 
这里有个判断是菜单按键还是应用按键的子程序吧。现在问题是,这个程序放在那里?程序依据什么来判断?如果是一个标志,那么这个标志得在菜单变化时改变吧。这好像要用全局变量呀,全局变量不太想用。
好了,另外的一方法,case: KEY_UP里面,不是有一个if(是否菜单) 菜单处理;else 出错;这里就是一作出判断,是菜单还是应用。我在else下指向应用不就得了。好象这样做会多出很多东西来啊,这里得用指针把其转到应用中来吧。这个菜单简洁架构让其给搞乱了。

2,菜单变得复杂化时
当我们做出一行显示的菜单后,老板可能一时心血来潮就要我们做两行的,或者多行的。当要做两行时,也没什么问题,但是两行以上就难变了如下:
  菜单标题栏显示
   3,项目A
  *4,项目B
   5,项目C
*表示当前正在选择的项目。这样的菜单就有些复杂了,因为由3到4,或由4到5时,当前状态是不用全刷屏,只要把*移动就行了,但到了5到6时,他就要刷屏了。
我这里钻牛角尖了,因为很多时候不会用到这么复杂,但当用上128×64的屏时,呵呵……
这个时候,OK和ESC键就什么影响,但UP和Down就不同了,就得再次判断要不刷屏了。与其这样,不如开始判断时,就区分开是是4到5这类,还是5到6这类。

3,函数调用的级数。
0 main
   1 menu_key_fun
       2 refur_menu_item
       2 (*KeyFuncPtr)();//它下面还有很多级,即该函数再调用函数,函数下再调用。
由于函数A调用函数B时,函数A的局部变量不会释放,还占用着。这样一级一级下去,内存会用得很快。
可以减少嵌入调用,如把函数指针作为menu_key_fun的返回值返回,于是在main处有:
    KeyFunPtr = menu_key_fun();
    (*KeyFuncPtr)();
这样,执行指针函数(*KeyFuncPtr)()时,menu_key_fun()是释放了的。但是有时不是你想减少就得减少的,于是出了个消息机制。

使用特权

评论回复
24
huangqi412| | 2007-11-2 16:43 | 只看该作者

顶老x

使用特权

评论回复
25
左手换右手| | 2007-11-2 19:34 | 只看该作者

回lz,

 我说的单选菜单是这样:比如你要为测量数据选择单位,m,mm,cm等,那么m,mm和cm就是单选菜单,当页面跳到这个菜单时被选择的菜单前应该划勾表示一下。
 之所以提到参数输入,是因为参数输入是由菜单进入的,即使做了参数输入的程序,其和菜单程序也是密切相关的,至少应该定义一下菜单事件的参数输入特性指针什么的,这部分应该被包含在菜单程序中。
 
 特殊情况就太多了,简单例子:还是说单位选择,假如由于某种原因,现在的单位不允许是cm,那么在选择了cm菜单后应该出现提示“××单位不能为cm”情况,
 再比如说,输入密码,首先密码应该显示为**,选择确认菜单还要比较密码是否正确然后做相应处理。
 

  当然,所有的这些特殊情况都可以在key处理中单独处理,但是这样的程序总是感觉通用性不强,而且增加一个特殊情况就得增加一个if处理,很是麻烦,不知道在菜单结构里能否做通用的处理,比如搞个类似Windows的钩子函数什么的。

使用特权

评论回复
26
xf.zhu| | 2007-11-2 19:40 | 只看该作者

下面是主要部分,我这个扩充很简单,更容易理解

enum
{
    Menu,
    SHYCSH,
    JSGSH,
    RQXZH,
    SHYBH,
    LSHSHJ,
    DAYIN,
    DELAY,
    AREA,
    SHYZZH,
    SHYPZH,
    SHYTJ,
    SHYBZH,
    SHYXSH,
    VEIW_LSH,
    DEL_LSH,
    TAB_MAX
};
typedef    struct
{
    uchar    MenuIndex;        // 当前状态索引号
    uchar    Enter;            // 按下"enter"键时转向的状态索引号
    uchar    Esc;            // 按下"Esc"键时转向的状态索引号
    uchar    Left;            // 按下"Left"键时转向的状态索引号
    uchar    Right;            // 按下"Right"键时转向的状态索引号
    uchar    Up;                // 按下"Up"键时转向的状态索引号
    uchar    Down;            // 按下"Down"键时转向的状态索引号
    void    (code    *EnterOperate)();        // 按下"enter"应该执行的功能操作
}KeyTabStruct;

void    (code    *KeyFuncPc)();      // 按键功能指针

KeyTabStruct    code    KeyTab[TAB_MAX];

uchar    MenuId=Menu,        // 当前菜单索引号
        MenuNextId=SHYCSH,        // 当前活动菜单索引号
        FuncId=0,        // 菜单函数运行状态字
        Position;        // 光标索引号

void    Task_Menu()
{
    KeyFuncPc=KeyTab[MenuId].EnterOperate;
    (*KeyFuncPc)();
}
/*=================================================================
函数原型:void    Menu_Face()
函数说明:菜单主界面
入口参数:无
出口参数:无
=================================================================*/
void    Menu_Face()
{
    uchar    pos;

    switch    (FuncId)
    {
        case 0:
            Lcd_Clr();
            Disp_Face();
            FuncId++;
            break;
        case 1:
            if (!_testbit_(Key_Fg))
            {
                break;
            }
            switch (New_Key)
            {
                case Key_Up:
                    if (KeyTab[MenuNextId].Up!=0xff)
                    {
                        pos=MenuNextId;
                        MenuNextId=KeyTab[MenuNextId].Up;
                        Rufur_Face(pos,MenuNextId);
                    }
                    break;
                case Key_Right:
                    if (KeyTab[MenuNextId].Right!=0xff)
                    {
                        pos=MenuNextId;
                        MenuNextId=KeyTab[MenuNextId].Right;
                        Rufur_Face(pos,MenuNextId);
                    }
                    break;
                case Key_Esc:
                    Menu_Fg=0;
                    Run_Fg=1;
                    MenuId=KeyTab[MenuId].Esc;
                    FuncId=0;
                    break;
                case Key_Enter:
                    MenuId=MenuNextId;
                    MenuNextId=KeyTab[MenuId].Enter;
                    FuncId=0;
                    break;
                case Key_Area:
                    MenuId=AREA;
                    FuncId=0;
                    break;
            }
            break;
        default:
            FuncId=0;
            break;
    }
}


使用特权

评论回复
27
hotpower| | 2007-11-2 20:11 | 只看该作者

倒~~~怎么还不穿裤子???

使用特权

评论回复
28
一朝成名| | 2007-11-3 14:04 | 只看该作者

LZ那里去了?


typedef struct
{
   ..................
}Menustruct;
和下面     是不是有个写错的啊  
KeyTabstruct code KeyTab[]=
 

使用特权

评论回复
29
xwj|  楼主 | 2007-11-3 19:11 | 只看该作者

嗯,是写错了

只是个简单架构,抛砖引玉,希望引出更多的精彩讨论和更好的程序

使用特权

评论回复
30
jetbo| | 2007-11-22 16:12 | 只看该作者

8


精彩,好贴就得顶...

 if(*(KeyTab[Menu_tree][Menu_tree_ptr]].Menu_NextTab))  

这句到底是怎么执行的?愣是没弄明白 

使用特权

评论回复
31
jingxinli| | 2007-12-10 00:18 | 只看该作者

不错,顶

使用特权

评论回复
32
mikezhong| | 2007-12-10 00:49 | 只看该作者

要学习

要学习XWJ.要学习程序..

使用特权

评论回复
33
jjg| | 2007-12-10 12:48 | 只看该作者

好贴.顶!

使用特权

评论回复
34
2_1_I_C| | 2007-12-10 13:57 | 只看该作者

学学

使用特权

评论回复
35
太阳很能| | 2010-4-6 10:59 | 只看该作者

使用特权

评论回复
36
zhg_wx| | 2010-4-7 22:39 | 只看该作者
mark
1# xwj

使用特权

评论回复
37
luck851| | 2010-4-19 15:50 | 只看该作者
mark

使用特权

评论回复
38
mymeter| | 2010-12-1 18:45 | 只看该作者
xuwenjun  xwj 第一感觉是下位机

使用特权

评论回复
39
armmage| | 2010-12-1 19:48 | 只看该作者
X大侠也就抛砖引玉而已,大家别太挑刺。
结构体封装菜单,这个问题怎么处理嘛一看就知道是有心人还是庸人。(话说庸人程序见多了)
我更关心的是如何组织屏幕现实的信息,包括显示坐标,显示内容,此内容被选中或内容变更后的显示,等高级属性。话说楼上有人提到过使用12864的液晶屏,如果用的是更大的 320240或600480,那么菜单图形组织就更重要了。

使用特权

评论回复
40
dragon20100708| | 2010-12-3 14:28 | 只看该作者
支持!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则