你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STEMWIN 自定义控件demo 学习使用官方没有的控件 带注释 精华  

[复制链接]
lovewyufeng 发布时间:2014-12-12 14:50
本帖最后由 lovewyufeng 于 2014-12-13 23:11 编辑

STemWin  无疑非常好用,系统提供的各种机制让我们攻城尸 敲GUI代码如虎添翼,事半功倍
可是仍然会遇到一些问题与困惑。  比如想要的功能系统没有提供怎么办,想用的控件没有提供怎么办。
STemWin 可以自定义控件吗?  可以更改  原控件的行为吗? 回答是肯定改变行为通过回调函数很容易办到,
并且网上应该有大量教程代码,这里就不介绍了。


举个例子,假如开发一台检测 重量的东西,屏幕上根据重量显示类似强度条一样的东西,
并且 轻的时候强度条是绿色的重则是红色, 由轻到重 从绿色到红色渐变。 在使用 STemWin 想要实现这个功能,
应该没有任何控件可以实现  唯一的实现方式是使用  底层绘图函数。,但是这里有个问题,使用底层绘图函数
则表示你抛弃了  WM管理器的各种功能,分层,重叠,渲染,无效化,回调!等等,这会使你开发其他地方很郁闷。

笔者正是希望有这样一个控件而着手试着自定义一个控件。并将经验传授给大家抛砖引玉,以后大家都有自己的自定义控件
,更自由的使用STemWin。同时为了马克下代码 以免忘记

下面先传两张效果图
QQ图片20141212143733.png QQ图片20141212143942.png


没有注释  大家看的顺序从

Create_demowidget 到 callback 就行了。

始终记得一点  WM管理器 通过 消息(callback) 来驱动 整个系统。


比如当你 的控件需要显示的时候  WM管理器会往你的 callback 发送一条 WM_PAINT 消息,此时你负责把控件应该有的样子显示出来就OK了

而这正好是我们想要。,其他消息则使用 WM_DefaultProc 去处理好了。



相信没有注释  你也能看懂的!



下面是代码  .h 和.c
  1. #include "WM.h"
  2. #include "DIALOG_Intern.h"      /* Req. for Create indirect data structure */
  3. #include "WIDGET.h"
  4. #include <stdint.h>
  5. #include "..\GUI\Include\GRAPH_Private.h"
  6. #define  DEMO_Widget_ID      0x34455854 /* DEMO_Widget */
  7. #define DEMO_Widget_INIT_ID(p) p->DebugId = DEMO_Widget_ID
  8. typedef struct {
  9.     WIDGET Widget;//第一项必须窗口 控件WM管理器使用
  10.     GUI_COLOR aBkColor[2];//根据需要添加  本控件 的两项颜色值   分别为上图的 背景黑色 和白色
  11.     GUI_COLOR RECT_Color;//上图外框的蓝色
  12.     WM_HMEM hpText;//未用到
  13.     WM_HMEM ahDrawObj[1];//未用到
  14.     int size_base;//中间最短一条的长度
  15.     GRAPH_PROPS Props;//盗用其他控件的  颜色, 绘外框的时候使用
  16.     uint16_t Sta_MAX;//控件的最大条数
  17.     uint16_t State;//当前显示的 信息

  18. #if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL
  19.     int DebugId;
  20. #endif  
  21. } DEMO_Widget_Obj;
  22. GUI_HMEM Create_demowidget(int x0, int y0, int xsize, int ysize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id);
  23. void Set_demowidget_Sta(GUI_HMEM hObj,int state);
  24. void Set_demowidget_Sta_MAX(GUI_HMEM hObj,int MAX);
  25. void Set_demowidget_Base(GUI_HMEM hObj,int base);


  26. 下面是 .c

  27. #include "demowidget.h"
  28. //这个函数负责显示  控件的外观  主要是调用一下  GUI 2D  绘图函数或者 有必要的话显示文本
  29. void _Paint(DEMO_Widget_Obj *pObj,GUI_HMEM hObj,GUI_RECT * pRectInvalid)
  30. {  
  31.         GUI_RECT RectClient;
  32.         int i,size_x;
  33.         GUI_RECT rClient, rInside,Rect={0,0,0,0},Rect1={0,0,0,0},Rect2={0,0,0,0};
  34.       GUI_GetClientRect(&RectClient);
  35.       rClient = RectClient;
  36.       Rect=rClient;
  37.       GUI_Clear();
  38.       GUI_SetBkColor(pObj->Props.aColor[1]);
  39.       GUI_SetColor(pObj->Props.aColor[2]);

  40.       GUI_DrawRectEx(&Rect);
  41.       GUI__ReduceRect(&Rect, &Rect, 1);
  42.       GUI_DrawRectEx(&Rect);
  43.       Rect=rClient;

  44.       GUI__ReduceRect(&rClient, &rClient, 3);
  45.       LCD_SetBkColor (pObj->aBkColor[0]);
  46.       LCD_SetColor   (pObj->RECT_Color);
  47.       size_x=(rClient.x1-pObj->size_base+1)/2/pObj->Sta_MAX;
  48.       Rect.x0=rClient.x0+pObj->Sta_MAX*size_x;
  49.       Rect.x1=rClient.x1-pObj->Sta_MAX*size_x;
  50.       Rect.y1=(rClient.y1/2)+rClient.y1/(pObj->Sta_MAX*2+1)/2-1;
  51.       Rect.y0=(rClient.y1/2)-rClient.y1/(pObj->Sta_MAX*2+1)/2;
  52.       GUI__ReduceRect(&Rect1,&Rect,0);
  53.       GUI__ReduceRect(&Rect2,&Rect,0);
  54.       GUI_DrawRectEx(&Rect);
  55.       for(i=0;i<pObj->Sta_MAX;i++)
  56.       {
  57.           Rect1.x0+=-size_x;
  58.           Rect1.x1+=+size_x;
  59.           Rect1.y0+=-rClient.y1/(pObj->Sta_MAX)/2;
  60.           Rect1.y1+=-rClient.y1/(pObj->Sta_MAX)/2;
  61.           Rect2.x0+=-size_x;
  62.           Rect2.x1+=+size_x;
  63.           Rect2.y0+=+rClient.y1/(pObj->Sta_MAX)/2;
  64.           Rect2.y1+=+rClient.y1/(pObj->Sta_MAX)/2;
  65.           GUI_DrawRectEx(&Rect1);
  66.           GUI_DrawRectEx(&Rect2);
  67.       }
  68.       LCD_SetColor(GUI_GREEN);
  69.       LCD_SetBkColor (pObj->aBkColor[0]);
  70.       GUI__ReduceRect(&Rect1,&Rect,1);
  71.       GUI__ReduceRect(&Rect2,&Rect,1);
  72.       GUI_FillRectEx(&Rect1);
  73.       for(i=0;i<pObj->State;i++)
  74.       {
  75.           LCD_SetColor((255-((255/pObj->Sta_MAX)*i)<<8)|((255/pObj->Sta_MAX*i)));
  76.           Rect1.x0+=-size_x;
  77.           Rect1.x1+=+size_x;
  78.           Rect1.y0+=-rClient.y1/(pObj->Sta_MAX)/2;
  79.           Rect1.y1+=-rClient.y1/(pObj->Sta_MAX)/2;
  80.           Rect2.x0+=-size_x;
  81.           Rect2.x1+=+size_x;
  82.           Rect2.y0+=+rClient.y1/(pObj->Sta_MAX)/2;
  83.           Rect2.y1+=+rClient.y1/(pObj->Sta_MAX)/2;
  84.           GUI_FillRectEx(&Rect1);
  85.           GUI_FillRectEx(&Rect2);
  86.       }
  87.       LCD_SetColor(pObj->aBkColor[1]);
  88.       for(;i<pObj->Sta_MAX;i++)
  89.       {
  90.           Rect1.x0+=-size_x;
  91.           Rect1.x1+=+size_x;
  92.           Rect1.y0+=-rClient.y1/(pObj->Sta_MAX)/2;
  93.           Rect1.y1+=-rClient.y1/(pObj->Sta_MAX)/2;
  94.           Rect2.x0+=-size_x;
  95.           Rect2.x1+=+size_x;
  96.           Rect2.y0+=+rClient.y1/(pObj->Sta_MAX)/2;
  97.           Rect2.y1+=+rClient.y1/(pObj->Sta_MAX)/2;
  98.           GUI_FillRectEx(&Rect1);
  99.           GUI_FillRectEx(&Rect2);
  100.       }
  101. }
  102. static void _Delete(DEMO_Widget_Obj* pObj) {
  103.     GUI_ALLOC_FreePtrArray(pObj->ahDrawObj, GUI_COUNTOF(pObj->ahDrawObj));
  104. }

  105. void DEMO_Widget_callback(WM_MESSAGE*pMsg)
  106. {
  107.     GUI_HMEM hObj=pMsg->hWin;
  108.     DEMO_Widget_Obj * pObj;
  109.     if (WIDGET_HandleActive(hObj, pMsg) == 0) {
  110.         return;
  111.     }
  112.      pObj= (DEMO_Widget_Obj *)GUI_ALLOC_h2p(hObj);

  113.      switch(pMsg->MsgId)
  114.      {
  115.          case WM_PAINT://响应重绘命令,显示自己 WM管理器在需要显示的时候自动发送。
  116.              _Paint(pObj, hObj,(GUI_RECT*)pMsg->Data.p);
  117.              return;
  118. case WM_DELETE:
  119. _Delete(pObj);
  120. break; /* No return here ... WM_DefaultProc needs to be called */
  121. //删除控件  这里不能return  因为需要WM_DefaultProc 迭代删除子控件
  122. }
  123. WM_DefaultProc(pMsg);
  124. }

  125. GUI_HMEM Create_demowidget(int x0, int y0, int xsize, int ysize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id)
  126. {
  127. GUI_HMEM hObj;
  128. GUI_USE_PARA(ExFlags);
  129. /* Create the window */
  130. WM_LOCK();
  131. hObj = WM_CreateWindowAsChild(x0, y0, xsize, ysize, hParent, WinFlags, DEMO_Widget_callback,
  132. sizeof(DEMO_Widget_Obj) - sizeof(WM_Obj));
  133. //创建一个Window  小工具的灵魂, 靠它小工具才受WM管理器管理  各种WM管理器的功能才得以使用
  134. //这里需要注意  设置了N个字节的 userdata ,userdata  和创建的Window  实际使用的内存是连续的
  135. //
  136. if(hObj)
  137. {
  138. DEMO_Widget_Obj * pObj = (DEMO_Widget_Obj *)GUI_ALLOC_h2p(hObj);
  139. //将Window   句柄转换为DEMO_Widget_Obj   类型的指针  这里的转换关系 需要  仔细思考!
  140. //上面提到userdata  和创建的Window  实际使用的内存是连续的  实际上 Window  实际使用的内存就是 WIDGET
  141. //这也是为什么一开始 说 DEMO_Widget_Obj 的第一项必须是 WIDGET  
  142. WIDGET__Init(&pObj->Widget, Id, WIDGET_STATE_FOCUSSABLE);
  143. DEMO_Widget_INIT_ID(pObj);//下面是设置一些默认属性
  144. pObj->aBkColor[0]=GUI_BLACK;
  145. pObj->aBkColor[1]=GUI_WHITE;
  146. pObj->RECT_Color=GUI_BLUE;
  147. pObj->Sta_MAX=40;
  148. pObj->State=0;
  149. pObj->size_base=5;
  150. pObj->State=0;
  151. pObj->Props = GRAPH__DefaultProps;
  152. }
  153. else
  154. {
  155. GUI_DEBUG_ERROROUT_IF(hObj==0, "DEMO_Widget_Create failed")
  156. }
  157. WM_UNLOCK();
  158. return hObj;
  159. }

  160. //下面的函数都由应用程序  运行过程中调用,
  161. //按照格式改属性然后  使用WM_InvalidateWindow 告诉 WM管理器  控件需要重绘就OK了
  162. void Set_demowidget_Sta(GUI_HMEM hObj,int state)
  163. {
  164. DEMO_Widget_Obj * pObj;
  165. if(hObj)
  166. {
  167. pObj= (DEMO_Widget_Obj *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */
  168. }
  169. else
  170. {
  171. return;
  172. }
  173. WM_LOCK();
  174. if(state<=pObj->Sta_MAX)
  175. pObj->State=state;
  176. WM_InvalidateWindow(hObj);
  177. WM_UNLOCK();
  178. }
  179. void Set_demowidget_Sta_MAX(GUI_HMEM hObj,int MAX)
  180. {
  181. DEMO_Widget_Obj * pObj;
  182. if(hObj)
  183. {
  184. pObj= (DEMO_Widget_Obj *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */
  185. }
  186. else
  187. {
  188. return;
  189. }
  190. WM_LOCK();
  191. pObj->Sta_MAX=MAX;
  192. WM_InvalidateWindow(hObj);
  193. WM_UNLOCK();
  194. }

  195. void Set_demowidget_Base(GUI_HMEM hObj,int base)
  196. {
  197. DEMO_Widget_Obj * pObj;
  198. if(hObj)
  199. {
  200. pObj= (DEMO_Widget_Obj *)GUI_ALLOC_h2p(hObj); /* Don't use use WIDGET_H2P because WIDGET_INIT_ID() has not be called at this point */
  201. }
  202. else
  203. {
  204. return;
  205. }
  206. WM_LOCK();
  207. pObj->size_base=base;
  208. WM_InvalidateWindow(hObj);
  209. WM_UNLOCK();
  210. }
复制代码


继续阅读:
树形 文件 目录  执行 初始化速度 和 内存优化


收藏 5 评论35 发布时间:2014-12-12 14:50

举报

35个回答
巅峰残狼 回答时间:2014-12-12 15:03:09
嗯,很不错,谢谢分享
迷途的羔羊-1901330 回答时间:2014-12-12 15:06:05
不错,学习了
Paphiopedilum 回答时间:2014-12-12 15:28:35
我只能默默的顶一下了
lovewyufeng 回答时间:2014-12-12 15:55:11
没有 人要求  上注释  
我就认为大家都看懂了哈
沐紫 回答时间:2014-12-12 16:30:17
lovewyufeng 发表于 2014-12-12 15:55
没有 人要求  上注释  
我就认为大家都看懂了哈

楼主还是上贴一下注释?可能有的朋友没看懂,但是没好意思说。
沐紫 回答时间:2014-12-12 16:30:17
lovewyufeng 发表于 2014-12-12 15:55
没有 人要求  上注释  
我就认为大家都看懂了哈

楼主还是上贴一下注释?可能有的朋友没看懂,但是没好意思说。

谢过
lovewyufeng 回答时间:2014-12-12 17:34:03
沐紫 发表于 2014-12-12 16:30
楼主还是上贴一下注释?可能有的朋友没看懂,但是没好意思说。

谢过

还不太会 编辑  帖子内容, 注释  改天奉上!

帖子不要沉
大器所成 回答时间:2014-12-12 21:02:17
既然没人好意思说上注释,那我说吧,求注释!!!!
lovewyufeng 回答时间:2014-12-12 21:07:07
大器所成 发表于 2014-12-12 21:02
既然没人好意思说上注释,那我说吧,求注释!!!!

明晚 上注释哈 ,今晚有事情
1234下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版