OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13688|回复: 9
打印 上一主题 下一主题

突发奇想!用emWin进度条控件做个表盘控件,效果不错

[复制链接]

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2016-6-3
在线时间
25 小时
跳转到指定楼层
楼主
发表于 2016-6-14 17:56:12 | 显示全部楼层 |只看大图 回帖奖励 |倒序浏览 |阅读模式
前段时间有客户问起emWin有没有表盘控件?一时语塞,才发现emWin还真没有表盘控件,SEGGER怎么了?
这几天突发奇想,为什么不用Progbar进度条控件改成表盘控件来用,因为它们性质和功能完全一样,只要把背景改一改,画个指针就完事,APP函数完全通用!自己还给它起了个好听的名字:ProgbarMeter控件。步骤如下:
(1)准备个表盘背景图片


(2)把绘制Progbar控件的函数改成自定义绘制函数,这样我们想把Progbar控件画成什么样都行,emWin已经不参与这个控件的绘制工作了
[mw_shl_code=c,true]hItem = WM_GetDialogItem(pMsg->hWin, ID_PROGBAR_0);//获取句柄
PROGBAR_SetSkin(hItem, SKIN_progbarmeter3C);//将这个PROGBAR控件改成自定义绘制函数[/mw_shl_code]

(3)编写自定义绘制函数
[mw_shl_code=c,true]//ProgbarMeter控件的自定义绘制函数
static int SKIN_progbarmeter(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo, unsigned char C)
{
    WM_HWIN hWin;
    int x0, y0;
    WINDOW_BMP *winBMP;

    switch (pDrawItemInfo->Cmd)
    {
    case WIDGET_ITEM_CREATE:
    //case WIDGET_ITEM_DRAW_BACKGROUND:
    case WIDGET_ITEM_DRAW_FRAME:
    //case WIDGET_ITEM_DRAW_TEXT:
        break;
    default: return PROGBAR_DrawSkinFlex(pDrawItemInfo);//emWin默认控件绘制函数

    case WIDGET_ITEM_DRAW_BACKGROUND:
        hWin = (WM_GET_PARENT[C-2])(pDrawItemInfo->hWin);//位于第几层修改这里(WM_GetParent数=层数-2)
        WM_GetUserData(hWin, &winBMP, sizeof(winBMP));//从用户数据区读出"页面图片结构体"指针
        //获取此控件相对于主页面(比如:背景WM_HBKWIN->WINDOW)位置偏移坐标
        x0 = WM_GetWindowOrgX(hWin) - WM_GetWindowOrgX(pDrawItemInfo->hWin);
        y0 = WM_GetWindowOrgY(hWin) -WM_GetWindowOrgY(pDrawItemInfo->hWin);
        PROGBARMETER_SetUserClip(pDrawItemInfo);//设置1个用户剪切区
        if(((PROGBAR_SKINFLEX_INFO *)pDrawItemInfo->p)->Index == PROGBAR_SKINFLEX_L)
            GUI_DrawBitmap(winBMP->normal, x0, y0);//从页面坐标显示图片,emWin会自己剪切出这个控件范围的图片
        else if(((PROGBAR_SKINFLEX_INFO *)pDrawItemInfo->p)->Index == PROGBAR_SKINFLEX_R)
            GUI_DrawBitmap(winBMP->normal, x0, y0);
        else BUTTON_DrawSkinFlex(pDrawItemInfo);
        WM_SetUserClipRect(0);
        break;
  case WIDGET_ITEM_DRAW_TEXT:
            PROGBARMETER_DispNeedle(pDrawItemInfo, 150, -150, 0, 100);
            return PROGBAR_DrawSkinFlex(pDrawItemInfo);
    }
    return 0;
}[/mw_shl_code]

(4)编写表盘指针绘制函数
[mw_shl_code=c,true]static const GUI_POINT _aNeedle[] = {{-3, 0}, {-2, -70}, {0, -80}, {2, -70}, {3, 0}};
//ProgbarMeter控件指针绘制函数
static void PROGBARMETER_DispNeedle(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo, short angleBEG, short angleEND, short valMIN, short valMAX)
{
    GUI_POINT aPoints[GUI_COUNTOF(_aNeedle)];
    GUI_RECT r;
    float Angle;

    short Value; char i, Text[8], *p = (char *)((PROGBAR_SKINFLEX_INFO *)pDrawItemInfo->p)->pText;
    for(i=0; i<7; i++){Text = *p++; Text[i+1] = 0; if(*p == '%') break;}
    Value = atoi(Text); if(Value<valMIN) Value = valMIN; if(Value>valMAX) Value = valMAX;
    Angle = angleBEG - (abs(angleEND-angleBEG)/(valMAX-valMIN))*Value;
    //PROGBAR_GetMinMax(pDrawItemInfo->hWin, &valMIN, &valMAX);//emwin v5.30
    //Angle = angleBEG - (abs(angleEND-angleBEG)/(valMAX-valMIN))*PROGBAR_GetValue(pDrawItemInfo->hWin);//emwin v5.30

    Angle *= 3.1415926f / 180;
    GUI_SetColor(0x35bf5f);
    GUI_RotatePolygon(aPoints, _aNeedle, GUI_COUNTOF(_aNeedle), Angle);
    WM_GetWindowRectEx(pDrawItemInfo->hWin, &r);
    GUI_FillPolygon(aPoints, GUI_COUNTOF(aPoints), (r.x1-r.x0)/2, (r.y1-r.y0)/2);
}[/mw_shl_code]



emWin表盘控件效果演示.rar (251.58 KB, 下载次数: 1423)
emWin表盘控件源码.rar (2.99 MB, 下载次数: 2072)

回复

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2016-6-3
在线时间
25 小时
2#
 楼主| 发表于 2016-6-14 19:45:21 | 显示全部楼层
自己也顶一下~~~~
回复 支持 反对

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2016-6-3
在线时间
25 小时
3#
 楼主| 发表于 2016-6-17 20:49:43 | 显示全部楼层

谢谢支持!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-5-23 22:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表