emWin实现BMP位图皮肤之Spinbox篇
2016-06-25 18:30
483 查看
(1)emWin通过skinning方式实现控件位图皮肤:
1)emWin传统贴皮肤图片的方法,是调用APP函数XXXX_SetBitmap()方式实现,但非常非常麻烦。
2)要想把控件显示出来,emWin每种控件都有1个控件绘制函数,而把这个控件绘制函数改成我们自己编写的"自定义绘制函数",这样我们想把这个控件画成什么样都行,emWin已经不参与这个控件的绘制工作了;在这个自定义绘制函数里面我们什么都不干,只显示出这个控件的图片,这就是用skinning方式实现位图皮肤。
3)支持整幅图片贴图,不需要对整幅图片进行切片分解,非常便捷。
如上图所示,(x0,y0)为整幅图片的显示坐标,(x1,y1)和(x2,y2)是emWin为控件自动生成的剪切显示坐标,我们只需要调用GUI_DrawBitmap()函数在(x0,y0)显示整幅图片即可,emWin会自动剪切显示出该控件的位图皮肤,功能非常强大。
(2)Spinbox控件的自定义绘制函数:
SKIN_spinbox.c
skinning.h
(3)Skinning方式实现位图皮肤的实施步骤:
1)创建窗体时,将"页面图片结构体指针"保存于窗体中:
WINDOW_BMP *winBMP;
static WINDOW_BMP BMP_WIN_main;//为"WIN_main"页面定义1个"页面图片结构体"
BMP_WIN_main.normal = &bmPage2_N;//将不同状态的页面BMP位图赋值给"页面图片结构体"
BMP_WIN_main.mark = &bmPage2_M;
BMP_WIN_main.focus = &bmPage2_N;
BMP_WIN_main.disable = &bmPage2_N;
BMP_WIN_main.thumbN = &bmPage2_N;
BMP_WIN_main.thumbM = &bmPage2_N;
winBMP = &BMP_WIN_main;
hWin = CreateWindow2(WM_HBKWIN);//创建WINmain页面
WM_SetUserData(hWin, &winBMP, sizeof(winBMP));//将"页面图片结构体"指针写到用户数据区
2)在窗体初始化WM_INIT_DIALOG消息中,把SPINBOX控件的绘制函数改成自定义绘制函数:
hItem = WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_0);//获取句柄
SPINBOX_SetSkin(hItem, SKIN_spinbox2C);//将这个SPINBOX控件改成自定义绘制函数
(4)总结:
以整幅图片实现emWin位图皮肤应该是诺嵌光电业界首创的方法,可以大大减轻控件贴图的工作量,保守估计贴图工作效率至少提高10倍以上。如果把每个控件对应的图片先切片分解下来,然后再转换成C文件,最后再贴图到控件上面去,那样工作量将是非常恐怖的!
源码下载: \docs\demoEM\demo_emwin_CodeBlocks\skinPRJ_WINemWin530noOS_CodeBlocks_v127.rar
如何打开源码看博文:emWin
2天速成实例教程000_如何快速入门ucGUI/emWin
1)emWin传统贴皮肤图片的方法,是调用APP函数XXXX_SetBitmap()方式实现,但非常非常麻烦。
2)要想把控件显示出来,emWin每种控件都有1个控件绘制函数,而把这个控件绘制函数改成我们自己编写的"自定义绘制函数",这样我们想把这个控件画成什么样都行,emWin已经不参与这个控件的绘制工作了;在这个自定义绘制函数里面我们什么都不干,只显示出这个控件的图片,这就是用skinning方式实现位图皮肤。
3)支持整幅图片贴图,不需要对整幅图片进行切片分解,非常便捷。
如上图所示,(x0,y0)为整幅图片的显示坐标,(x1,y1)和(x2,y2)是emWin为控件自动生成的剪切显示坐标,我们只需要调用GUI_DrawBitmap()函数在(x0,y0)显示整幅图片即可,emWin会自动剪切显示出该控件的位图皮肤,功能非常强大。
(2)Spinbox控件的自定义绘制函数:
SKIN_spinbox.c
skinning.h
#include "DIALOG.h" #include "gui.h" #include "skinning.h" //获取父窗口句柄,即主页面句柄,保存着页面位图的指针 static WM_HWIN WM_GetParent1C(WM_HWIN hChild) {return hChild;} static WM_HWIN WM_GetParent2C(WM_HWIN hChild) {return WM_GetParent(hChild);} static WM_HWIN WM_GetParent3C(WM_HWIN hChild) {return WM_GetParent(WM_GetParent(hChild));} static WM_HWIN WM_GetParent4C(WM_HWIN hChild) {return WM_GetParent(WM_GetParent(WM_GetParent(hChild)));} static WM_HWIN WM_GetParent5C(WM_HWIN hChild) {return WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(hChild))));} static WM_HWIN WM_GetParent6C(WM_HWIN hChild) {return WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(hChild)))));} static WM_HWIN WM_GetParent7C(WM_HWIN hChild) {return WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(hChild))))));} static WM_HWIN WM_GetParent8C(WM_HWIN hChild) {return WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(hChild)))))));} static WM_HWIN (*WM_GET_PARENT[])(WM_HWIN) = {WM_GetParent1C,WM_GetParent2C,WM_GetParent3C,WM_GetParent4C,WM_GetParent5C,WM_GetParent6C,WM_GetParent7C,WM_GetParent8C}; static void SPINBOX_SetUserClip(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo) { GUI_RECT r; r.x0 = pDrawItemInfo->x0; r.y0 = pDrawItemInfo->y0; r.x1 = pDrawItemInfo->x1; r.y1 = pDrawItemInfo->y1; WM_SetUserClipRect(&r); } //Spinbox控件的自定义绘制函数 static int SKIN_spinbox(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_BUTTON_L: //case WIDGET_ITEM_DRAW_BUTTON_R: //case WIDGET_ITEM_DRAW_FRAME: break; default: return SPINBOX_DrawSkinFlex(pDrawItemInfo);//emWin默认控件绘制函数 case WIDGET_ITEM_DRAW_BUTTON_R: hWin = (WM_GET_PARENT[C-1])(pDrawItemInfo->hWin);//位于第几层修改这里(WM_GetParent数=层数-1) WM_GetUserData(hWin, &winBMP, sizeof(winBMP));//从用户数据区读出"页面图片结构体"指针 //获取此控件相对于主页面(比如:WINDOW)位置偏移坐标 x0 = WM_GetWindowOrgX(hWin) - WM_GetWindowOrgX(pDrawItemInfo->hWin); y0 = WM_GetWindowOrgY(hWin) -WM_GetWindowOrgY(pDrawItemInfo->hWin); SPINBOX_SetUserClip(pDrawItemInfo);//设置1个用户剪切区 if(pDrawItemInfo->ItemIndex == SPINBOX_SKINFLEX_PI_ENABLED) GUI_DrawBitmap(winBMP->normal, x0, y0);//从页面坐标显示图片,emWin会自己剪切出这个控件范围的图片 else if(pDrawItemInfo->ItemIndex == SPINBOX_SKINFLEX_PI_PRESSED) GUI_DrawBitmap(winBMP->mark, x0, y0); else if(pDrawItemInfo->ItemIndex == SPINBOX_SKINFLEX_PI_FOCUSSED) GUI_DrawBitmap(winBMP->focus, x0, y0); else if(pDrawItemInfo->ItemIndex == SPINBOX_SKINFLEX_PI_DISABLED) GUI_DrawBitmap(winBMP->disable, x0, y0); else SPINBOX_DrawSkinFlex(pDrawItemInfo); WM_SetUserClipRect(0); break; case WIDGET_ITEM_DRAW_BUTTON_L: hWin = (WM_GET_PARENT[C-1])(pDrawItemInfo->hWin);//位于第几层修改这里(WM_GetParent数=层数-1) WM_GetUserData(hWin, &winBMP, sizeof(winBMP)); x0 = WM_GetWindowOrgX(hWin) - WM_GetWindowOrgX(pDrawItemInfo->hWin); y0 = WM_GetWindowOrgY(hWin) -WM_GetWindowOrgY(pDrawItemInfo->hWin); SPINBOX_SetUserClip(pDrawItemInfo); if(pDrawItemInfo->ItemIndex == SPINBOX_SKINFLEX_PI_ENABLED) GUI_DrawBitmap(winBMP->normal, x0, y0); else if(pDrawItemInfo->ItemIndex == SPINBOX_SKINFLEX_PI_PRESSED) GUI_DrawBitmap(winBMP->mark, x0, y0); else if(pDrawItemInfo->ItemIndex == SPINBOX_SKINFLEX_PI_FOCUSSED) GUI_DrawBitmap(winBMP->focus, x0, y0); else if(pDrawItemInfo->ItemIndex == SPINBOX_SKINFLEX_PI_DISABLED) GUI_DrawBitmap(winBMP->disable, x0, y0); else SPINBOX_DrawSkinFlex(pDrawItemInfo); WM_SetUserClipRect(0); break; } return 0; } //Spinbox控件的自定义绘制函数,位于第2层(比如:WINDOW->SPINBOX) int SKIN_spinbox2C(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo){ return SKIN_spinbox(pDrawItemInfo, 2); } //Spinbox控件的自定义绘制函数,位于第3层(比如:FRAMEWIN->CLIENT->SPINBOX) int SKIN_spinbox3C(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo){ return SKIN_spinbox(pDrawItemInfo, 3); } //Spinbox控件的自定义绘制函数,位于第4层(比如:WINDOW->FRAMEWIN->CLIENT->SPINBOX) int SKIN_spinbox4C(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo){ return SKIN_spinbox(pDrawItemInfo, 4); } //Spinbox控件的自定义绘制函数,位于第5层(比如:WINDOW->SPINBOX->CLIENT->WINDOW->SPINBOX) int SKIN_spinbox5C(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo){ return SKIN_spinbox(pDrawItemInfo, 5); }
(3)Skinning方式实现位图皮肤的实施步骤:
1)创建窗体时,将"页面图片结构体指针"保存于窗体中:
WINDOW_BMP *winBMP;
static WINDOW_BMP BMP_WIN_main;//为"WIN_main"页面定义1个"页面图片结构体"
BMP_WIN_main.normal = &bmPage2_N;//将不同状态的页面BMP位图赋值给"页面图片结构体"
BMP_WIN_main.mark = &bmPage2_M;
BMP_WIN_main.focus = &bmPage2_N;
BMP_WIN_main.disable = &bmPage2_N;
BMP_WIN_main.thumbN = &bmPage2_N;
BMP_WIN_main.thumbM = &bmPage2_N;
winBMP = &BMP_WIN_main;
hWin = CreateWindow2(WM_HBKWIN);//创建WINmain页面
WM_SetUserData(hWin, &winBMP, sizeof(winBMP));//将"页面图片结构体"指针写到用户数据区
2)在窗体初始化WM_INIT_DIALOG消息中,把SPINBOX控件的绘制函数改成自定义绘制函数:
hItem = WM_GetDialogItem(pMsg->hWin, ID_SPINBOX_0);//获取句柄
SPINBOX_SetSkin(hItem, SKIN_spinbox2C);//将这个SPINBOX控件改成自定义绘制函数
(4)总结:
以整幅图片实现emWin位图皮肤应该是诺嵌光电业界首创的方法,可以大大减轻控件贴图的工作量,保守估计贴图工作效率至少提高10倍以上。如果把每个控件对应的图片先切片分解下来,然后再转换成C文件,最后再贴图到控件上面去,那样工作量将是非常恐怖的!
源码下载: \docs\demoEM\demo_emwin_CodeBlocks\skinPRJ_WINemWin530noOS_CodeBlocks_v127.rar
如何打开源码看博文:emWin
2天速成实例教程000_如何快速入门ucGUI/emWin
相关文章推荐
- hadoop HDFS
- python实现超市扫码仪计费
- 服务启动报错--未注入
- ionic 底部把内容挡住
- 反射机制----写的好
- 双色球、大乐透彩票注数算法
- GNU 工具与库
- 浅谈深度学习中潜藏的稀疏表达
- Hadoop YARN
- 安卓与51单片机的蓝牙通信(安卓端)
- NSThread-多线程浅析
- property animation(属性动画)、view animation(补间动画)、drawable animation(帧动画)比较
- 多线程
- Eclipse新建Servlet时候,不会自动生成mapping到web.xml,而是在代码中加入注解@WebServlet
- Linux:sed工具
- emWin实现BMP位图皮肤之Slider篇
- caffe finetuning实践
- 构建乘积数组
- 文本处理工具
- 直通车多创意喊您来添加