emWin实现BMP位图皮肤之Checkbox篇

来源:互联网 发布:中和支付网络pos机 编辑:程序博客网 时间:2024/05/21 09:33

(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)Checkbox控件的自定义绘制函数

SKIN_checkbox.c

skinning.h

#include "DIALOG.h"#include "gui.h"#include "skinning.h"//获取父窗口句柄,即主页面句柄,保存着页面位图的指针static WM_HWIN WM_GetParent2C(WM_HWIN hChild) {return hChild;}static WM_HWIN WM_GetParent3C(WM_HWIN hChild) {return WM_GetParent(hChild);}static WM_HWIN WM_GetParent4C(WM_HWIN hChild) {return WM_GetParent(WM_GetParent(hChild));}static WM_HWIN WM_GetParent5C(WM_HWIN hChild) {return WM_GetParent(WM_GetParent(WM_GetParent(hChild)));}static WM_HWIN WM_GetParent6C(WM_HWIN hChild) {return 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(hChild)))));}static WM_HWIN WM_GetParent8C(WM_HWIN hChild) {return WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(WM_GetParent(hChild))))));}static WM_HWIN WM_GetParent9C(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_GetParent2C,WM_GetParent3C,WM_GetParent4C,WM_GetParent5C,WM_GetParent6C,WM_GetParent7C,WM_GetParent8C,WM_GetParent9C};//Checkbox控件的自定义绘制函数static int SKIN_checkbox(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo, unsigned char C){  WM_HWIN hWin;  int x0, y0;  GUI_RECT r;  WINDOW_BMP *winBMP;  switch (pDrawItemInfo->Cmd)  {  case WIDGET_ITEM_CREATE:  //case WIDGET_ITEM_DRAW_BUTTON:  //case WIDGET_ITEM_DRAW_BITMAP:  //case WIDGET_ITEM_DRAW_FOCUS:  //case WIDGET_ITEM_DRAW_TEXT:    break;  default: return CHECKBOX_DrawSkinFlex(pDrawItemInfo);//emWin默认控件绘制函数  case WIDGET_ITEM_DRAW_BUTTON:    hWin = (WM_GET_PARENT[C-1])(pDrawItemInfo->hWin);//位于第几层修改这里(WM_GetParent数=层数-1)    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);    GUI_DrawBitmap(winBMP->normal, x0, y0);//从页面坐标显示图片,emWin会自己剪切出这个控件范围的图片    break;  case WIDGET_ITEM_DRAW_BITMAP://选择打勾    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);    GUI_DrawBitmap(winBMP->mark, x0, y0);    break;  case WIDGET_ITEM_DRAW_FOCUS:    CHECKBOX_DrawSkinFlex(pDrawItemInfo);    break;  }  return 0;}//Checkbox控件的自定义绘制函数,位于第2层(比如:背景WM_HBKWIN->WINDOW->CHECKBOX)int SKIN_checkbox2C(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo){  return SKIN_checkbox(pDrawItemInfo, 2);}//Checkbox控件的自定义绘制函数,位于第3层(比如:背景WM_HBKWIN->FRAMEWIN->CLIENT->CHECKBOX)int SKIN_checkbox3C(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo){  return SKIN_checkbox(pDrawItemInfo, 3);}//Checkbox控件的自定义绘制函数,位于第4层(比如:背景WM_HBKWIN->WINDOW->FRAMEWIN->CLIENT->CHECKBOX)int SKIN_checkbox4C(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo){  return SKIN_checkbox(pDrawItemInfo, 4);}//Checkbox控件的自定义绘制函数,位于第5层(比如:背景WM_HBKWIN->WINDOW->MULTIPAGE->CLIENT->WINDOW->CHECKBOX)int SKIN_checkbox5C(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo){  return SKIN_checkbox(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消息中,CHECKBOX控件的绘制函数改成自定义绘制函数:
  hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0);//获取句柄
  CHECKBOX_SetSkin(hItem, SKIN_checkbox2C);//将这个CHECKBOX控件改成自定义绘制函数


(4)总结:

以整幅图片实现emWin位图皮肤应该是诺嵌光电业界首创的方法,可以大大减轻控件贴图的工作量,保守估计贴图工作效率至少提高10倍以上。如果把每个控件对应的图片先切片分解下来,然后再转换成C文件,最后再贴图到控件上面去,那样工作量将是非常恐怖的!




0 0
原创粉丝点击