emwin+字库芯片实现按钮文字内容任意

 在前几天调试通了字库芯片取模的代码部分,然后就想可不可以直接使用字库芯片而不再用emwin的字库工具生成的方式来设置控件的文字内容。网上搜索了一些资料,没有找到满意的答案,自己动手实现了一个按钮控件的。觉得有点麻烦,准备放弃了,毕竟对于按钮来说不会没事就更换按钮上的文字,还是采用传统的方式为好。反倒是像text,edit,multiedit等控件更需要能够支持字库芯片。那是后续的事情了,我先把按钮的实现方式发出来,给大家一个参考:其实说白了也没啥,就是自己实现按钮控件的回调函数,在WM_PAINT响应事件中按照自己的需求对按钮进行绘制。这里面涉及到一个问题,就是屏幕坐标的转换。我没有使用emwin提供的字符串显示接口函数,而是用自己写的函数替代,不知道有没有什么问题,下面是实现的代码。先贴一个直接向屏幕写字符串的函数,这个是不擦除背景图案直接写字符串的,可以中英文混合输入,可以通过space指定字符间距,参数ZTN是指定字号大小

uint8_t ShowStr2LCDWithBg(uint16_t x,uint16_t y,uint8_t ZTN,char*str,uint16_t clr,uint8_t space)
{//不擦除原有背景颜色,直接写文字
    uint8_t w,detx;
    uint16_t i,j;
    uint8_t data;
    uint8_t*lpData;
    
    while(*str!=0)
    {
        //字库芯片bug,调用前必须对缓存清零,不清零会有错误,见上一篇文章
        memset(&gFont16,0,sizeof(gFont16));
        gFont16.size=ZTN;
        gFont16.thick=(ZTN*3)/4;;
        if((*str&0x80)==0x80)
        {//这是汉字
            if((*(str+1)&0x80)!=0x80)
            {//半个汉字,不显示了
                str++;
            }else
            {
                gFont16.type=VEC_SONG_STY;
                gFont16.fontCode=*str;
                gFont16.fontCode<<=8;
                str++;
                gFont16.fontCode+=*str;
                
            }
            detx =ZTN;
            
        }else
        {//这是英文字符
            gFont16.type=VEC_FT_ASCII_STY;
            gFont16.fontCode=*str;
            detx =ZTN/2;
        }
        str++;
        //从字库芯片读取字模
        w=get_font_st(&gFont16);
        //获取字模的宽度w,一般会比要求的字体宽
        
        lpData = gFont16.zkBuffer;
        
        if((x+w)<lcddev.width)
        {
            for(i=0;i<ZTN;i++)
            {
                for(j=0;j<w;j++)
                {
                    if((j&0x07)==0)
                    {
                        data = *lpData;
                        lpData++;
                    }
                    if(j<ZTN)
                    {//超出字体宽度部分不显示
                        if((data&0x80)==0x80)
                        {
                            lcd_draw_point(x+j,y+i,clr);
                        }
                        data<<=1;
                    }
                }
                    
            }    
        }else
        {
            return 1;
        }
        x+=detx;
        x+=space;
        
    }
    return 0;
}


    如果需要擦除原有背景颜色,稍微修改一下上面的代码为if((data&0x80)==0x80)添加else部分就行了。
    下面是按钮部分的代码实现,用BUTTON_CreateEx()函数创建一个button,指定回调函数,具体代码如下:

         hItem=BUTTON_CreateEx(x,y,w,h,pageHand,WM_CF_SHOW,0,BUTTON_ID_USER);
        if(hItem!=NULL)
        {
            BUTTON_SetText(hItem,"测试");
            WM_SetHasTrans(hItem);
            WM_SetCallback(hItem,_cb_MyBtn);
        }


     这样就在客户区的窗口位置x,y的位置创建了一个宽度为w,高度为h,ID为BUTTON_ID_USER的一个按钮,如果直接运行,按钮上是没有文字的。下面需要我们通过回调函数_cb_MyBtn()来画出我们的按钮,我的代码是实现一个圆角矩形按钮,选中时和非选中状态有不同的按钮颜色,具体实现如下:
     

static void _cb_MyBtn(WM_MESSAGE * pMsg)
{//有多个按钮,所有按钮共用这一个回调函数
    WM_HWIN hSel;
    GUI_RECT Rect;
    uint16_t StrW;
    uint16_t orgX,orgY;
    uint16_t tColor;
    char btnText[20];
    switch(pMsg->MsgId)
    {
        case WM_PAINT:
            //设置圆角区域之外的地方为背景色
            GUI_SetBkColor(CLIENT_AREA_COLOR);
            GUI_Clear();
            //得到按钮的显示区域
            WM_GetClientRect(&Rect);
            //因为有很多按钮,用了一个全局数组存储了各个按钮的id,判断当前的按钮是否为选中状态
            hSel = WM_GetDialogItem(gMPage.pageHand,MPagewgList[gMPage.selIndex]);
            if(hSel==pMsg->hWin)
            {//如果时选中的按钮
                //设置按钮区域为选中的颜色
                GUI_SetBkColor(MEASURE_SELECTED_COLOR);
                GUI_SetColor(MEASURE_SELECTED_COLOR);
                //填充圆角矩形区域
                GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 10);
                //GUI_SetColor(GUI_WHITE);
                //设置选中以后的文字颜色,注意emwin使用的时4字节带alpha信息测存储方式。而我这里使用的时RGB565的形式,所以单独用一个变量来存储颜色
                tColor =WHITE;
            }
            else
            {//非选中的按钮
                GUI_SetBkColor(BUTTON_COLOR);
                GUI_SetColor(BUTTON_COLOR);
                GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 10);
                //GUI_SetColor(GUI_BLACK);
                tColor =BLACK;
            }
            //获取按钮的文字信息
            BUTTON_GetText(pMsg->hWin,btnText,20);
            //GUI_SetFont(BUTTON_GetFont(pMsg->hWin));
            //这里我要把文字现在在按钮靠上居中的位置,这里Rect中的坐标是控件内的相对坐标不是屏幕的绝对坐标
            Rect.y0+=5;
            //下面计算显示的字符串占多宽
            StrW = GUI__strlen(btnText);
            StrW*=18;//汉字宽度,根据实际情况自己修改
            StrW/=4; //每个汉字占2字节,先除以2,然后再取显示的一半宽度,再次除以2
            //获取当前按钮控件在屏幕上的绝对坐标
            orgX = WM_GetWindowOrgX(pMsg->hWin); 
            orgY = WM_GetWindowOrgY(pMsg->hWin);
            //直接到屏幕上显示汉字
            ShowStr2LCDWithBg(orgX+(Rect.x1-Rect.x0)/2-StrW,Rect.y0+orgY,18,btnText,tColor,0);
            //GUI_DispStringInRect(btnText, &Rect, GUI_TA_HCENTER | GUI_TA_TOP);
        break;
        default:
            BUTTON_Callback(pMsg);
        break;
    }
}


通过以上的代码,就可以实现从字库芯片读取字模,然后更新emwin按钮控件的文本信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值