软键盘输入设计(C语言)

前言

之前写过一篇关于软键盘输入设计的文章点击这里查看,用的是掌机自支持的zzdbase语言,文章结尾说了其实最初想用C来实现的,但是中途遇到了困难,便改为zzdbase语言了。最近项目中想到一个比较好的软件架构,刚好用来编写之前的软键盘输入程序。花了半天时间,将原来的代码改为了c预言实现。

本次主要更改的地方

  1. 软件架构更改(本文章不叙述)
  2. 软键盘实现
  3. 硬键盘与软键盘切换
  4. 一些小优化

软键盘实现(主要看代码)

首先定义ASCII码表,用10进制表示。最后一个为“0”,为空字符。码表之所以定义成这种,是考虑到了键盘布局和输入方便的因素。

U8 ASCData[27]={126,33,64,35,36,37,94,38,44,92,61,60,62,63,91,93,123,125,95,124,96,39,32,34,59,58,0};

下面是根据定义好的ASCII码表来显示软键盘。

void DoShowKeyboard(void)
{

    U8 i;
    U8 num_temp[1];
    U8 row;
    /* 设置屏幕背景 */ 
    ClearLCDn(6,3);
    ShowString(6,0,"                    ",LCD_COLOR_NAG);
    ShowString(7,0,"                    ",LCD_COLOR_NAG);
    ShowString(8,0,"                    ",LCD_COLOR_NAG);

    //3行显示    
    for(i=0;i<27;i++)
    {

        if (i<=8)
        {
            row = (i+1)*2;
            sprintf(num_temp,"%c",ASCData[i]);
            if (i == 0)
            {
                ShowString(6,row,num_temp,LCD_COLOR_POS); // 默认第一个高亮选中
            }
            else
            {
                ShowString(6,row,num_temp,LCD_COLOR_NAG);
            }
        }
        else if ((i<=17)&&(i>=9))
        {
            row = (i-8)*2;
            sprintf(num_temp,"%c",ASCData[i]);
            ShowString(7,row,num_temp,LCD_COLOR_NAG);
        }
        else if ((i<=26)&&(i>=18))
        {
            row = (i-17)*2;
            sprintf(num_temp,"%c",ASCData[i]);
            ShowString(8,row,num_temp,LCD_COLOR_NAG);
        }
        else
        {
            break;
        }
    }
}

软硬键盘切换输入

软硬键盘切换输入的实现主要通过侦听键盘按键,如按下切换键(本例设置为KEY_HELP),则在两种模式之间进行切换,实现两种模式的字符输入。

/* 输入主函数 */
U8 DoInputValues(U8 * buf, U8 len)
{
    S16 Key;  //接收键盘输入的键值
    U8 len_fact = 0; //已输入的字符串长度
    U8 CursorPos = 0;// 定义一个目前输入模式,0-硬键盘输入  1-软键盘输入
    U8 KeyL; //键值低8位字节 用来显示硬键盘输入的ASCii码
    U8 res;

    _setkeymode(2);

    LOOP6:for(;;)
    {
        DoRefreshShow(buf,len_fact); // 刷新已输入字符串显示

        if (CursorPos == 0)  // 硬键盘输入模式
        {
            GotoCursor(2,0);

            Key = _bioskey(0); //监听输入键值 

            if (Key == ESC) //退出键
            {
                return 1;
            }
            else if (Key == ENTER) //确认键
            {
                return len_fact;
            }
            else if (Key == DEL) // 删除键
            {
                if (len_fact == 0)
                {
                    goto LOOP6;
                }
                else // 已输入字符串长度不为0,删除最后一个字符(置0值)
                {
                    len_fact--;
                    memset(buf+len_fact,0x00,1);
                    goto LOOP6;
                }
            }
            else if (Key == KEY_HELP)// 帮助键 切换到软键盘输入
            {
                CursorPos = 1;
                goto LOOP6;
            }
            else // 硬键盘输入键值 如 A B C 1 2 3等
            {
                ;
            }
        }
        else if (CursorPos == 1) // 软键盘输入模式 执行软键盘输入函数
        {
            res = DoSoftwareInput(buf,&len_fact);
            if (res == 1)
            {
                CursorPos = 0;
                goto LOOP6;
            }
        }

        KeyL = (U8)(Key&0x00FF); // 取硬键盘输入键值低8位 保存其ASCII码

        *(buf + len_fact) = (U8)(KeyL);
        len_fact++;

    }
}

软键盘输入函数

U8 DoSoftwareInput(U8 * buf, U8 *len)
{
    S16 keyvalue;
    S8 index = 0;
    S8 indexold=0;
    U8 line,row;
    U8 num_temp[1];
    U8 *tempbuf = buf;
    U8 lentemp;

    lentemp = *len; // 传入已输入字符串长度指针

    DoShowKeyboard(); // 显示软键盘

    loop4:for(;;)
    {
        _setdispcolor(LCD_COLOR_POS);
        DoRefreshShow(tempbuf,lentemp); // 刷新显示
        GotoCursor(2,0);

        keyvalue = _bioskey(0); // 监听键盘按键

        if (keyvalue == ENTER) // 确认,将当前软键盘高亮的字符保存
        {
            if (lentemp == 32)
            {
                ;
            }
            else if (lentemp<32)
            {
                *(tempbuf + lentemp) = ASCData[index];
                lentemp++;
            }
            else
            {
                ;
            }
            goto loop4;
        }
        else if ((keyvalue == ESC)||(keyvalue == KEY_HELP)) // 退出软键盘输入 切换到硬键盘
        {
            DoQuitKeyboard();
            *len = lentemp;
            return 1;
        }
        else if (keyvalue == DEL) // 删除 删除最后一个字符
        {
            if (lentemp == 0)
            {
                ;
            }
            else
            {
                lentemp--;
                *(tempbuf + lentemp) = 0x00;
            }
            goto loop4;
        }
        else if (keyvalue == UP) // 向上键  软键盘高亮数字移动
        {
            indexold = index;
            index -= 9;
            if (indexold == 8)
            {
                index = 17;
            }
            else if (index < 0)
            {
                index = index+27;
            }
        }
        else if (keyvalue == DOWN)
        {
            indexold = index;
            index += 9;
            if (indexold == 17)
            {
                index = 8;
            }
            else if (index > 25)
            {
                index = index-27;
            }
        }
        else if (keyvalue == LEFT)
        {

            indexold = index;
            index--;
            if (index < 0)
            {
                index = 25;
            }
        }
        else if (keyvalue == RIGHT)
        {
            indexold = index;
            index++;
            if (index > 25)
            {
                index = 0;
            }
        }
        else
        {
            goto loop4;
        }

        // 新选中的字符变为高亮状态 index索引ASCII表位置
        if ((index>=0)&&(index<=8))
        {
            line = 6;
            row = (index+1)*2;
        }
        if ((index>=9)&&(index<=17))
        {
            line = 7;
            row = (index-8)*2;
        }
        if ((index>=18)&&(index<=26))
        {
            line = 8;
            row = (index-17)*2;
        }

        sprintf(num_temp,"%c",ASCData[index]);
        ShowString(line,row,num_temp,LCD_COLOR_POS);

        // 原来高亮的字符变为非高亮 indexold索引其ASCII位置
        if ((indexold>=0)&&(indexold<=8))
        {
            line = 6;
            row = (indexold+1)*2;
        }
        if ((indexold>=9)&&(indexold<=17))
        {
            line = 7;
            row = (indexold-8)*2;
        }
        if ((indexold>=18)&&(indexold<=26))
        {
            line = 8;
            row = (indexold-17)*2;
        }

        sprintf(num_temp,"%c",ASCData[indexold]);
        ShowString(line,row,num_temp,LCD_COLOR_NAG);
    }
}

小的优化

C语言相比于zzdbase语言更具有灵活性,可自我发挥空间更大。例如在修改此例中,将原来zzdbase语言封装好的发送接收自己重新做了调整,加入了定时,可以用来判断接收超时。

// 发送接收函数  
void DoSendAndReceive(U8 *Sendbuf, U8 *Sendlen, U8 *Recvbuf, U8 *Recvlen)
{
    U8 i,res;
    U8 tempsendlen,temprecvlen; // 定义发送接收长度
    U8 tempsendbuf[256],temprecvbuf[256]; //定义发送接收缓冲区
    U8 starttime[9]={0}; //定义计时开始时间
    U8 endtime[9]={0}; //定义计时结束时间
    U8 startsecond,endsecond; // 开始 结束 秒
    U8 delay; //接收延时


    tempsendlen = *Sendlen;

    memcpy(tempsendbuf,Sendbuf,tempsendlen); 

    for(i=0;i<tempsendlen;i++)
    {
        _com_send(tempsendbuf[i]);
    }

    memset(temprecvbuf,0x00,sizeof(temprecvbuf)); //接收缓冲初始化

    ClearMid();
    ShowString(1,0,"数据接收中...",LCD_COLOR_POS);

    //接收计时,超过设置值退出(接收超时)
    _gettime(starttime);//获取当前时间,保存到计时开始
    startsecond= (U8)(((starttime[6] - '0') * 10) + (starttime[7] - '0'));// 保存开始计时 秒

    do{
            res = _com_read_buf(temprecvbuf,&temprecvlen,256,500); // 接收侦听循环

            _gettime(endtime);
            endsecond= (U8)((endtime[6] - '0') * 10 + (endtime[7] - '0'));

            if (endsecond < startsecond)
            {
                endsecond += 60;
            }

            delay = endsecond - startsecond;

            ShowTime(2,0,delay); // 显示已过去的时间

            if (delay > 3) //默认接收3秒 超过3s 退出侦听,判断为接收超时
            {
                break;
            }
        }while(res==1);

        if (temprecvlen != 0) // 接收到数据  数据和长度传给指针
        {
            memcpy(Recvbuf,temprecvbuf,temprecvlen);
            *Recvlen = temprecvlen;
        }
        else
        {
            ;
        }

}

通过此次的更改对比,发现C语言的优势便在于灵活性非常强,不受掌机库函数的限制,而且经过测试发现,更改后的C语言程序版本比之前的zzdbase语言版本更稳定,操作性更强,主要是因为在c版本上做了一些优化,并且更改了软件框架,使之更容易实现我所需要的功能。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董董灿是个攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值