硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1890|回复: 4
收起左侧

[emWin教程入门篇] 【emWin实战教程V2.0】第37章      窗口管理器实例

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
发表于 2017-2-17 16:48:46 | 显示全部楼层 |阅读模式
完整65章+12章附件教程下载地址:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=19834




                  第37章      窗口管理器实例(含自定义消息)


    为了帮助大家更好的理解窗口管理器的回调函数和消息机制,本章教程专门做了两个相关的例子,帮助大家更好的理解。
37.1  初学者重要提示
37.2 用户自定义消息类型实例
37.3 桌面窗口回调函数实例
37.4 总结
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-2-17 16:50:24 | 显示全部楼层
37.1  初学者重要提示

1、通过实例来学习emWin是最佳的学习捷径。
2、本章节举的两个例子都用到了对话框,对于初学者来说,仅需知道这是对话框即可,重点是看对话框回调函数的实现,后面章节会专门讲解对话框。
3、窗口管理器这块的API函数应该是emWin手册所有章节中函数最多的,以后需要用到什么功能了,查询就行,或者看官方的实例,哪个函数不理解了也可以查手册。下图是中文版手册里面API函数位置:
37.1.png


下图是英文版手册里面API函数的位置:
37.2.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-2-17 16:53:03 | 显示全部楼层
37.2 用户自定义消息类型实例


    第36章为大家讲解的都是STemWin支持的消息类型,这里我们通过一个实例来实现自定义消息,这个功能在大家以后的实际项目中都有机会用到,比较有实战价值。
    下面我们直接通过如下的代码来讲解实现方法和用到的函数(可以直接将代码复制到模拟器或者开发板上面运行)。
  1. #include "DIALOG.h"
  2. /*
  3. *********************************************************************************************************
  4. *                                         变量
  5. *********************************************************************************************************
  6. */
  7. static GUI_COLOR _acColor[3] = {GUI_BLUE,GUI_RED,GUI_YELLOW};   //--------------(1)
  8. static unsigned char ucBackColor;
  9. /*
  10. *********************************************************************************************************
  11. *                                         宏定义
  12. *********************************************************************************************************
  13. */
  14. #define ID_FRAMEWIN_0  (GUI_ID_USER + 0x00)
  15. #define ID_BUTTON_0    (GUI_ID_USER + 0x01)
  16. #define ID_SCROLLBAR_0 (GUI_ID_USER + 0x02)
  17. #define ID_SLIDER_0    (GUI_ID_USER + 0x03)
  18. #define WM_UPDATE      (WM_USER + 0x00) /* 自定义消息 */  // --------------(2)
  19. /*
  20. *********************************************************************************************************
  21. *                           GUI_WIDGET_CREATE_INFO类型数组
  22. *********************************************************************************************************
  23. */
  24. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  25.   { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 480, 272, 0, 0x64, 0 },
  26.   { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 130, 28, 147, 35, 0, 0x0, 0 },
  27.   { SCROLLBAR_CreateIndirect, "Scrollbar", ID_SCROLLBAR_0, 129, 74, 147, 28, 0, 0x0, 0 },
  28.   { SLIDER_CreateIndirect, "Slider", ID_SLIDER_0, 133, 118, 137, 25, 0, 0x0, 0 },
  29. };
  30. /*
  31. *********************************************************************************************************
  32. *    函 数 名: _cbDialog
  33. *    功能说明: 对话框回调函数        
  34. *    形    参: pMsg  回调参数
  35. *    返 回 值: 无
  36. *********************************************************************************************************
  37. */
  38. static void _cbDialog(WM_MESSAGE * pMsg)
  39. {
  40.      WM_HWIN hItem;
  41.      int     NCode;
  42.      int     Id;
  43.      switch (pMsg->MsgId)
  44.      {
  45.          case WM_INIT_DIALOG:
  46.             
  47.               //
  48.               // 初始化 'Framewin'
  49.               //
  50.               hItem = pMsg->hWin;
  51.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  52.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  53.               FRAMEWIN_SetText(hItem, "armfly");
  54.         
  55.               //
  56.               // 初始化 'Button'
  57.               //
  58.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  59.               BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
  60.               BUTTON_SetText(hItem, "armfly");
  61.               /* 默认颜色取*/
  62.               ucBackColor = 0;
  63.               break;
  64.          case WM_PAINT:      
  65.             GUI_SetBkColor(_acColor[ucBackColor]);
  66.             GUI_Clear();
  67.             break;
  68.          case WM_UPDATE:      //--------------(3)
  69.               ucBackColor++;
  70.               if (ucBackColor == 3)
  71.               {
  72.                    ucBackColor = 0;
  73.               }
  74.               WM_InvalidateWindow(pMsg->hWin);
  75.               break;
  76.    
  77.         case WM_KEY:
  78.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
  79.             {
  80.                 case GUI_KEY_ESCAPE:
  81.                     GUI_EndDialog(pMsg->hWin, 1);
  82.                     break;
  83.                 case GUI_KEY_ENTER:
  84.                     GUI_EndDialog(pMsg->hWin, 0);
  85.                     break;
  86.             }
  87.               break;
  88.          case WM_NOTIFY_PARENT:
  89.               Id    = WM_GetId(pMsg->hWinSrc);
  90.               NCode = pMsg->Data.v;
  91.               switch(Id)
  92.               {
  93.                    case ID_BUTTON_0:
  94.                        switch(NCode)
  95.                        {
  96.                             case WM_NOTIFICATION_CLICKED:
  97.                                  break;
  98.                            
  99.                             case WM_NOTIFICATION_RELEASED:
  100.                                  break;
  101.                        }
  102.                        break;
  103.                   
  104.                    case ID_SCROLLBAR_0:
  105.                        switch(NCode)
  106.                        {
  107.                             case WM_NOTIFICATION_CLICKED:
  108.                                  break;
  109.                            
  110.                             case WM_NOTIFICATION_RELEASED:
  111.                                  break;
  112.                            
  113.                             case WM_NOTIFICATION_VALUE_CHANGED:
  114.                                  break;
  115.                        }
  116.                        break;
  117.                   
  118.                    case ID_SLIDER_0:
  119.                        switch(NCode)
  120.                        {
  121.                             case WM_NOTIFICATION_CLICKED:
  122.                                  break;
  123.                            
  124.                             case WM_NOTIFICATION_RELEASED:
  125.                                  break;
  126.                            
  127.                             case WM_NOTIFICATION_VALUE_CHANGED:
  128.                                  break;
  129.                        }
  130.                        break;
  131.               }
  132.               break;
  133.             
  134.          default:
  135.               WM_DefaultProc(pMsg);
  136.               break;
  137.      }
  138. }
  139. /*
  140. *********************************************************************************************************
  141. *    函 数 名: CreateFramewin
  142. *    功能说明: 创建对话框      
  143. *    形    参: 无
  144. *    返 回 值: 返回对话框句柄
  145. *********************************************************************************************************
  146. */
  147. WM_HWIN CreateFramewin(void)
  148. {
  149.      WM_HWIN hWin;
  150.      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  151.      return hWin;
  152. }
  153. /*
  154. *********************************************************************************************************
  155. *    函 数 名: MainTask
  156. *    功能说明: GUI主函数
  157. *    形    参: 无
  158. *    返 回 值: 无
  159. *********************************************************************************************************
  160. */
  161. void MainTask(void)
  162. {
  163.      WM_HWIN hDlg;
  164.      /* 初始emWin */
  165.      GUI_Init();
  166.      /* 创建对话框 */
  167.     hDlg = CreateFramewin();
  168.      while(1)
  169.      {
  170.          /* 给对话框hDlg发送自定义消息WM_UPDATE */
  171.          WM_SendMessageNoPara(WM_GetClientWindow(hDlg), WM_UPDATE);   // --------------(4)
  172.          GUI_Delay(500);
  173.      }
  174. }
复制代码
实现自定义消息的关键是函数WM_SendMessageNoPara的使用,学会了这个函数基本就学会了自定义消息的实现:
1.     定义一个数组,里面有三种颜色,再定义一个变量,用于三种颜色的切换。
2.     定义一个用户消息WM_UPDATE,一定要以WM_USER作为起始值,防止跟系统其他的数值冲突。如果还要实现其它自定义消息,在这个数值的基础上面定义即可。
3.     在回调函数中加入自定义消息WM_UPDATE,在这个消息里面切换对话框的背景色变量,然后调用函数WM_InvalidateWindow将对话框进行无效化,从而会触发窗口管理器去执行WM_PAINT消息,这样就实现了对话框背景色的变化。
4.     通过函数WM_SendMessageNoPara()每隔500ms给对话框发送WM_UPDATE消息。函数原型如下:
      void WM_SendMessageNoPara(WM_HWIN hWin, int MsgId)
    此函数用于将不带参数的消息发送到指定窗口,使用也比较简单,第一个参数hWin是要接受消息的窗口句柄,第二个参数MsgId是消息类型。其中第一个参数要特别注意,如果是给对话框发消息,且对话框的主体是框架窗口FrameWin或者直接给框架窗口FrameWin发消息,第一个参数必须要使用函数WM_GetClientWindow获得框架窗口的客户区,这一点非常重要,经常有初学者在这个地方犯错误。如果对话框的主体是Windows或者直接给Windows窗口发消息,无需使用函数WM_GetClientWindow,直接填句柄就可以了。
    此时初学者还会有个疑问,能否使用函数WM_SendMessageNoPara可以发送类似WM_PAINT的系统消息?答案是可以的,不过跟发自定义消息稍有区别:
  1. /* 设置要用于绘制操作的活动窗口 */
  2. WM_SelectWindow(WM_GetClientWindow(hDlg));
  3. /* 给对话框hDlg发送系统消息WM_PAINT */
  4. WM_SendMessageNoPara(WM_GetClientWindow(hDlg), WM_PAINT);
  5. /* 切换回默认的桌面窗口 */
  6. WM_SelectWindow(WM_HBKWIN);
复制代码
   另外还有一个带参数的消息发送函数WM_SendMessage,在第38章会有一个例子调用这个函数。最后,本程序的显示效果如下(分辨率480*272),每500ms更新一次对话框的客户区背景色:
37.3.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-2-17 16:55:24 | 显示全部楼层
37.3 桌面窗口回调函数实例


        这个例子为大家讲解如何给桌面窗口配置回调函数。实现源码如下(可以直接将代码复制到模拟器或者开发板上面运行)。
  1. #include "DIALOG.h"
  2. /*
  3. *********************************************************************************************************
  4. *                                         宏定义
  5. *********************************************************************************************************
  6. */
  7. #define ID_FRAMEWIN_0  (GUI_ID_USER + 0x00)
  8. #define ID_BUTTON_0    (GUI_ID_USER + 0x01)
  9. #define ID_SCROLLBAR_0 (GUI_ID_USER + 0x02)
  10. #define ID_SLIDER_0    (GUI_ID_USER + 0x03)
  11. /*
  12. *********************************************************************************************************
  13. *                           GUI_WIDGET_CREATE_INFO类型数组
  14. *********************************************************************************************************
  15. */
  16. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {   //--------------(1)
  17.   { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 480, 272, FRAMEWIN_CF_MOVEABLE, 0x64, 0 },
  18.   { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 130, 28, 147, 35, 0, 0x0, 0 },
  19.   { SCROLLBAR_CreateIndirect, "Scrollbar", ID_SCROLLBAR_0, 129, 74, 147, 28, 0, 0x0, 0 },
  20.   { SLIDER_CreateIndirect, "Slider", ID_SLIDER_0, 133, 118, 137, 25, 0, 0x0, 0 },
  21. };
  22. /*
  23. *********************************************************************************************************
  24. *    函 数 名: _cbDialog
  25. *    功能说明: 对话框回调函数        
  26. *    形    参: pMsg  回调参数
  27. *    返 回 值: 无
  28. *********************************************************************************************************
  29. */
  30. static void _cbDialog(WM_MESSAGE * pMsg)
  31. {
  32.      WM_HWIN hItem;
  33.      int     NCode;
  34.      int     Id;
  35.      switch (pMsg->MsgId)
  36.      {
  37.          case WM_INIT_DIALOG:
  38.             
  39.               //
  40.               // 初始化 'Framewin'
  41.               //
  42.               hItem = pMsg->hWin;
  43.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  44.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  45.               FRAMEWIN_SetText(hItem, "armfly");
  46.         
  47.               //
  48.               // 初始化 'Button'
  49.               //
  50.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
  51.               BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
  52.               BUTTON_SetText(hItem, "armfly");
  53.               break;
  54.          case WM_PAINT:
  55.               GUI_SetBkColor(GUI_RED);
  56.               GUI_Clear();
  57.               break;
  58.         case WM_KEY:
  59.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
  60.             {
  61.                 case GUI_KEY_ESCAPE:
  62.                     GUI_EndDialog(pMsg->hWin, 1);
  63.                     break;
  64.                 case GUI_KEY_ENTER:
  65.                     GUI_EndDialog(pMsg->hWin, 0);
  66.                     break;
  67.             }
  68.               break;
  69.          case WM_NOTIFY_PARENT:
  70.               Id    = WM_GetId(pMsg->hWinSrc);
  71.               NCode = pMsg->Data.v;
  72.               switch(Id)
  73.               {
  74.                    case ID_BUTTON_0:
  75.                        switch(NCode)
  76.                        {
  77.                             case WM_NOTIFICATION_CLICKED:
  78.                                  break;
  79.                            
  80.                             case WM_NOTIFICATION_RELEASED:
  81.                                  break;
  82.                        }
  83.                        break;
  84.                   
  85.                    case ID_SCROLLBAR_0:
  86.                        switch(NCode)
  87.                        {
  88.                             case WM_NOTIFICATION_CLICKED:
  89.                                  break;
  90.                            
  91.                             case WM_NOTIFICATION_RELEASED:
  92.                                  break;
  93.                            
  94.                             case WM_NOTIFICATION_VALUE_CHANGED:
  95.                                  break;
  96.                        }
  97.                        break;
  98.                   
  99.                    case ID_SLIDER_0:
  100.                        switch(NCode)
  101.                        {
  102.                             case WM_NOTIFICATION_CLICKED:
  103.                                  break;
  104.                            
  105.                             case WM_NOTIFICATION_RELEASED:
  106.                                  break;
  107.                            
  108.                             case WM_NOTIFICATION_VALUE_CHANGED:
  109.                                  break;
  110.                        }
  111.                        break;
  112.               }
  113.               break;
  114.             
  115.          default:
  116.               WM_DefaultProc(pMsg);
  117.               break;
  118.      }
  119. }
  120. /*
  121. *********************************************************************************************************
  122. *    函 数 名: CreateFramewin
  123. *    功能说明: 创建对话框      
  124. *    形    参: 无
  125. *    返 回 值: 返回对话框句柄
  126. *********************************************************************************************************
  127. */
  128. WM_HWIN CreateFramewin(void)
  129. {
  130.      WM_HWIN hWin;
  131.      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  132.      return hWin;
  133. }
  134. /*
  135. *********************************************************************************************************
  136. *    函 数 名: _cbBkWindow
  137. *    功能说明: 桌面窗口回调函数      
  138. *    形    参: 无
  139. *    返 回 值: 返回对话框句柄
  140. *********************************************************************************************************
  141. */
  142. static void _cbBkWindow(WM_MESSAGE * pMsg) //--------------(2)
  143. {
  144.     WM_HWIN hWin = pMsg->hWin;
  145.     switch (pMsg->MsgId)
  146.     {
  147.          case WM_PAINT:
  148.               GUI_SetBkColor(GUI_BLUE);
  149.               GUI_Clear();
  150.               break;
  151.         default:
  152.             WM_DefaultProc(pMsg);
  153.     }
  154. }
  155. /*
  156. *********************************************************************************************************
  157. *    函 数 名: MainTask
  158. *    功能说明: GUI主函数
  159. *    形    参: 无
  160. *    返 回 值: 无
  161. *********************************************************************************************************
  162. */
  163. void MainTask(void)
  164. {
  165.      WM_HWIN hDlg;
  166.      /*
  167.         使能窗口使用内存设备,这样可以有效避免闪烁, 放在GUI_Init前面就包括桌面
  168.         窗口,如果放在后面就不包括桌面窗口。
  169.      */
  170.      WM_SetCreateFlags(WM_CF_MEMDEV);  //--------------(3)
  171.      /* 初始emWin */
  172.      GUI_Init();
  173.      /* 设置桌面窗口的回调函数 */
  174.      WM_SetCallback(WM_HBKWIN, _cbBkWindow); //--------------(4)
  175.      /* 创建对话框 */
  176.     hDlg = CreateFramewin();
  177.      while(1)
  178.      {
  179.          GUI_Delay(10);
  180.      }
  181. }
复制代码
1.     对话框资源列表第一个选项FrameWin设置了一个参数FRAMEWIN_CF_MOVEABLE,这样对话框就是可以移动的,方便查看桌面窗口回调函数的刷新。关于对话框的使用会在后面章节为大家详细讲解,这里有个感性的认识即可。
2.     桌面窗口的回调函数(桌面窗口是emWin最底层的窗口,是初始化后自动创建的),这里仅实现了一个WM_PAINT消息。
3.     使用函数WM_SetCreateFlags(WM_CF_MEMDEV)分两种情况,如果此函数是放在函数GUI_Init前面,那么所有的窗口将自动使用内存设备,使用内存设备的好处是有效避免闪烁感。如果此函数是放在函数GUI_Init后面调用,那么桌面窗口是没有使用内存设备的,这点要特别注意。
4.     通过函数WM_SetCallback来设置桌面窗口的回调函数,实现的功能比较简单,仅设置重绘消息。这里的功能基本等同于调用函数WM_SetDesktopColor(GUI_BLUE)。实现的效果是一样的,都是可以自动重绘桌面窗口。
        另外,测试中还发现一点,如果用户将函数WM_SetCreateFlags(WM_CF_MEMDEV)放在GUI_Init前面,桌面窗口也是可以自动重绘的,这样就可以不需要使用WM_SetCallback来设置桌面窗口回调函数或者使用函数WM_SetDesktopColor(GUI_BLUE),不过重绘的颜色固定为灰色。
----------------------------
        这个程序的显示效果如下(分辨率480*272):
37.4.png

用户可以拖动这个窗口,鼠标点击到标题栏就可以拖动了,跟操作电脑端软件是一样的:
37.5.png

如果不设置桌面窗口回调函数,且函数WM_SetCreateFlags(WM_CF_MEMDEV)没有放在GUI_Init前面调用,那么拖动窗口的话,显示效果就是这个样子的:
37.6.png

显示成这个样子是因为桌面窗口没有执行重绘,导致拖动对话框的时候一直有上次显示的残影。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-2-17 16:56:00 | 显示全部楼层
37.4   总结


    本章节就跟大家讲这么多,希望通过本章教程让大家对窗口管理器有更好的认识,不过还需要大家在模拟器或者开发板上面多做这方面的练习,将其它的窗口管理器API函数也调用测试下。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-11-1 07:03 , Processed in 0.237373 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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