OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 11718|回复: 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)准备个表盘背景图片
image001.png

(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]

image003.png

emWin表盘控件效果演示.rar (251.58 KB, 下载次数: 1423)
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2016-3-16
在线时间
48 小时
发表于 2016-6-17 10:00:02 | 显示全部楼层
回复 支持 1 反对 0

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
11922
金钱
11922
注册时间
2015-11-5
在线时间
2086 小时
发表于 2016-6-14 18:16:42 | 显示全部楼层
很不错,谢谢分享!
拿来长岛冰茶换我半晚安睡
回复 支持 反对

使用道具 举报

3

主题

548

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1383
金钱
1383
注册时间
2015-2-3
在线时间
197 小时
发表于 2016-6-14 18:20:02 | 显示全部楼层
不错哎,值得学习
回复 支持 反对

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

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

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

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

谢谢支持!
回复 支持 反对

使用道具 举报

19

主题

490

帖子

4

精华

论坛元老

Rank: 8Rank: 8

积分
5174
金钱
5174
注册时间
2016-7-21
在线时间
1147 小时
发表于 2016-10-20 13:39:00 | 显示全部楼层
请问楼主这样的源码用社么软件打开呢? VS2013和VC++6.0都不会打开,求指教
@野生程序员
回复 支持 反对

使用道具 举报

2

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2016-11-7
在线时间
26 小时
发表于 2016-11-7 14:32:18 | 显示全部楼层
楼主威武,不错的
回复 支持 反对

使用道具 举报

13

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2018-9-16
在线时间
33 小时
发表于 2018-11-28 14:32:24 | 显示全部楼层
试了一下,模拟器上面效果可以,就是指针的像素不够,很粗。但是弄到STM32上面去,原来指针区域透明的,结果不透明了,那个进度条的框一直显示
回复 支持 反对

使用道具 举报

5

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2019-4-25
在线时间
13 小时
发表于 2021-10-15 17:39:18 | 显示全部楼层
楼主,咨询你一个问题,我看你这使用的图片都是一个跟窗口尺寸一样尺寸的图片,如果只用一个进度条图片(例如:200*20),该怎么修改你的代码呢?

我尝试了一下:
//Progbar控件的自定义绘制函数
static int SKIN_progbar(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;
        case WIDGET_ITEM_DRAW://_FRAME:
                hWin = (WM_GET_PARENT[C-1])(pDrawItemInfo->hWin);//位于第几层修改这里(WM_GetParent数=层数-1)
                //WM_GetUserData(hWin, &winBMP, sizeof(winBMP));//从用户数据区读出"页面图片结构体"指针
        PROGBAR_GetUserData(pDrawItemInfo->hWin, &winBMP, sizeof(winBMP));
                //获取此控件相对于主页面(比如:WINDOW)位置偏移坐标
                x0 = WM_GetWindowOrgX(hWin) + WM_GetWindowOrgX(pDrawItemInfo->hWin);
                y0 = WM_GetWindowOrgY(hWin) + WM_GetWindowOrgY(pDrawItemInfo->hWin);
                GUI_DrawBitmap(winBMP->normal, x0, y0);//从页面坐标显示图片,emWin会自己剪切出这个控件范围的图片
                break;
        case WIDGET_ITEM_DRAW_BACKGROUND:
                hWin = (WM_GET_PARENT[C-1])(pDrawItemInfo->hWin);//位于第几层修改这里(WM_GetParent数=层数-1)
                //WM_GetUserData(hWin, &winBMP, sizeof(winBMP));
        PROGBAR_GetUserData(pDrawItemInfo->hWin, &winBMP, sizeof(winBMP));
                x0 = WM_GetWindowOrgX(hWin) + WM_GetWindowOrgX(pDrawItemInfo->hWin);
                y0 = WM_GetWindowOrgY(hWin) + WM_GetWindowOrgY(pDrawItemInfo->hWin);
                PROGBAR_SetUserClip(pDrawItemInfo);//设置1个用户剪切区
                if(((PROGBAR_SKINFLEX_INFO *)pDrawItemInfo->p)->Index == PROGBAR_SKINFLEX_L)
                        GUI_DrawBitmap(winBMP->mark, x0, y0);
                else if(((PROGBAR_SKINFLEX_INFO *)pDrawItemInfo->p)->Index == PROGBAR_SKINFLEX_R)
                        GUI_DrawBitmap(winBMP->normal, x0, y0);
                else
            BUTTON_DrawSkinFlex(pDrawItemInfo);//PROGBAR_DrawSkinFlex(pDrawItemInfo);
                WM_SetUserClipRect(0);
                break;
    default: return PROGBAR_DrawSkinFlex(pDrawItemInfo);//emWin默认控件绘制函数
        }
        return 0;
}

但是没有显示图片,只是显示了进度条这个区域,不知道哪里出问题了,大神帮一下忙
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-22 09:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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