硬汉嵌入式论坛

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

[emWin教程入门篇] 【emWin实战教程V2.0】第55章     MULTIPAGE-多页控件

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

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




第55章     MULTIPAGE-多页控件



         本章节为大家讲解STemWin支持的多页控件,通过使用多页控件,可以很方便的在窗口上面扩展出多个页面,这样就可以集成更多的功能到这个窗口上面,使用此控件的最大好处也就在这里了。
55.1 初学者重要提示
55.2 多页控件基础知识
55.3 使用GUIBuilder创建多页控件并用模拟器显示出来
55.4 官方WIDGET_Multipage.c实例
55.5 实验例程说明(RTOS)
55.6 实验例程说明(裸机)
55.7 总结
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-13 16:38:52 | 显示全部楼层
55.1  初学者重要提示


u  初学者爱问的问题简单汇总:
        问题1:多页控件选项卡的位置是否可以任意设置
        答:可以的,函数MULTIPAGE_SetAlign配合MULTIPAGE_SetRotation就可以实现。
2、本教程配套的emWin版本是5.32,从emWin5.28版本开始,皮肤色是自动使能的,所以部分多页控件的API函数是失效的,主要是多页控件颜色设置函数,此问题也经常被初学者问。
3、实际项目中,建议用户将对话框附加到多页控件的页面窗口上,这样页面窗口的管理将非常方便,而且这个对话框也可以使用GUIBuilder进行创建,本章节配套的例子都是采用的这种方法。
4、多页控件的所有API函数在emWin手册中都有讲解,下图是中文版手册里面API函数位置:
55.1.png


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

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-13 16:42:11 | 显示全部楼层
55.2 多页控件基础知识

       先通过下面的图表看看多页控件是什么样子的:
55.3.png
相信大家在电脑端经常见到这种类似的控件,通过使用多页控件,可以很方便的在窗口上面扩展出多个页面,这样就可以集成更多的功能到这个窗口上面,使用此控件的最大好处也就在这里了。另外,如果窗口中无法显示所有选项卡,就如上表第二个图中创建了6个页面,选项卡无法全部显示出来,右下角就会显示出一个滚动条。

        下面接着说说多页控件的组成结构,一个多页控件是由1个MultiPage窗口,1个客户端窗口和n个用户所创建的页面窗口组成,n的大小由用户决定,用户创建了几个,n就是几:
                     (1)1个MULTIPAGE窗口
                     (2)1个客户端窗口
                     (3)N个页面窗口
页面窗口是被添加到客户端窗口上的,具体的层次关系如下:
55.4.png


用户的应用程序是创建到各个页面窗口上的。
---------------------------------------------------------------------------------------------------------
不开启皮肤色时,多页控件的显示效果就是上面图表中所示的,开启皮肤后显示效果如下:
55.5.png


55.2.1    多页控件支持的通知代码

        多页控件支持的通知代码主要是用来处理多页控件消息用的,多页控件主要支持四种消息事件,点击消息,释放消息,移开消息(点击了多页控件,且从多页控件所在的区域移开了但没有释放)和多页控件选项卡的内容被更改消息。比如用户通过触摸屏点击了多页控件,窗口管理器会给多页控件父窗口回调函数发送消息WM_NOTIFY_PARENT来通知父窗口,进而再区分是四种消息中的哪一种,用户就可以在相应的消息代码里面加入要实现的功能。
        以下事件是作为WM_NOTIFY_PARENT消息的一部分由多页控件发送给其父窗口,用来区分不同的多页控件消息。
55.6.png

注意,实际测试发现消息WM_NOTIFICATION_VALUE_CHANGED很奇葩,点击选项卡或者切换选项卡,这个消息都会被触发,感觉这个消息没有什么用,有些多余了。

55.2.2   多页控件支持的键盘反应(输入聚焦)


        多页控件支持输入聚焦,也支持外置键盘或者类似外置键盘的输入设备给多页控件发消息。当前仅支持以下两种按键消息:
        (输入聚焦是一个重要的知识点,使用外置键盘或者类似外置键盘的输入设备要用到)
55.7.png

特别注意一点,对于多页控件来说,要先聚焦到这个控件上了,给多页控件发送按键消息才会有反应。

55.2.3   多页控件API函数


        多行文本控件的API函数比较多,但调用都不难。我们这里把以下两个比较相似的函数特别解释下:
MULTIPAGE_AddPage
        此函数用于将窗口添加到多页控件的页面窗口。
MULTIPAGE_AddEmptyPage
        此函数也是用于将窗口添加到多页控件的页面窗口,跟函数MULTIPAGE_AddPage的区别是此函数可以在无窗口需要添加时,可以将窗口句柄参数设置为0。
----------------------------------------------------------------------------------------------------------
        本章节教程配套例子是将多页控件配合对话框一起使用的,实际项目中也推荐大家这么做,可以很方便的进行界面管理。在对话框上面使用多页控件是通过函数MULTIPAGE_CreateIndirect()来实现的。根据第41章41.7.1小节讲解的<WIDGET>_CreateIndirect()函数,GUI_WIDGET_CREATE_INFO结构体类型定义如下:
  1. typedef struct {
  2. GUI_WIDGET_CREATE_FUNC * pfCreateIndirect;    // 间接创建函数
  3. const char * pName;                           // 控件名(不是所有控件都需要)
  4. I16 Id;                                       // 控件ID
  5. I16 x0, y0, xSize, ySize;                     // 控件的坐标位置和大小
  6. I16 Flags;                                    // 控件用到的标志,没有就写0
  7. I32 Para;                                     // 控件用到的参数,没有就写0
  8. U32 NumExtraBytes;                            // 函数 <WIDGET>_SetUserData & <WIDGET>_GetUserData用到的
  9. // 额外字节。
  10. } GUI_WIDGET_CREATE_INFO;
复制代码
        上面结构体成员里面的标记Flags和参数Para是可选的,函数MULTIPAGE_CreateIndirect()没有用到参数Para,但用到了标记Flags,与函数MULTIPAGE_CreateEx的形参ExFlags是等效的,具体形参ExFlags支持哪些标记参看emWin官方手册中的说明即可。
        这里举一个对话框资源列表里面创建多页控件的例子,帮助大家更好的理解:
  1. /*
  2. *********************************************************************************************************
  3. *                           宏定义
  4. *********************************************************************************************************
  5. */
  6. #define ID_FRAMEWIN_0  (GUI_ID_USER + 0x00)
  7. #define ID_MULTIPAGE_0 (GUI_ID_USER + 0x01)
  8. /*
  9. *********************************************************************************************************
  10. *                           GUI_WIDGET_CREATE_INFO类型数组
  11. *********************************************************************************************************
  12. */
  13. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
  14. {
  15. { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x0, 0 },
  16.   { MULTIPAGE_CreateIndirect, "Multipage", ID_MULTIPAGE_0, 23, 25, 400, 240, 0, 0x0, 0 },
  17. };
复制代码
上面的对话框资源列表里面依次创建了框架窗口控件,多页控件。多页控件的参数和GUI_WIDGET_CREATE_INFO结构成员的对应关系如下:

pfCreateIndirect = MULTIPAGE_CreateIndirect;
pName = "Multipage";
Id = ID_MULTIPAGE_0;
x0 = 23;
y0 = 25;
xSize = 400;
ySzie = 240;
Flags = 0;
Para = 0x0;
NumExtraBytes = 0;
对于这个对应关系要注意以下两点:
1、这里的x0y0坐标位置是相对于对话框资源列表中框架窗口的客户端窗口的位置坐标。
2、Id号,这里的Id号是用户自定义的,emWin在GUI.h文件中也定义了部分多行文本控件的Id号,用户是可以直接使用的:
  1. #define GUI_ID_MULTIPAGE0 0x230
  2. #define GUI_ID_MULTIPAGE1 0x231
  3. #define GUI_ID_MULTIPAGE2 0x232
  4. #define GUI_ID_MULTIPAGE3 0x233
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-13 16:46:41 | 显示全部楼层
55.3 使用GUIBuilder创建多页控件并用模拟器显示出来

        (这句话放在开头说,GUIBuilder仅仅能够创建多页控件的框架,具体应用需要用户在页面窗口上面去实现)
        首先需要大家按照第2章2.3.4小节的说明下载STemWin的软件包,其中GUIBuilder5.32位于路径:STM32Cube_FW_F4_V1.13.0\\Middlewares\\ST\\STemWin\\Software里面
55.8.png


55.3.1   第一步:建立一个对话框,主体是框架窗口


1、到GUIBuilder后,打开这个软件,并按照如下方式建立一个对话框。
55.9.png
2、修改框架窗口大小为800*480
55.10.png
3、下面设置对话框标题的字体,对齐方式,和显示的文本。首先,在建立的对话框上面右击鼠标,选择Set font
55.11.png

        弹出如下界面,并选择字体GUI_FONT_32B_ASCII,点击OK。
55.12.png

设置好字体以后再设置对齐方式,还是右击鼠标,选择Set text alignment,并选择居中
55.13.png

配置完成后,上面的文本Framewin会居中显示,然后还是鼠标右击,选择Set title text,并更改Framewin为armfly,修改的地方在左下角:
55.14.png

设置好以后,对话框就算建立完毕。

55.3.2   第二步:在对话框上面建立多页控件


多页控件的建立方法和上面的对话框是一样的。先将多页控件拖到对话框上面,建立后的效果如下所示:
55.15.png

对于建立的多行文本控件,用户可以任意拖动,并通过鼠标调整其大小,调整方法如下:先左击选中相应控件,会出现绿色的边框,在边框的地方拖动鼠标即可修改大小
55.16.png

这里我们直接左键选中多页控件后,通过左下角的属性框中设置长度是400*240。
55.17.png

设置完毕后,还需要单独添加页面窗口,还是鼠标左键选中此控件,然后鼠标右击选择Add page,最后在左下角的属性框里面可以设置选项卡上面显示的内容,我们这里就设置为STM32-V4,。
55.18.png

相同的方法,我们再添加两个页面窗口,选项卡分别命名为STM32-V5和STM32-V6。
55.19.png




55.3.3   第三步:建立好后点击File-save


        保存方法如下:
55.20.png

保存后生成的文件在GUIBuilder5.32软件所在的文件夹里面:
55.21.png


55.3.4   第四步:在模拟器上运行GUIBuilder生成的代码


        在模拟器上面如何演示GUIBuilder生成的代码已经在第6章的6.3小节详细讲述了,这里不再赘述。可以在模拟器上面运行的完整代码如下,此代码对应的例子是V6-581_STemWin实验_MultiPage多页控件(模拟器):


(由于GUIBuilder创建多页控件的功能有限,我们这里要添加的代码稍多,为多页控件的三个页面窗口都添加了对话框,实际项目中,建议用户将对话框附加到多页控件的页面窗口上,这样页面窗口的管理将非常方便,而且这个对话框也可以使用GUIBuilder进行创建
  1. /*********************************************************************
  2. *                                                                    *
  3. *                SEGGER Microcontroller GmbH & Co. KG                *
  4. *        Solutions for real time microcontroller applications        *
  5. *                                                                    *
  6. **********************************************************************
  7. *                                                                    *
  8. * C-file generated by:                                               *
  9. *                                                                    *
  10. *        GUI_Builder for emWin version 5.32                          *
  11. *        Compiled Oct  8 2015, 11:59:02                              *
  12. *        (c) 2015 Segger Microcontroller GmbH & Co. KG               *
  13. *                                                                    *
  14. **********************************************************************
  15. *                                                                    *
  16. *        Internet: www.segger.com  Support: support@segger.com       *
  17. *                                                                    *
  18. **********************************************************************
  19. */
  20. // USER START (Optionally insert additional includes)
  21. // USER END
  22. #include "DIALOG.h"
  23. /*
  24. ************************************************************************************************
  25. *                             添加到多页控件第一个页面窗口的对话框                    //--------------(1)
  26. ************************************************************************************************
  27. */
  28. /*********************************************************************
  29. *
  30. *       Defines
  31. *
  32. **********************************************************************
  33. */
  34. #define ID_WINDOW_01 (GUI_ID_USER + 0x10)
  35. #define ID_BUTTON_01 (GUI_ID_USER + 0x11)
  36. // USER START (Optionally insert additional static data)
  37. // USER END
  38. /*********************************************************************
  39. *
  40. *       _aDialogCreate
  41. */
  42. static const GUI_WIDGET_CREATE_INFO _aDialogCreatePage1[] = {
  43.   { WINDOW_CreateIndirect, "Window", ID_WINDOW_01, 0, 0, 400, 200, 0, 0x0, 0 },
  44.   { BUTTON_CreateIndirect, "Button", ID_BUTTON_01, 127, 68, 129, 43, 0, 0x0, 0 },
  45. };
  46. /*********************************************************************
  47. *
  48. *       Static code
  49. *
  50. **********************************************************************
  51. */
  52. // USER START (Optionally insert additional static code)
  53. // USER END
  54. /*********************************************************************
  55. *
  56. *       _cbDialog
  57. */
  58. static void _cbDialogPage1(WM_MESSAGE * pMsg) {
  59.   WM_HWIN hItem;
  60.   int     NCode;
  61.   int     Id;
  62.   // USER START (Optionally insert additional variables)
  63.   // USER END
  64.   switch (pMsg->MsgId) {
  65.   case WM_INIT_DIALOG:
  66.     //
  67.     // Initialization of 'Button'
  68.     //
  69.     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_01);
  70.     BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
  71.     BUTTON_SetText(hItem, "Page1");
  72.     // USER START (Optionally insert additional code for further widget initialization)
  73.     // USER END
  74.     break;
  75.   case WM_NOTIFY_PARENT:
  76.     Id    = WM_GetId(pMsg->hWinSrc);
  77.     NCode = pMsg->Data.v;
  78.     switch(Id) {
  79.     case ID_BUTTON_01: // Notifications sent by 'Button'
  80.       switch(NCode) {
  81.       case WM_NOTIFICATION_CLICKED:
  82.         // USER START (Optionally insert code for reacting on notification message)
  83.         // USER END
  84.         break;
  85.       case WM_NOTIFICATION_RELEASED:
  86.         // USER START (Optionally insert code for reacting on notification message)
  87.         // USER END
  88.         break;
  89.       // USER START (Optionally insert additional code for further notification handling)
  90.       // USER END
  91.       }
  92.       break;
  93.     // USER START (Optionally insert additional code for further Ids)
  94.     // USER END
  95.     }
  96.     break;
  97.   default:
  98.     WM_DefaultProc(pMsg);
  99.     break;
  100.   }
  101. }
  102. /*********************************************************************
  103. *
  104. *       CreateWindowPage1
  105. */
  106. WM_HWIN CreateWindowPage1(void) {
  107.   WM_HWIN hWin;
  108.   hWin = GUI_CreateDialogBox(_aDialogCreatePage1, GUI_COUNTOF(_aDialogCreatePage1), _cbDialogPage1,
  109. WM_HBKWIN, 0, 0);
  110.   return hWin;
  111. }
  112. /*
  113. ************************************************************************************************
  114. *                             添加到多页控件第二个页面窗口的对话框                   //--------------(2)
  115. ************************************************************************************************
  116. */
  117. /*********************************************************************
  118. *
  119. *       Defines
  120. *
  121. **********************************************************************
  122. */
  123. #define ID_WINDOW_02 (GUI_ID_USER + 0x20)
  124. #define ID_BUTTON_02 (GUI_ID_USER + 0x21)
  125. // USER START (Optionally insert additional static data)
  126. // USER END
  127. /*********************************************************************
  128. *
  129. *       _aDialogCreate
  130. */
  131. static const GUI_WIDGET_CREATE_INFO _aDialogCreatePage2[] = {
  132.   { WINDOW_CreateIndirect, "Window", ID_WINDOW_02, 0, 0, 400, 200, 0, 0x0, 0 },
  133.   { BUTTON_CreateIndirect, "Button", ID_BUTTON_02, 127, 68, 129, 43, 0, 0x0, 0 },
  134. };
  135. /*********************************************************************
  136. *
  137. *       Static code
  138. *
  139. **********************************************************************
  140. */
  141. // USER START (Optionally insert additional static code)
  142. // USER END
  143. /*********************************************************************
  144. *
  145. *       _cbDialog
  146. */
  147. static void _cbDialogPage2(WM_MESSAGE * pMsg) {
  148.   WM_HWIN hItem;
  149.   int     NCode;
  150.   int     Id;
  151.   // USER START (Optionally insert additional variables)
  152.   // USER END
  153.   switch (pMsg->MsgId) {
  154.   case WM_INIT_DIALOG:
  155.     //
  156.     // Initialization of 'Button'
  157.     //
  158.     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_02);
  159.     BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
  160.     BUTTON_SetText(hItem, "Page2");
  161.     // USER START (Optionally insert additional code for further widget initialization)
  162.     // USER END
  163.     break;
  164.   case WM_NOTIFY_PARENT:
  165.     Id    = WM_GetId(pMsg->hWinSrc);
  166.     NCode = pMsg->Data.v;
  167.     switch(Id) {
  168.     case ID_BUTTON_02: // Notifications sent by 'Button'
  169.       switch(NCode) {
  170.       case WM_NOTIFICATION_CLICKED:
  171.         // USER START (Optionally insert code for reacting on notification message)
  172.         // USER END
  173.         break;
  174.       case WM_NOTIFICATION_RELEASED:
  175.         // USER START (Optionally insert code for reacting on notification message)
  176.         // USER END
  177.         break;
  178.       // USER START (Optionally insert additional code for further notification handling)
  179.       // USER END
  180.       }
  181.       break;
  182.     // USER START (Optionally insert additional code for further Ids)
  183.     // USER END
  184.     }
  185.     break;
  186.   default:
  187.     WM_DefaultProc(pMsg);
  188.     break;
  189.   }
  190. }
  191. /*********************************************************************
  192. *
  193. *       CreateWindowPage2
  194. */
  195. WM_HWIN CreateWindowPage2(void) {
  196.   WM_HWIN hWin;
  197.   hWin = GUI_CreateDialogBox(_aDialogCreatePage2, GUI_COUNTOF(_aDialogCreatePage2), _cbDialogPage2,
  198. WM_HBKWIN, 0, 0);
  199.   return hWin;
  200. }
  201. /*
  202. ************************************************************************************************
  203. *                             添加到多页控件第三个页面窗口的对话框                      //--------------(3)
  204. ************************************************************************************************
  205. */
  206. /*********************************************************************
  207. *
  208. *       Defines
  209. *
  210. **********************************************************************
  211. */
  212. #define ID_WINDOW_03 (GUI_ID_USER + 0x30)
  213. #define ID_BUTTON_03 (GUI_ID_USER + 0x31)
  214. // USER START (Optionally insert additional static data)
  215. // USER END
  216. /*********************************************************************
  217. *
  218. *       _aDialogCreate
  219. */
  220. static const GUI_WIDGET_CREATE_INFO _aDialogCreatePage3[] = {
  221.   { WINDOW_CreateIndirect, "Window", ID_WINDOW_03, 0, 0, 400, 200, 0, 0x0, 0 },
  222.   { BUTTON_CreateIndirect, "Button", ID_BUTTON_03, 127, 68, 129, 43, 0, 0x0, 0 },
  223. };
  224. /*********************************************************************
  225. *
  226. *       Static code
  227. *
  228. **********************************************************************
  229. */
  230. // USER START (Optionally insert additional static code)
  231. // USER END
  232. /*********************************************************************
  233. *
  234. *       _cbDialog
  235. */
  236. static void _cbDialogPage3(WM_MESSAGE * pMsg) {
  237.   WM_HWIN hItem;
  238.   int     NCode;
  239.   int     Id;
  240.   // USER START (Optionally insert additional variables)
  241.   // USER END
  242.   switch (pMsg->MsgId) {
  243.   case WM_INIT_DIALOG:
  244.     //
  245.     // Initialization of 'Button'
  246.     //
  247.     hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_03);
  248.     BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
  249.     BUTTON_SetText(hItem, "Page3");
  250.     // USER START (Optionally insert additional code for further widget initialization)
  251.     // USER END
  252.     break;
  253.   case WM_NOTIFY_PARENT:
  254.     Id    = WM_GetId(pMsg->hWinSrc);
  255.     NCode = pMsg->Data.v;
  256.     switch(Id) {
  257.     case ID_BUTTON_03: // Notifications sent by 'Button'
  258.       switch(NCode) {
  259.       case WM_NOTIFICATION_CLICKED:
  260.         // USER START (Optionally insert code for reacting on notification message)
  261.         // USER END
  262.         break;
  263.       case WM_NOTIFICATION_RELEASED:
  264.         // USER START (Optionally insert code for reacting on notification message)
  265.         // USER END
  266.         break;
  267.       // USER START (Optionally insert additional code for further notification handling)
  268.       // USER END
  269.       }
  270.       break;
  271.     // USER START (Optionally insert additional code for further Ids)
  272.     // USER END
  273.     }
  274.     break;
  275.   default:
  276.     WM_DefaultProc(pMsg);
  277.     break;
  278.   }
  279. }
  280. /*********************************************************************
  281. *
  282. *       CreateWindowPage3
  283. */
  284. WM_HWIN CreateWindowPage3(void) {
  285.   WM_HWIN hWin;
  286.   hWin = GUI_CreateDialogBox(_aDialogCreatePage3, GUI_COUNTOF(_aDialogCreatePage3), _cbDialogPage3,
  287. WM_HBKWIN, 0, 0);
  288.   return hWin;
  289. }
  290. /*********************************************************************
  291. *
  292. *       Defines
  293. *
  294. **********************************************************************
  295. */
  296. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
  297. #define ID_MULTIPAGE_0 (GUI_ID_USER + 0x01)
  298. // USER START (Optionally insert additional defines)
  299. // USER END
  300. /*********************************************************************
  301. *
  302. *       Static data
  303. *
  304. **********************************************************************
  305. */
  306. // USER START (Optionally insert additional static data)
  307. // USER END
  308. /*********************************************************************
  309. *
  310. *       _aDialogCreate
  311. */
  312. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  313.   { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x0, 0 },
  314.   { MULTIPAGE_CreateIndirect, "Multipage", ID_MULTIPAGE_0, 23, 25, 400, 240, 0, 0x0, 0 }, //--------(4)
  315.   // USER START (Optionally insert additional widgets)
  316.   // USER END
  317. };
  318. /*********************************************************************
  319. *
  320. *       Static code
  321. *
  322. **********************************************************************
  323. */
  324. // USER START (Optionally insert additional static code)
  325. // USER END
  326. /*********************************************************************
  327. *
  328. *       _cbDialog
  329. */
  330. static void _cbDialog(WM_MESSAGE * pMsg) {
  331.   WM_HWIN hItem;
  332.   WM_HWIN hWinPage;
  333.   int     NCode;
  334.   int     Id;
  335.   // USER START (Optionally insert additional variables)
  336.   // USER END
  337.   switch (pMsg->MsgId) {
  338.   case WM_INIT_DIALOG:
  339.     //
  340.     // Initialization of 'Framewin'
  341.     //
  342.     hItem = pMsg->hWin;
  343. FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  344. FRAMEWIN_SetText(hItem, "armfly");
  345.     FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  346.     //
  347.     // Initialization of 'Multipage'
  348.     //
  349.     hItem = WM_GetDialogItem(pMsg->hWin, ID_MULTIPAGE_0); //--------------(5)
  350.      MULTIPAGE_SetFont(hItem, GUI_FONT_16_ASCII);         //--------------(6)
  351.      hWinPage = CreateWindowPage1();                      //--------------(7)
  352.     MULTIPAGE_AddEmptyPage(hItem, hWinPage, "STM32-V4");  //--------------(8)
  353.      hWinPage = CreateWindowPage2();                      //--------------(9)
  354.     MULTIPAGE_AddEmptyPage(hItem, hWinPage, "STM32-V5");  //--------------(10)
  355.      hWinPage = CreateWindowPage3();                      //--------------(11)
  356.     MULTIPAGE_AddEmptyPage(hItem, hWinPage, "STM32-V6");  //--------------(12)
  357.     // USER START (Optionally insert additional code for further widget initialization)
  358.     // USER END
  359.     break;
  360.   case WM_NOTIFY_PARENT:
  361.     Id    = WM_GetId(pMsg->hWinSrc);
  362.     NCode = pMsg->Data.v;
  363.     switch(Id) {
  364.     case ID_MULTIPAGE_0: // Notifications sent by 'Multipage'
  365.       switch(NCode) {
  366.       case WM_NOTIFICATION_CLICKED:                     //--------------(13)
  367.         // USER START (Optionally insert code for reacting on notification message)
  368.         // USER END
  369.         break;
  370.       case WM_NOTIFICATION_RELEASED:                   //--------------(14)
  371.         // USER START (Optionally insert code for reacting on notification message)
  372.         // USER END
  373.         break;
  374.       case WM_NOTIFICATION_MOVED_OUT:                 //--------------(15)
  375.         // USER START (Optionally insert code for reacting on notification message)
  376.         // USER END
  377.         break;
  378.       case WM_NOTIFICATION_VALUE_CHANGED:             //--------------(16)
  379.         // USER START (Optionally insert code for reacting on notification message)
  380.         // USER END
  381.         break;
  382.       // USER START (Optionally insert additional code for further notification handling)
  383.       // USER END
  384.       }
  385.       break;
  386.     // USER START (Optionally insert additional code for further Ids)
  387.     // USER END
  388.     }
  389.     break;
  390.   // USER START (Optionally insert additional message handling)
  391.   // USER END
  392.   default:
  393.     WM_DefaultProc(pMsg);
  394.     break;
  395.   }
  396. }
  397. /*********************************************************************
  398. *
  399. *       Public code
  400. *
  401. **********************************************************************
  402. */
  403. /*********************************************************************
  404. *
  405. *       CreateFramewin
  406. */
  407. WM_HWIN CreateFramewin(void);
  408. WM_HWIN CreateFramewin(void) {
  409.   WM_HWIN hWin;
  410.   hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  411.   return hWin;
  412. }
  413. // USER START (Optionally insert additional public code)
  414. // USER END
  415. /*************************** End of file ****************************/
  416. /*********************************************************************
  417. *
  418. *       MainTask
  419. */
  420. void MainTask(void)
  421. {
  422.      /* 初始化 */
  423.      GUI_Init();
  424.      /* 窗口自动使用存储设备 */
  425.      WM_SetCreateFlags(WM_CF_MEMDEV);
  426.      /* 创建对话框,使用GUIBulder5.32生成的对话框创建函数 */
  427.      CreateFramewin();
  428.      while(1)
  429.      {
  430.          GUI_Delay(50);
  431.      }
  432. }
  433. /*************************** End of file ****************************/
复制代码
创建的这个例子相对稍麻烦,主要实现了在对话框上面创建一个多页控件,并为多页控件创建了三个页面窗口,每个窗口添加了一个对话框。
1.     创建的第一个对话框,添加到多页控件的第一个页面窗口上。这里是使用GUIBuilder创建的对话框,主体窗口是Window,界面大小是400*200。
2.     创建的第二个对话框,添加到多页控件的第二个页面窗口上。这里是使用GUIBuilder创建的对话框,主体窗口是Window,界面大小是400*200。
3.     创建的第三个对话框,添加到多页控件的第三个页面窗口上。这里是使用GUIBuilder创建的对话框,主体窗口是Window,界面大小是400*200。
4.     在对话框的资源列表中创建一个多页控件。
5.     通过函数WM_GetDialogItem获得对话框上ID为ID_MULTIPAGE_0的多页控件句柄。
6.     通过函数MULTIPAGE_SetFont设置多页控件选项卡中文本的字体。
7.     调用函数CreateWindowPage1创建第一个对话框。
8.     通过函数MULTIPAGE_AddEmptyPage将第一个对话框添加到多页控件的第一个页面窗口,并将选项卡命名为STM32-V4
9.     调用函数CreateWindowPage2创建第二个对话框。
10.  通过函数MULTIPAGE_AddEmptyPage将第二个对话框添加到多页控件的第二个页面窗口,并将选项卡命名为STM32-V5
11.  调用函数CreateWindowPage3创建第三个对话框。
12.  通过函数MULTIPAGE_AddEmptyPage将第三个对话框添加到多页控件的第三个页面窗口,并将选
项卡命名为STM32-V6。
13.  多页控件ID_ MULTIPAGE_0的点击消息WM_NOTIFICATION_CLICKED,如果用户需要点击多页控件后执行某项功能,就可以在这个消息里面加入用户功能。
14.  多页控件ID_ MULTIPAGE_0的释放消息WM_NOTIFICATION_RELEASED,如果用户需要多页控件释放后执行某项功能,就可以在这个消息里面加入用户功能。
15.  多页控件ID_ MULTIPAGE_0的移开消息WM_NOTIFICATION_MOVED_OUT,如果用户需要进入此消息后执行某项功能,就可以在这个消息里面加入用户功能。
16.  多页控件ID_ MULTIPAGE_0的消息WM_NOTIFICATION_VALUE_CHANGED,如果用户需要进入此消息后执行某项功能,就可以在这个消息里面加入用户功能。

实际显示效果如下,分辨率800*480:
55.22.png

对于这个创建和演示过程,强烈建议初学者实际动手操作。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-13 16:48:29 | 显示全部楼层
55.4  官方WIDGET_Multipage.c实例讲解

        这个例子在模拟器中的位置:
55.23.png


主要功能介绍:
        这个例子比较容易理解,适合初学者学习参考,主要实现了在框架窗口上面创建一个多页控件,并给多页控件创建了6个页面窗口,每个页面窗口上都添加了对话框。
程序代码如下:
  1. #include <stdlib.h>
  2. #include "GUI.h"
  3. #include "MULTIPAGE.h"
  4. /*********************************************************************
  5. *
  6. *       Defines
  7. *
  8. **********************************************************************
  9. */
  10. //
  11. // Recommended memory to run the sample with adequate performance
  12. //
  13. #define RECOMMENDED_MEMORY (1024L * 20)
  14. /*********************************************************************
  15. *
  16. *       Static data
  17. *
  18. **********************************************************************
  19. */
  20. /*********************************************************************
  21. *
  22. *       Dialog resource
  23. *
  24. *  These tables contain the information required to create the dialogs.
  25. *  It has been created manually, but could also be created by the GUIBuilder.
  26. */
  27. static const GUI_WIDGET_CREATE_INFO _aDialogCreate1[] = {
  28.   { WINDOW_CreateIndirect,    "Dialog 1", 0,                   0,   0, 260, 100, FRAMEWIN_CF_MOVEABLE },
  29.   { BUTTON_CreateIndirect,    "Button",   GUI_ID_BUTTON0,      5,  30,  80,  20, 0},
  30.   { TEXT_CreateIndirect,      "Dialog 1", 0,                   5,  10,  50,  20, TEXT_CF_LEFT }
  31. };
  32. static const GUI_WIDGET_CREATE_INFO _aDialogCreate2[] = {
  33.   { WINDOW_CreateIndirect,    "Dialog 2", 0,                   0,   0, 260, 100, FRAMEWIN_CF_MOVEABLE },
  34.   { CHECKBOX_CreateIndirect,  "",         GUI_ID_CHECK0,       5,  30,   0,   0, 0},
  35.   { CHECKBOX_CreateIndirect,  "",         GUI_ID_CHECK1,       5,  50,   0,   0, 0},
  36.   { TEXT_CreateIndirect,      "Select 0", GUI_ID_TEXT0,       25,  30,  50,  15, TEXT_CF_LEFT },
  37.   { TEXT_CreateIndirect,      "Select 1", GUI_ID_TEXT1,       25,  50,  50,  15, TEXT_CF_LEFT },
  38.   { TEXT_CreateIndirect,      "Dialog 2", 0,                   5,  10,  50,  20, TEXT_CF_LEFT }
  39. };
  40. static const GUI_WIDGET_CREATE_INFO _aDialogCreate3[] = {
  41.   { WINDOW_CreateIndirect,    "Dialog 3", 0,                   0,   0, 260, 100, FRAMEWIN_CF_MOVEABLE },
  42.   { RADIO_CreateIndirect,     "",         GUI_ID_RADIO0,       5,  30,   0,   0, 0, 3},
  43.   { TEXT_CreateIndirect,      "Option 1", GUI_ID_TEXT0,       25,  30,  50,  15, TEXT_CF_LEFT },
  44.   { TEXT_CreateIndirect,      "Option 2", GUI_ID_TEXT1,       25,  50,  50,  15, TEXT_CF_LEFT },
  45.   { TEXT_CreateIndirect,      "Option 3", GUI_ID_TEXT2,       25,  70,  50,  15, TEXT_CF_LEFT },
  46.   { TEXT_CreateIndirect,      "Dialog 3", 0,                   5,  10,  50,  20, TEXT_CF_LEFT }
  47. };
  48. static const GUI_WIDGET_CREATE_INFO _aDialogCreate4[] = {
  49.   { WINDOW_CreateIndirect,    "Dialog 4", 0,                   0,   0, 260, 100, FRAMEWIN_CF_MOVEABLE },
  50.   { MULTIEDIT_CreateIndirect, "Text",     GUI_ID_MULTIEDIT0,   5,  30, 200,  40  },
  51.   { TEXT_CreateIndirect,      "Dialog 4", 0,                   5,  10,  50,  20, TEXT_CF_LEFT }
  52. };
  53. static const GUI_WIDGET_CREATE_INFO _aDialogCreate5[] = {
  54.   { WINDOW_CreateIndirect,    "Dialog 5", 0,                   0,   0, 260, 100, FRAMEWIN_CF_MOVEABLE },
  55.   { SLIDER_CreateIndirect,    "",         GUI_ID_SLIDER0,      5,  30, 200,  40  },
  56.   { TEXT_CreateIndirect,      "Dialog 5", 0,                   5,  10,  50,  20, TEXT_CF_LEFT }
  57. };
  58. static const GUI_WIDGET_CREATE_INFO _aDialogCreate6[] = {
  59.   { WINDOW_CreateIndirect,    "Dialog 6", 0,                   0,   0, 260, 100, FRAMEWIN_CF_MOVEABLE },
  60.   { SCROLLBAR_CreateIndirect, "",         GUI_ID_SCROLLBAR0,   5,  30, 200,  40  },
  61.   { TEXT_CreateIndirect,      "Dialog 6", 0,                   5,  10,  50,  20, TEXT_CF_LEFT }
  62. };
  63. /*********************************************************************
  64. *
  65. *       Static code
  66. *
  67. **********************************************************************
  68. */
  69. /*********************************************************************
  70. *
  71. *       _cbDialog4
  72. */
  73. static void _cbDialog4(WM_MESSAGE * pMsg) {
  74.   WM_HWIN hItem;
  75.   WM_HWIN hDlg;
  76.   hDlg = pMsg->hWin;
  77.   switch (pMsg->MsgId) {
  78.   case WM_INIT_DIALOG:
  79.     hItem = WM_GetDialogItem(hDlg, GUI_ID_MULTIEDIT0);
  80.     MULTIEDIT_SetText(hItem, "MULTIEDIT widget");
  81.     MULTIEDIT_SetInsertMode(hItem, 1);
  82.     break;
  83.   default:
  84.     WM_DefaultProc(pMsg);
  85.   }
  86. }
  87. /*********************************************************************
  88. *
  89. *       _cbBkWindow
  90. *
  91. *  Function description
  92. *    Callback routine of the background window.
  93. *    It shows the sample title and draws the background.
  94. */
  95. static void _cbBkWindow(WM_MESSAGE * pMsg) {
  96.   switch (pMsg->MsgId) {
  97.   case WM_PAINT:
  98.     GUI_SetBkColor(GUI_BLUE);
  99.     GUI_Clear();
  100.     GUI_SetColor(GUI_WHITE);
  101.     GUI_SetFont(&GUI_Font24_ASCII);
  102.     GUI_DispStringHCenterAt("WIDGET_Multipage - Sample", 160, 5);
  103.     break;
  104.   default:
  105.     WM_DefaultProc(pMsg);
  106.   }
  107. }
  108. /*********************************************************************
  109. *
  110. *       Public code
  111. *
  112. **********************************************************************
  113. */
  114. /*********************************************************************
  115. *
  116. *       MainTask
  117. */
  118. void MainTask(void) {
  119.   WM_HWIN hMultiPage;
  120.   WM_HWIN hFrameWin;
  121.   WM_HWIN hDialog;
  122.   //
  123.   // Enable use of memory devices
  124.   //
  125.   WM_SetCreateFlags(WM_CF_MEMDEV);
  126.   GUI_Init();
  127.   //
  128.   // Check if recommended memory for the sample is available
  129.   //
  130.   if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
  131.     GUI_ErrorOut("Not enough memory available.");
  132.     return;
  133.   }
  134.   WM_SetCallback(WM_HBKWIN, _cbBkWindow);
  135.   //
  136.   // Create the frame window
  137.   //
  138.   hFrameWin = FRAMEWIN_Create("FrameWindow", NULL, WM_CF_SHOW, 40, 44, 240, 152);  //--------------(1)
  139.   FRAMEWIN_SetClientColor(hFrameWin, GUI_GREEN);
  140.   FRAMEWIN_SetActive(hFrameWin, 1);
  141.   FRAMEWIN_SetMoveable(hFrameWin, 1);
  142.   //
  143.   // Create the MULTIPAGE widget
  144.   //
  145.   hMultiPage = MULTIPAGE_CreateEx(7, 6, 220, 120, WM_GetClientWindow(hFrameWin), WM_CF_SHOW, 0, 0); //---(2)
  146.   GUI_Delay(500);
  147.   //
  148.   // Create and attach the MULTIPAGE dialog windows
  149.   //
  150.   hDialog = GUI_CreateDialogBox(_aDialogCreate1, GUI_COUNTOF(_aDialogCreate1), NULL,     
  151. WM_UNATTACHED, 0, 0);  //--------------(3)
  152.   MULTIPAGE_AddPage(hMultiPage, hDialog, "Page 1");     //--------------(4)
  153.   GUI_Delay(500);
  154.   hDialog = GUI_CreateDialogBox(_aDialogCreate2, GUI_COUNTOF(_aDialogCreate2), NULL,     
  155. WM_UNATTACHED, 0, 0);
  156.   MULTIPAGE_AddPage(hMultiPage, hDialog, "Page 2");     //--------------(5)
  157.   GUI_Delay(500);
  158.   hDialog = GUI_CreateDialogBox(_aDialogCreate3, GUI_COUNTOF(_aDialogCreate3), NULL,     
  159. WM_UNATTACHED, 0, 0);
  160.   MULTIPAGE_AddPage(hMultiPage, hDialog, "Page 3");     //--------------(6)
  161.   GUI_Delay(500);
  162.   hDialog = GUI_CreateDialogBox(_aDialogCreate4, GUI_COUNTOF(_aDialogCreate4), _cbDialog4,
  163. WM_UNATTACHED, 0, 0);
  164.   MULTIPAGE_AddPage(hMultiPage, hDialog, "Page 4");     //--------------(7)
  165.   GUI_Delay(500);
  166.   hDialog = GUI_CreateDialogBox(_aDialogCreate5, GUI_COUNTOF(_aDialogCreate5), NULL,      
  167. WM_UNATTACHED, 0, 0);
  168.   MULTIPAGE_AddPage(hMultiPage, hDialog, "Page 5");     //--------------(8)
  169.   GUI_Delay(500);
  170.   hDialog = GUI_CreateDialogBox(_aDialogCreate6, GUI_COUNTOF(_aDialogCreate6), NULL,      
  171. WM_UNATTACHED, 0, 0);
  172.   MULTIPAGE_AddPage(hMultiPage, hDialog, "Page 6");     //--------------(9)
  173.   GUI_Delay(500);
  174.   //
  175.   // Demonstrate the use of MULTIPAGE_SetAlign
  176.   //
  177.   MULTIPAGE_SetAlign(hMultiPage, MULTIPAGE_ALIGN_RIGHT);  //--------------(10)
  178.   GUI_Delay(500);
  179.   MULTIPAGE_SetAlign(hMultiPage, MULTIPAGE_ALIGN_RIGHT | MULTIPAGE_ALIGN_BOTTOM);  //--------------(11)
  180.   GUI_Delay(500);
  181.   MULTIPAGE_SetAlign(hMultiPage, MULTIPAGE_ALIGN_LEFT | MULTIPAGE_ALIGN_BOTTOM);  //--------------(12)
  182.   while (1) {
  183.     GUI_Delay(100);
  184.   }
  185. }
  186. /*************************** End of file ****************************/
复制代码
1.     通过函数FRAMEWIN_Create创建框架窗口。
2.     通过函数MULTIPAGE_CreateEx将多页控件创建到框架窗口,特别注意,多页控件是要创建框架窗口的客户端窗口上,所以父窗口是WM_GetClientWindow(hFrameWin)。
3.     创建对话框,并将父窗口的参数设置为WM_UNATTACHED,表示当前未设置父窗口,或者说未附加到任何窗口上。
4.     通过函数MULTIPAGE_AddPage将对话框附加到多页控件的第1个页面窗口。
5.     通过函数MULTIPAGE_AddPage将第2次创建对话框附加到多页控件的第2个页面窗口。
6.     通过函数MULTIPAGE_AddPage将第3次创建对话框附加到多页控件的第3个页面窗口。
7.     通过函数MULTIPAGE_AddPage将第4次创建对话框附加到多页控件的第4个页面窗口。
8.     通过函数MULTIPAGE_AddPage将第5次创建对话框附加到多页控件的第5个页面窗口。
9.     通过函数MULTIPAGE_AddPage将第6次创建对话框附加到多页控件的第6个页面窗口。
10.  通过函数MULTIPAGE_SetAlign设置多页控件的选项卡右对齐。
11.  通过函数MULTIPAGE_SetAlign设置多页控件的选项卡右下角对齐。
12.  通过函数MULTIPAGE_SetAlign设置多页控件的选项卡左下角对齐。
实际显示效果如下:
55.24.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-13 16:52:46 | 显示全部楼层
55.5 实验例程说明(RTOS)


配套例子:
        V6-579_STemWin实验_MultiPage多页控件(RTOS)
实验目的:
        1.     本实验主要学习多行文本控件的使用。
        2.     emWin功能的实现在MainTask.c文件里面。
实验内容:
        1.     K1按键按下,串口打印任务执行情况(波特率115200,数据位8,奇偶校验位无,停止位1)。
        2.     K2按键按下,实现截图功能,将图片以BMP格式保存到SD卡中。
        3.     GUI任务主要在对话框上面创建了一个多页控件,控件上创建了三个页面窗口,每个页面窗口,添加了一个对话框。并且为每个对话框上面都添加了按钮控件,点击按钮控件实现LED的亮灭反转,三个对话框上的按钮控件分别控制的是LED1,LED2和LED3。
        4.     各个任务实现的功能如下:
              App Task Start   任务:实现按键和触摸扫描。
              App Task MspPro任务 :实现截图功能,将图片以BMP格式保存到SD卡中。
              App Task UserIF  任务:按键消息处理。
              App Task COM   任务:暂未使用。
              App Task GUI    任务:GUI任务。
μCOS-III任务调试信息(按K1按键,串口打印):
55.25.png

STemWin界面显示效果:
        800*480分辨率界面效果。
55.26.png

STemWin动态内存配置:
        GUIConf.c文件中的配置如下:
  1. #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
  2. #if EX_SRAM
  3. #define GUI_NUMBYTES  (1024*1024*8)
  4. #else
  5. #define GUI_NUMBYTES  (100*1024)
  6. #endif
复制代码
        通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM    1 表示使用外部SDRAM作为emWin动态内存,大小8MB。
#define EX_SRAM    0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
STemWin底层接口配置:
        LCDConf_Lin_Template.c文件中共12项emWin配置:
  1. /*
  2. **********************************************************************************************************
  3.                                           用户可以配置的选项
  4. **********************************************************************************************************
  5. */
  6. /* 0. 在官方代码的基础上再做优化,官方的部分函数效率低,耗内存, 0表示优化 */
  7. #define emWin_Optimize   0
  8. /*
  9.   1. 显示屏的物理分辨率,驱动已经做了显示屏自适应,支持4.3寸,5寸和7寸屏
  10.      这里填写自适应显示屏中的最大分辨率。
  11. */
  12. #define XSIZE_PHYS       800
  13. #define YSIZE_PHYS       480
  14. /* 2. 多缓冲 / 虚拟屏,多缓冲和虚拟屏不可同时使用,emWin不支持 */
  15. #define NUM_BUFFERS      3 /* 定义多缓冲个数,仅可以设置1,2和3,也就是最大支持三缓冲 */
  16. #define NUM_VSCREENS     1 /* 定义虚拟屏个数 */
  17. /* 3. 没有图层激活时,背景色设置, 暂时未用到 */
  18. #define BK_COLOR         GUI_DARKBLUE
  19. /*
  20.    4. 重定义图层数,对于STM32F429/439,用户可以选择一个图层或者两个图层,不支持三图层
  21.       (1). 设置GUI_NUM_LAYERS = 1时,即仅使用图层1时,默认触摸值是发送给图层1的。
  22.        (2). 设置GUI_NUM_LAYERS = 2时,即图层1和图层2都已经使能,此时图层2是顶层,
  23.             用户需要根据自己的使用情况设置如下两个地方。
  24.             a. 在bsp_touch.c文件中的函数TOUCH_InitHard里面设置参数State.Layer = 1,1就表示
  25.                给图层2发送触摸值。
  26.             b. 调用GUI_Init函数后,调用函数GUI_SelectLayer(1), 设置当前操作的是图层2。
  27. */
  28. #undef  GUI_NUM_LAYERS
  29. #define GUI_NUM_LAYERS    1
  30. /*
  31.    5. 设置图层1和图层2对应的显存地址
  32.       (1) EXT_SDRAM_ADDR 是SDRAM的首地址。
  33.       (2) LCD_LAYER0_FRAME_BUFFER 是图层1的显存地址。
  34.        (3) LCD_LAYER1_FRAME_BUFFER 是图层2的显存地址。
  35.        (4) 每个图层的显存大小比较考究,这里进行下简单的说明。
  36.            如果用户选择的颜色模式 = 32位色ARGB8888,显存的大小:
  37.            XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS * NUM_BUFFERS
  38.          
  39.            颜色模式 = 24位色RGB888,显存的大小:
  40.            XSIZE_PHYS * YSIZE_PHYS * 3 * NUM_VSCREENS * NUM_BUFFERS
  41.          
  42.            颜色模式 = 16位色RGB566,ARGB1555, ARGB4444,AL88,那么显存的大小就是:
  43.            XSIZE_PHYS * YSIZE_PHYS * 2 * NUM_VSCREENS * NUM_BUFFERS
  44.            颜色模式 = 8位色L8,AL44,那么显存的大小就是:
  45.            XSIZE_PHYS * YSIZE_PHYS * 1 * NUM_VSCREENS * NUM_BUFFERS  
  46.      
  47.       这里为了方便起见,将开发板配套的16MB的SDRAM前8MB分配给LCD显存使用,后8MB用于emWin动态内存。
  48.        对于24位色,16位色,8位色,用户可以对其使能三缓冲,并且使能双图层。但是32位色也使能三缓冲和双
  49.        图层的话会超出8MB,所以用户根据自己的情况做显存和emWin动态内存的分配调整。
  50.          举一个例子,对于800*480分辨率的显示屏,使能32位色,三缓冲,那么最终一个图层需要的大小就是
  51.       800 * 480 * 4 * 3  = 4.394MB的空间,如果是双图层,已经超出8MB的分配范围。
  52.      
  53.       (5)为了方便起见,图层2的宏定义LCD_LAYER1_FRAME_BUFFER中的参数4是按照32位色设置的,如果用户的图层1
  54.          使用的是8位色,这里填数字1,如果是16位色,这里填2,如果是24位色,这里填3。
  55. */
  56. #define LCD_LAYER0_FRAME_BUFFER  EXT_SDRAM_ADDR
  57. #define LCD_LAYER1_FRAME_BUFFER  (LCD_LAYER0_FRAME_BUFFER + XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS *
  58. NUM_BUFFERS)
  59. /*
  60.    6. STM32F429/439支持的颜色模式,所有模式都支持,用户可任意配置。
  61.       特别注意如下两个问题:
  62.        (1) 如果用户选择了ARGB8888或者RGB888模式,LCD闪烁比较厉害的话,
  63.            请降低LTDC的时钟大小,在文件bsp_tft_429.c的函数LCD_ConfigLTDC里面设置。
  64.            a. 一般800*480分辨率的显示屏,ARGB8888或者RGB888模式LTDC时钟选择10-20MHz即可。
  65.            b. 480*272分辨率的可以高些,取20MHz左右即可。
  66.        (2) 16位色或者8位色模式,LTDC的时钟频率一般可以比24位色或者32位色的高一倍。
  67. */
  68. #define _CM_ARGB8888      1
  69. #define _CM_RGB888        2
  70. #define _CM_RGB565        3
  71. #define _CM_ARGB1555      4
  72. #define _CM_ARGB4444      5
  73. #define _CM_L8            6
  74. #define _CM_AL44          7
  75. #define _CM_AL88          8
  76. /* 7. 配置图层1的颜色模式和分辨率大小 */
  77. #define COLOR_MODE_0      _CM_RGB565
  78. #define XSIZE_0           XSIZE_PHYS
  79. #define YSIZE_0           YSIZE_PHYS
  80. /* 8. 配置图层2的的颜色模式和分辨率大小 */
  81. #define COLOR_MODE_1      _CM_RGB565
  82. #define XSIZE_1           XSIZE_PHYS
  83. #define YSIZE_1           YSIZE_PHYS
  84. /* 9. 单图层情况下,根据用户选择的颜色模式可自动选择图层1的emWin的驱动和颜色模式 */
  85. #if   (COLOR_MODE_0 == _CM_ARGB8888)
  86.   #define COLOR_CONVERSION_0 GUICC_M8888I
  87.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_32
  88. #elif (COLOR_MODE_0 == _CM_RGB888)
  89.   #define COLOR_CONVERSION_0 GUICC_M888
  90.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_24
  91. #elif (COLOR_MODE_0 == _CM_RGB565)
  92.   #define COLOR_CONVERSION_0 GUICC_M565
  93.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  94. #elif (COLOR_MODE_0 == _CM_ARGB1555)
  95.   #define COLOR_CONVERSION_0 GUICC_M1555I
  96.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  97. #elif (COLOR_MODE_0 == _CM_ARGB4444)
  98.   #define COLOR_CONVERSION_0 GUICC_M4444I
  99.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  100. #elif (COLOR_MODE_0 == _CM_L8)
  101.   #define COLOR_CONVERSION_0 GUICC_8666
  102.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  103. #elif (COLOR_MODE_0 == _CM_AL44)
  104.   #define COLOR_CONVERSION_0 GUICC_1616I
  105.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  106. #elif (COLOR_MODE_0 == _CM_AL88)
  107.   #define COLOR_CONVERSION_0 GUICC_88666I
  108.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  109. #else
  110.   #error Illegal color mode 0!
  111. #endif
  112. /* 10. 双图层情况下,根据用户选择的颜色模式可自动选择图层2的emWin的驱动和颜色模式 */
  113. #if (GUI_NUM_LAYERS > 1)
  114. #if   (COLOR_MODE_1 == _CM_ARGB8888)
  115.   #define COLOR_CONVERSION_1 GUICC_M8888I
  116.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_32
  117. #elif (COLOR_MODE_1 == _CM_RGB888)
  118.   #define COLOR_CONVERSION_1 GUICC_M888
  119.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_24
  120. #elif (COLOR_MODE_1 == _CM_RGB565)
  121.   #define COLOR_CONVERSION_1 GUICC_M565
  122.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  123. #elif (COLOR_MODE_1 == _CM_ARGB1555)
  124.   #define COLOR_CONVERSION_1 GUICC_M1555I
  125.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  126. #elif (COLOR_MODE_1 == _CM_ARGB4444)
  127.   #define COLOR_CONVERSION_1 GUICC_M4444I
  128.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  129. #elif (COLOR_MODE_1 == _CM_L8)
  130.   #define COLOR_CONVERSION_1 GUICC_8666
  131.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  132. #elif (COLOR_MODE_1 == _CM_AL44)
  133.   #define COLOR_CONVERSION_1 GUICC_1616I
  134.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  135. #elif (COLOR_MODE_1 == _CM_AL88)
  136.   #define COLOR_CONVERSION_1 GUICC_88666I
  137.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  138. #else
  139.   #error Illegal color mode 1!
  140. #endif
  141. #else
  142. #undef XSIZE_0
  143. #undef YSIZE_0
  144. #define XSIZE_0       XSIZE_PHYS
  145. #define YSIZE_0       YSIZE_PHYS
  146. #endif
  147. /*11. 配置选项检测,防止配置错误或者某些选项没有配置 */
  148. #ifndef   XSIZE_PHYS
  149.   #error Physical X size of display is not defined!
  150. #endif
  151. #ifndef   YSIZE_PHYS
  152.   #error Physical Y size of display is not defined!
  153. #endif
  154. #ifndef   NUM_VSCREENS
  155.   #define NUM_VSCREENS 1
  156. #else
  157.   #if (NUM_VSCREENS <= 0)
  158.     #error At least one screeen needs to be defined!
  159.   #endif
  160. #endif
  161. #if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
  162.   #error Virtual screens and multiple buffers are not allowed!
  163. #endif
复制代码
        对于这12个配置选项,注释说明已经比较详细。默认情况下,本教程配套的emWin例子都是用的三缓冲,RGB565格式,且仅使用单图层。
程序设计:
任务栈大小分配:
         μCOS-III任务栈大小在os_cfg.h文件中配置:
#define  APP_CFG_TASK_START_STK_SIZE                     512u
#define  APP_CFG_TASK_MsgPro_STK_SIZE                    512u
#define  APP_CFG_TASK_COM_STK_SIZE                       512u
#define  APP_CFG_TASK_USER_IF_STK_SIZE                    512u
#define  APP_CFG_TASK_GUI_STK_SIZE                        1024u
        任务栈大小的单位是4字节,那么每个任务的栈大小如下:
App Task Start   任务:2048字节。
       App Task MspPro任务 :2048字节。
       App Task UserIF  任务:2048字节。
       App Task COM   任务:2048字节。
App Task GUI    任务:4096字节。
系统栈大小分配:
        μCOS-III的系统栈大小在os_cfg_app.h文件中配置:
        #define  OS_CFG_ISR_STK_SIZE                      512u      
          系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB。
μCOS-III初始化:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: 标准c程序入口。
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. int main(void)
  10. {
  11.     OS_ERR  err;
  12.    
  13.      /* 初始化uC/OS-III 内核 */
  14.     OSInit(&err);
  15.      /* 创建一个启动任务(也就是主任务)。启动任务会创建所有的应用程序任务 */
  16.      OSTaskCreate((OS_TCB       *)&AppTaskStartTCB,  /* 任务控制块地址 */           
  17.                  (CPU_CHAR     *)"App Task Start",  /* 任务名 */
  18.                  (OS_TASK_PTR   )AppTaskStart,      /* 启动任务函数地址 */
  19.                  (void         *)0,                 /* 传递给任务的参数 */
  20.                  (OS_PRIO       )APP_CFG_TASK_START_PRIO, /* 任务优先级 */
  21.                  (CPU_STK      *)&AppTaskStartStk[0],     /* 堆栈基地址 */
  22.                  (CPU_STK_SIZE  )APP_CFG_TASK_START_STK_SIZE / 10, /* 堆栈监测区,这里表示后10%作为监测区 */
  23.                  (CPU_STK_SIZE  )APP_CFG_TASK_START_STK_SIZE,      /* 堆栈空间大小 */
  24.                  (OS_MSG_QTY    )0,  /* 本任务支持接受的最大消息数 */
  25.                  (OS_TICK       )0,  /* 设置时间片 */
  26.                  (void         *)0,  /* 堆栈空间大小 */
  27.                  (OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  28.         
  29.                     /*  定义如下:
  30.                        OS_OPT_TASK_STK_CHK      使能检测任务栈,统计任务栈已用的和未用的
  31.                        OS_OPT_TASK_STK_CLR      在创建任务时,清零任务栈
  32.                        OS_OPT_TASK_SAVE_FP      如果CPU有浮点寄存器,则在任务切换时保存浮点寄存器的内容
  33.                     */
  34.                  (OS_ERR       *)&err);
  35.      /* 启动多任务系统,控制权交给uC/OS-III */
  36.     OSStart(&err);                                             
  37.    
  38.     (void)&err;
  39.    
  40.     return (0);
  41. }
复制代码
硬件外设初始化
        硬件外设的初始化是在bsp.c文件实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: bsp_Init
  4. *    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
  5. *    形    参:无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void bsp_Init(void)
  10. {
  11.      /*
  12.          由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
  13.          启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
  14.          系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
  15.      */
  16.      /* 使能CRC 因为使用STemWin前必须要使能 */
  17.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  18.    
  19.      /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
  20.      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  21.    
  22.      SystemCoreClockUpdate();    /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
  23.      bsp_InitUart();        /* 初始化串口 */
  24.      bsp_InitKey();         /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
  25.    
  26.      bsp_InitExtIO();       /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */
  27.      bsp_InitLed();         /* 初始LED指示灯端口 */
  28.    
  29.      bsp_InitI2C();         /* 配置I2C总线 */
  30.      bsp_InitSPIBus();       /* 配置SPI总线 */
  31.    
  32.      bsp_InitSFlash();       /* 初始化SPI Flash */
  33.    
  34.      bsp_InitExtSDRAM();   /* 初始化SDRAM */
  35.      bsp_DetectLcdType();  /* 检测触摸板和LCD面板型号, 结果存在全局变量 g_TouchType, g_LcdType */
  36.    
  37.      TOUCH_InitHard();    /* 初始化配置触摸芯片 */
  38.      LCD_ConfigLTDC();     /* 初始化配置LTDC */
  39.    
  40.      result = f_mount(&fs, "0:/", 0);     /* 挂载文件系统 */
  41. }
复制代码
五个μCOS-III任务的实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: AppTaskStart
  4. *    功能说明: 这是一个启动任务,在多任务系统启动后,必须初始化滴答计数器。本任务主要实现按键和触摸检测。
  5. *    形    参: p_arg 是在创建该任务时传递的形参
  6. *    返 回 值: 无
  7.      优 先 级: 2
  8. *********************************************************************************************************
  9. */
  10. static  void  AppTaskStart (void *p_arg)
  11. {
  12.      OS_ERR      err;
  13.      uint8_t  ucCount = 0;
  14.      uint8_t  ucCount1 = 0;
  15.    
  16.     /* 仅用于避免编译器告警,编译器不会产生任何目标代码 */  
  17.     (void)p_arg;
  18.    
  19.      /* BSP 初始化。 BSP = Board Support Package 板级支持包,可以理解为底层驱动。*/
  20.      CPU_Init();  /* 此函数要优先调用,因为外设驱动中使用的us和ms延迟是基于此函数的 */
  21.      bsp_Init();      
  22.      BSP_Tick_Init();
  23.    
  24. #if OS_CFG_STAT_TASK_EN > 0u
  25.      OSStatTaskCPUUsageInit(&err);  
  26. #endif
  27. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  28.     CPU_IntDisMeasMaxCurReset();
  29. #endif
  30.         
  31.      /* 创建应用程序的任务 */
  32.      AppTaskCreate();
  33.    
  34.      /* 创建任务通信 */
  35.      AppObjCreate();
  36.    
  37.     while(1)
  38.     {
  39.          /* 1ms一次触摸扫描,电阻触摸屏 */
  40.          if(g_tTP.Enable == 1)
  41.          {
  42.               TOUCH_Scan();
  43.             
  44.               /* 按键扫描 */
  45.               ucCount++;
  46.               if(ucCount == 10)
  47.               {
  48.                    ucCount = 0;
  49.                    bsp_KeyScan();
  50.               }
  51.              OSTimeDly(1, OS_OPT_TIME_DLY, &err);         
  52.          }
  53.         
  54.          /* 20ms一次触摸扫描,电容触摸屏GT811
  55.              GT811取20ms比较稳定,取10ms偶尔会有跳动。
  56.          */
  57.          if(g_GT811.Enable == 1)
  58.          {
  59.               bsp_KeyScan();
  60.               ucCount1++;
  61.               if(ucCount1 == 2)
  62.               {
  63.                    ucCount1 = 0;
  64.                    GT811_OnePiontScan();
  65.               }
  66.              OSTimeDly(10, OS_OPT_TIME_DLY, &err);     
  67.          }
  68.         
  69.          /* 10ms一次触摸扫描,电容触摸屏FT5X06 */
  70.          if(g_tFT5X06.Enable == 1)
  71.          {
  72.               bsp_KeyScan();
  73.               FT5X06_OnePiontScan();
  74.              OSTimeDly(10, OS_OPT_TIME_DLY, &err);
  75.          }
  76.     }   
  77. }
  78. /*
  79. *********************************************************************************************************
  80. *    函 数 名: AppTaskMsgPro
  81. *    功能说明: 实现截图功能,将图片以BMP格式保存到SD卡中
  82. *    形    参: p_arg 是在创建该任务时传递的形参
  83. *    返 回 值: 无
  84.      优 先 级: 3
  85. *********************************************************************************************************
  86. */
  87. static void AppTaskMsgPro(void *p_arg)
  88. {
  89.      uint32_t ulStart, ulEnd;
  90.      OS_ERR      err;
  91.      uint8_t       Pic_Name = 0;
  92.      char buf[20];
  93.      (void)p_arg;
  94.          
  95.      while(1)
  96.      {   
  97.           /* 等待获取信号量同步消息,接收到后执行串口打印 */
  98.          OSSemPend((OS_SEM *)&SEM_SYNCH,
  99.                      (OS_TICK )0,
  100.                      (OS_OPT  )OS_OPT_PEND_BLOCKING,
  101.                      (CPU_TS  )0,
  102.                      (OS_ERR *)&err);
  103.         
  104.          if(err == OS_ERR_NONE)
  105.          {   
  106.               sprintf(buf,"0:/PicSave/%d.bmp",Pic_Name);
  107.             
  108.               /* 记录截图前起始时间 */
  109.               ulStart = OSTimeGet(&err);
  110.             
  111.               /* 开启调度锁 */
  112.               OSSchedLock(&err);
  113.             
  114.               /* 如果SD卡中没有PicSave文件,会进行创建 */
  115.               result = f_mkdir("0:/PicSave");
  116.             
  117.               /* 创建截图 */
  118.               result = f_open(&file,buf, FA_WRITE|FA_CREATE_ALWAYS);
  119.             
  120.               /* 向SD卡绘制BMP图片 */
  121.               GUI_BMP_Serialize(_WriteByte2File, &file);
  122.             
  123.               /* 创建完成后关闭file */
  124.              result = f_close(&file);
  125.             
  126.               /* 开启调度锁 */
  127.               OSSchedUnlock(&err);
  128.             
  129.               /* 记录截图后时间并获取截图过程耗时 */
  130.               ulEnd = OSTimeGet(&err);
  131.               ulEnd -= ulStart;
  132.             
  133.               App_Printf("截图完成,耗时 = %dms\\r\\n", ulEnd);
  134.               Pic_Name++;      
  135.          }                                                                                                                  
  136.      }  
  137. }
  138. /*
  139. *********************************************************************************************************
  140. *    函 数 名: AppTaskUserIF
  141. *    功能说明: 按键消息处理
  142. *    形    参: p_arg 是在创建该任务时传递的形参
  143. *    返 回 值: 无
  144.      优 先 级: 4
  145. *********************************************************************************************************
  146. */
  147. static void AppTaskUserIF(void *p_arg)
  148. {
  149.      OS_ERR      err;
  150.      uint8_t  ucKeyCode;
  151.    
  152.      (void)p_arg;                /* 避免编译器报警 */
  153.    
  154.      while (1)
  155.      {      
  156.          ucKeyCode = bsp_GetKey();
  157.         
  158.          if (ucKeyCode != KEY_NONE)
  159.          {
  160.               switch (ucKeyCode)
  161.               {
  162.                    case KEY_DOWN_K1:             /* K1键按下 打印任务执行情况 */
  163.                        DispTaskInfo();        
  164.                        break;
  165.                   
  166.                    case KEY_DOWN_K2:             /* K2键按下 向消息队列发送数据 */
  167.                        OSSemPost((OS_SEM *)&SEM_SYNCH,
  168.                                   (OS_OPT  )OS_OPT_POST_1,
  169.                                   (OS_ERR *)&err);
  170.                        break;
  171.                   
  172.                    default:                     /* 其他的键值不处理 */
  173.                        break;
  174.               }
  175.          }
  176.         
  177.          OSTimeDly(20, OS_OPT_TIME_DLY, &err);
  178.      }
  179. }
  180. /*
  181. *********************************************************************************************************
  182. *    函 数 名: AppTaskCom
  183. *    功能说明: 暂未使用
  184. *    形    参: p_arg 是在创建该任务时传递的形参
  185. *    返 回 值: 无
  186.      优 先 级: 5
  187. *********************************************************************************************************
  188. */
  189. static void AppTaskCOM(void *p_arg)
  190. {
  191.      OS_ERR  err;      
  192.    
  193.      (void)p_arg;
  194.    
  195.      while(1)
  196.      {   
  197.          OSTimeDly(500, OS_OPT_TIME_DLY, &err);
  198.      }                                                                                                
  199. }
  200. /*
  201. *********************************************************************************************************
  202. *    函 数 名: AppTaskGUI
  203. *    功能说明: GUI任务,最低优先级                        
  204. *    形    参:p_arg 是在创建该任务时传递的形参
  205. *    返 回 值: 无
  206. *   优 先 级:OS_CFG_PRIO_MAX - 4u
  207. *********************************************************************************************************
  208. */
  209. static void AppTaskGUI(void *p_arg)
  210. {
  211.     (void)p_arg;       /* 避免编译器告警 */
  212.         
  213.      while (1)
  214.      {
  215.          MainTask();
  216.      }
  217. }
复制代码
emWin任务的具体实现(在MainTask.c文件里面):
  1. #include "MainTask.h"
  2. #include "includes.h"
  3. /*
  4. *********************************************************************************************************
  5. *                             添加到多页控件第一个页面窗口的对话框
  6. *********************************************************************************************************
  7. */
  8. /*
  9. *********************************************************************************************************
  10. *                                         宏定义
  11. *********************************************************************************************************
  12. */
  13. #define ID_WINDOW_01 (GUI_ID_USER + 0x10)
  14. #define ID_BUTTON_01 (GUI_ID_USER + 0x11)
  15. /*
  16. *********************************************************************************************************
  17. *                           GUI_WIDGET_CREATE_INFO类型数组
  18. *********************************************************************************************************
  19. */
  20. static const GUI_WIDGET_CREATE_INFO _aDialogCreatePage1[] =
  21. {
  22.      { WINDOW_CreateIndirect, "Window", ID_WINDOW_01, 0, 0, 400, 200, 0, 0x0, 0 },
  23.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_01, 127, 68, 129, 43, 0, 0x0, 0 },
  24. };
  25. /*
  26. *********************************************************************************************************
  27. *    函 数 名: _cbDialogPage1
  28. *    功能说明: 对话框回调函数        
  29. *    形    参: pMsg  回调参数
  30. *    返 回 值: 无
  31. *********************************************************************************************************
  32. */
  33. static void _cbDialogPage1(WM_MESSAGE * pMsg)
  34. {
  35.      WM_HWIN hItem;
  36.      int     NCode;
  37.      int     Id;
  38.      switch (pMsg->MsgId)
  39.      {
  40.          case WM_INIT_DIALOG:
  41.             
  42.               //
  43.               // 初始化按钮控件
  44.               //
  45.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_01);
  46.               BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
  47.               BUTTON_SetText(hItem, "LED1");
  48.               break;
  49.         
  50.          case WM_NOTIFY_PARENT:
  51.               Id    = WM_GetId(pMsg->hWinSrc);
  52.               NCode = pMsg->Data.v;
  53.               switch(Id)
  54.               {
  55.                    case ID_BUTTON_01:
  56.                    switch(NCode)
  57.                    {
  58.                        case WM_NOTIFICATION_CLICKED:
  59.                             bsp_LedToggle(1);
  60.                             break;
  61.                      
  62.                        case WM_NOTIFICATION_RELEASED:
  63.                             break;
  64.                    }
  65.                    break;
  66.               }
  67.               break;
  68.             
  69.          default:
  70.               WM_DefaultProc(pMsg);
  71.               break;
  72.      }
  73. }
  74. /*
  75. *********************************************************************************************************
  76. *    函 数 名: CreateWindowPage1
  77. *    功能说明: 创建对话框      
  78. *    形    参: 无
  79. *    返 回 值: 返回对话框句柄
  80. *********************************************************************************************************
  81. */
  82. WM_HWIN CreateWindowPage1(void)
  83. {
  84.      WM_HWIN hWin;
  85.      hWin = GUI_CreateDialogBox(_aDialogCreatePage1, GUI_COUNTOF(_aDialogCreatePage1), _cbDialogPage1,
  86. WM_HBKWIN, 0, 0);
  87.      return hWin;
  88. }
  89. /*
  90. *********************************************************************************************************
  91. *                             添加到多页控件第二个页面窗口的对话框
  92. *********************************************************************************************************
  93. */
  94. /*
  95. *********************************************************************************************************
  96. *                                         宏定义
  97. *********************************************************************************************************
  98. */
  99. #define ID_WINDOW_02 (GUI_ID_USER + 0x20)
  100. #define ID_BUTTON_02 (GUI_ID_USER + 0x21)
  101. /*
  102. *********************************************************************************************************
  103. *                           GUI_WIDGET_CREATE_INFO类型数组
  104. *********************************************************************************************************
  105. */
  106. static const GUI_WIDGET_CREATE_INFO _aDialogCreatePage2[] =
  107. {
  108.      { WINDOW_CreateIndirect, "Window", ID_WINDOW_02, 0, 0, 400, 200, 0, 0x0, 0 },
  109.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_02, 127, 68, 129, 43, 0, 0x0, 0 },
  110. };
  111. /*
  112. *********************************************************************************************************
  113. *    函 数 名: _cbDialogPage1
  114. *    功能说明: 对话框回调函数        
  115. *    形    参: pMsg  回调参数
  116. *    返 回 值: 无
  117. *********************************************************************************************************
  118. */
  119. static void _cbDialogPage2(WM_MESSAGE * pMsg)
  120. {
  121.      WM_HWIN hItem;
  122.      int     NCode;
  123.      int     Id;
  124.      switch (pMsg->MsgId)
  125.      {
  126.          case WM_INIT_DIALOG:
  127.             
  128.               //
  129.               // 初始化按钮控件
  130.               //
  131.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_02);
  132.               BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
  133.               BUTTON_SetText(hItem, "LED2");
  134.               break;
  135.         
  136.          case WM_NOTIFY_PARENT:
  137.               Id    = WM_GetId(pMsg->hWinSrc);
  138.               NCode = pMsg->Data.v;
  139.               switch(Id)
  140.               {
  141.                    case ID_BUTTON_02:
  142.                    switch(NCode)
  143.                    {
  144.                        case WM_NOTIFICATION_CLICKED:
  145.                             bsp_LedToggle(2);
  146.                             break;
  147.                      
  148.                        case WM_NOTIFICATION_RELEASED:
  149.                             break;
  150.                    }
  151.                    break;
  152.               }
  153.               break;
  154.             
  155.          default:
  156.               WM_DefaultProc(pMsg);
  157.               break;
  158.      }
  159. }
  160. /*
  161. *********************************************************************************************************
  162. *    函 数 名: CreateWindowPage2
  163. *    功能说明: 创建对话框      
  164. *    形    参: 无
  165. *    返 回 值: 返回对话框句柄
  166. *********************************************************************************************************
  167. */
  168. WM_HWIN CreateWindowPage2(void)
  169. {
  170.      WM_HWIN hWin;
  171.      hWin = GUI_CreateDialogBox(_aDialogCreatePage2, GUI_COUNTOF(_aDialogCreatePage2), _cbDialogPage2,
  172. WM_HBKWIN, 0, 0);
  173.      return hWin;
  174. }
  175. /*
  176. *********************************************************************************************************
  177. *                             添加到多页控件第三个页面窗口的对话框
  178. *********************************************************************************************************
  179. */
  180. /*
  181. *********************************************************************************************************
  182. *                                         宏定义
  183. *********************************************************************************************************
  184. */
  185. #define ID_WINDOW_03 (GUI_ID_USER + 0x30)
  186. #define ID_BUTTON_03 (GUI_ID_USER + 0x31)
  187. /*
  188. *********************************************************************************************************
  189. *                           GUI_WIDGET_CREATE_INFO类型数组
  190. *********************************************************************************************************
  191. */
  192. static const GUI_WIDGET_CREATE_INFO _aDialogCreatePage3[] =
  193. {
  194.      { WINDOW_CreateIndirect, "Window", ID_WINDOW_03, 0, 0, 400, 200, 0, 0x0, 0 },
  195.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_03, 127, 68, 129, 43, 0, 0x0, 0 },
  196. };
  197. /*
  198. *********************************************************************************************************
  199. *    函 数 名: _cbDialogPage3
  200. *    功能说明: 对话框回调函数        
  201. *    形    参: pMsg  回调参数
  202. *    返 回 值: 无
  203. *********************************************************************************************************
  204. */
  205. static void _cbDialogPage3(WM_MESSAGE * pMsg)
  206. {
  207.      WM_HWIN hItem;
  208.      int     NCode;
  209.      int     Id;
  210.      switch (pMsg->MsgId)
  211.      {
  212.          case WM_INIT_DIALOG:
  213.             
  214.               //
  215.               // 初始化按钮控件
  216.               //
  217.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_03);
  218.               BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
  219.               BUTTON_SetText(hItem, "LED3");
  220.               break;
  221.         
  222.          case WM_NOTIFY_PARENT:
  223.               Id    = WM_GetId(pMsg->hWinSrc);
  224.               NCode = pMsg->Data.v;
  225.               switch(Id)
  226.               {
  227.                    case ID_BUTTON_03:
  228.                    switch(NCode)
  229.                    {
  230.                        case WM_NOTIFICATION_CLICKED:
  231.                             bsp_LedToggle(3);
  232.                             break;
  233.                      
  234.                        case WM_NOTIFICATION_RELEASED:
  235.                             break;
  236.                    }
  237.                    break;
  238.               }
  239.               break;
  240.             
  241.          default:
  242.               WM_DefaultProc(pMsg);
  243.               break;
  244.      }
  245. }
  246. /*
  247. *********************************************************************************************************
  248. *    函 数 名: CreateWindowPage3
  249. *    功能说明: 创建对话框      
  250. *    形    参: 无
  251. *    返 回 值: 返回对话框句柄
  252. *********************************************************************************************************
  253. */
  254. WM_HWIN CreateWindowPage3(void)
  255. {
  256.      WM_HWIN hWin;
  257.      hWin = GUI_CreateDialogBox(_aDialogCreatePage3, GUI_COUNTOF(_aDialogCreatePage3), _cbDialogPage3,
  258. WM_HBKWIN, 0, 0);
  259.      return hWin;
  260. }
  261. /*
  262. *********************************************************************************************************
  263. *                                         宏定义
  264. *********************************************************************************************************
  265. */
  266. #define ID_FRAMEWIN_0  (GUI_ID_USER + 0x00)
  267. #define ID_MULTIPAGE_0 (GUI_ID_USER + 0x01)
  268. /*
  269. *********************************************************************************************************
  270. *                           GUI_WIDGET_CREATE_INFO类型数组
  271. *********************************************************************************************************
  272. */
  273. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
  274. {
  275.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x0, 0 },
  276.      { MULTIPAGE_CreateIndirect, "Multipage", ID_MULTIPAGE_0, 23, 25, 400, 240, 0, 0x0, 0 },
  277. };
  278. /*
  279. *********************************************************************************************************
  280. *    函 数 名: _cbDialog
  281. *    功能说明: 对话框回调函数        
  282. *    形    参: pMsg  回调参数
  283. *    返 回 值: 无
  284. *********************************************************************************************************
  285. */
  286. static void _cbDialog(WM_MESSAGE * pMsg)
  287. {
  288.      WM_HWIN hItem;
  289.      WM_HWIN hWinPage;
  290.      int     NCode;
  291.      int     Id;
  292.      switch (pMsg->MsgId)
  293.      {
  294.          case WM_INIT_DIALOG:
  295.             
  296.               //
  297.               // 初始化框架窗口
  298.               //
  299.               hItem = pMsg->hWin;
  300.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  301. FRAMEWIN_SetText(hItem, "armfly")
  302.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  303.         
  304.               //
  305.               // 初始化多页控件
  306.               //
  307.               hItem = WM_GetDialogItem(pMsg->hWin, ID_MULTIPAGE_0);
  308.               MULTIPAGE_SetFont(hItem, GUI_FONT_16_ASCII);
  309.               hWinPage = CreateWindowPage1();
  310.               MULTIPAGE_AddEmptyPage(hItem, hWinPage, "STM32-V4");
  311.               hWinPage = CreateWindowPage2();
  312.               MULTIPAGE_AddEmptyPage(hItem, hWinPage, "STM32-V5");
  313.               hWinPage = CreateWindowPage3();
  314.               MULTIPAGE_AddEmptyPage(hItem, hWinPage, "STM32-V6");
  315.               break;
  316.         
  317.          case WM_NOTIFY_PARENT:
  318.               Id    = WM_GetId(pMsg->hWinSrc);
  319.               NCode = pMsg->Data.v;
  320.               switch(Id)
  321.               {
  322.                    case ID_MULTIPAGE_0:
  323.                    switch(NCode)
  324.                    {
  325.                        case WM_NOTIFICATION_CLICKED:
  326.                             break;
  327.                      
  328.                        case WM_NOTIFICATION_RELEASED:
  329.                             break;
  330.                      
  331.                        case WM_NOTIFICATION_MOVED_OUT:
  332.                             break;
  333.                      
  334.                        case WM_NOTIFICATION_VALUE_CHANGED:
  335.                             break;
  336.                    }
  337.                   break;
  338.               }
  339.               break;
  340.             
  341.          default:
  342.               WM_DefaultProc(pMsg);
  343.               break;
  344.      }
  345. }
  346. /*
  347. *********************************************************************************************************
  348. *    函 数 名: CreateFramewin
  349. *    功能说明: 创建对话框      
  350. *    形    参: 无
  351. *    返 回 值: 返回对话框句柄
  352. *********************************************************************************************************
  353. */
  354. WM_HWIN CreateFramewin(void)
  355. {
  356.      WM_HWIN hWin;
  357.      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  358.      return hWin;
  359. }
  360. /*
  361. *********************************************************************************************************
  362. *    函 数 名: MainTask
  363. *    功能说明: GUI主函数
  364. *    形    参: 无
  365. *    返 回 值: 无
  366. *********************************************************************************************************
  367. */
  368. void MainTask(void)
  369. {
  370.    
  371.      /* 初始化 */
  372.      GUI_Init();
  373.    
  374.      /*
  375.       关于多缓冲和窗口内存设备的设置说明
  376.         1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
  377.            WM_MULTIBUF_Enable(1);
  378.         2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
  379.         3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
  380.            STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
  381.            感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
  382.         4. 所有emWin例子默认是开启三缓冲。
  383.      */
  384.      WM_MULTIBUF_Enable(1);
  385.    
  386.      /*
  387.        触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
  388.         此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
  389.      */
  390.     //TOUCH_Calibration();
  391.    
  392.      /* 创建对话框 */
  393.      CreateFramewin();
  394.         
  395.      while(1)
  396.      {
  397.          GUI_Delay(50);
  398.      }
  399. }
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-13 16:56:11 | 显示全部楼层
55.6 实验例程说明(裸机)


配套例子:
        V6-580_STemWin实验_MultiPage多页控件(裸机)
实验目的:
        1.     本实验主要学习多行文本控件的使用。
        2.     emWin功能的实现在MainTask.c文件里面。
实验内容:
        1.     GUI任务主要在对话框上面创建了一个多页控件,控件上创建了三个页面窗口,每个页面窗口,添加了一个对话框。
并且为每个对话框上面都添加了按钮控件,点击按钮控件实现LED的亮灭反转,三个对话框上的按钮控件分别控制的是LED1,LED2和LED3。
STemWin界面显示效果:
        800*480分辨率界面效果。
55.27.png


STemWin动态内存配置:
GUIConf.c文件中的配置如下:
  1. #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
  2. #if EX_SRAM
  3. #define GUI_NUMBYTES  (1024*1024*8)
  4. #else
  5. #define GUI_NUMBYTES  (100*1024)
  6. #endif
复制代码
        通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:
#define EX_SRAM    1 表示使用外部SDRAM作为emWin动态内存,大小8MB。
#define EX_SRAM    0 表示使用内部SRAM作为emWin动态内存,大小100KB。
默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。
STemWin底层接口配置:
        LCDConf_Lin_Template.c文件中共12项emWin配置:
  1. /*
  2. **********************************************************************************************************
  3.                                           用户可以配置的选项
  4. **********************************************************************************************************
  5. */
  6. /* 0. 在官方代码的基础上再做优化,官方的部分函数效率低,耗内存, 0表示优化 */
  7. #define emWin_Optimize   0
  8. /*
  9.   1. 显示屏的物理分辨率,驱动已经做了显示屏自适应,支持4.3寸,5寸和7寸屏
  10.      这里填写自适应显示屏中的最大分辨率。
  11. */
  12. #define XSIZE_PHYS       800
  13. #define YSIZE_PHYS       480
  14. /* 2. 多缓冲 / 虚拟屏,多缓冲和虚拟屏不可同时使用,emWin不支持 */
  15. #define NUM_BUFFERS      3 /* 定义多缓冲个数,仅可以设置1,2和3,也就是最大支持三缓冲 */
  16. #define NUM_VSCREENS     1 /* 定义虚拟屏个数 */
  17. /* 3. 没有图层激活时,背景色设置, 暂时未用到 */
  18. #define BK_COLOR         GUI_DARKBLUE
  19. /*
  20.    4. 重定义图层数,对于STM32F429/439,用户可以选择一个图层或者两个图层,不支持三图层
  21.       (1). 设置GUI_NUM_LAYERS = 1时,即仅使用图层1时,默认触摸值是发送给图层1的。
  22.        (2). 设置GUI_NUM_LAYERS = 2时,即图层1和图层2都已经使能,此时图层2是顶层,
  23.             用户需要根据自己的使用情况设置如下两个地方。
  24.             a. 在bsp_touch.c文件中的函数TOUCH_InitHard里面设置参数State.Layer = 1,1就表示
  25.                给图层2发送触摸值。
  26.             b. 调用GUI_Init函数后,调用函数GUI_SelectLayer(1), 设置当前操作的是图层2。
  27. */
  28. #undef  GUI_NUM_LAYERS
  29. #define GUI_NUM_LAYERS    1
  30. /*
  31.    5. 设置图层1和图层2对应的显存地址
  32.       (1) EXT_SDRAM_ADDR 是SDRAM的首地址。
  33.       (2) LCD_LAYER0_FRAME_BUFFER 是图层1的显存地址。
  34.        (3) LCD_LAYER1_FRAME_BUFFER 是图层2的显存地址。
  35.        (4) 每个图层的显存大小比较考究,这里进行下简单的说明。
  36.            如果用户选择的颜色模式 = 32位色ARGB8888,显存的大小:
  37.            XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS * NUM_BUFFERS
  38.          
  39.            颜色模式 = 24位色RGB888,显存的大小:
  40.            XSIZE_PHYS * YSIZE_PHYS * 3 * NUM_VSCREENS * NUM_BUFFERS
  41.          
  42.            颜色模式 = 16位色RGB566,ARGB1555, ARGB4444,AL88,那么显存的大小就是:
  43.            XSIZE_PHYS * YSIZE_PHYS * 2 * NUM_VSCREENS * NUM_BUFFERS
  44.            颜色模式 = 8位色L8,AL44,那么显存的大小就是:
  45.            XSIZE_PHYS * YSIZE_PHYS * 1 * NUM_VSCREENS * NUM_BUFFERS  
  46.      
  47.       这里为了方便起见,将开发板配套的16MB的SDRAM前8MB分配给LCD显存使用,后8MB用于emWin动态内存。
  48.        对于24位色,16位色,8位色,用户可以对其使能三缓冲,并且使能双图层。但是32位色也使能三缓冲和双
  49.        图层的话会超出8MB,所以用户根据自己的情况做显存和emWin动态内存的分配调整。
  50.          举一个例子,对于800*480分辨率的显示屏,使能32位色,三缓冲,那么最终一个图层需要的大小就是
  51.       800 * 480 * 4 * 3  = 4.394MB的空间,如果是双图层,已经超出8MB的分配范围。
  52.      
  53.       (5)为了方便起见,图层2的宏定义LCD_LAYER1_FRAME_BUFFER中的参数4是按照32位色设置的,如果用户的图层1
  54.          使用的是8位色,这里填数字1,如果是16位色,这里填2,如果是24位色,这里填3。
  55. */
  56. #define LCD_LAYER0_FRAME_BUFFER  EXT_SDRAM_ADDR
  57. #define LCD_LAYER1_FRAME_BUFFER  (LCD_LAYER0_FRAME_BUFFER + XSIZE_PHYS * YSIZE_PHYS * 4 * NUM_VSCREENS *
  58. NUM_BUFFERS)
  59. /*
  60.    6. STM32F429/439支持的颜色模式,所有模式都支持,用户可任意配置。
  61.       特别注意如下两个问题:
  62.        (1) 如果用户选择了ARGB8888或者RGB888模式,LCD闪烁比较厉害的话,
  63.            请降低LTDC的时钟大小,在文件bsp_tft_429.c的函数LCD_ConfigLTDC里面设置。
  64.            a. 一般800*480分辨率的显示屏,ARGB8888或者RGB888模式LTDC时钟选择10-20MHz即可。
  65.            b. 480*272分辨率的可以高些,取20MHz左右即可。
  66.        (2) 16位色或者8位色模式,LTDC的时钟频率一般可以比24位色或者32位色的高一倍。
  67. */
  68. #define _CM_ARGB8888      1
  69. #define _CM_RGB888        2
  70. #define _CM_RGB565        3
  71. #define _CM_ARGB1555      4
  72. #define _CM_ARGB4444      5
  73. #define _CM_L8            6
  74. #define _CM_AL44          7
  75. #define _CM_AL88          8
  76. /* 7. 配置图层1的颜色模式和分辨率大小 */
  77. #define COLOR_MODE_0      _CM_RGB565
  78. #define XSIZE_0           XSIZE_PHYS
  79. #define YSIZE_0           YSIZE_PHYS
  80. /* 8. 配置图层2的的颜色模式和分辨率大小 */
  81. #define COLOR_MODE_1      _CM_RGB565
  82. #define XSIZE_1           XSIZE_PHYS
  83. #define YSIZE_1           YSIZE_PHYS
  84. /* 9. 单图层情况下,根据用户选择的颜色模式可自动选择图层1的emWin的驱动和颜色模式 */
  85. #if   (COLOR_MODE_0 == _CM_ARGB8888)
  86.   #define COLOR_CONVERSION_0 GUICC_M8888I
  87.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_32
  88. #elif (COLOR_MODE_0 == _CM_RGB888)
  89.   #define COLOR_CONVERSION_0 GUICC_M888
  90.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_24
  91. #elif (COLOR_MODE_0 == _CM_RGB565)
  92.   #define COLOR_CONVERSION_0 GUICC_M565
  93.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  94. #elif (COLOR_MODE_0 == _CM_ARGB1555)
  95.   #define COLOR_CONVERSION_0 GUICC_M1555I
  96.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  97. #elif (COLOR_MODE_0 == _CM_ARGB4444)
  98.   #define COLOR_CONVERSION_0 GUICC_M4444I
  99.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  100. #elif (COLOR_MODE_0 == _CM_L8)
  101.   #define COLOR_CONVERSION_0 GUICC_8666
  102.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  103. #elif (COLOR_MODE_0 == _CM_AL44)
  104.   #define COLOR_CONVERSION_0 GUICC_1616I
  105.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_8
  106. #elif (COLOR_MODE_0 == _CM_AL88)
  107.   #define COLOR_CONVERSION_0 GUICC_88666I
  108.   #define DISPLAY_DRIVER_0   GUIDRV_LIN_16
  109. #else
  110.   #error Illegal color mode 0!
  111. #endif
  112. /* 10. 双图层情况下,根据用户选择的颜色模式可自动选择图层2的emWin的驱动和颜色模式 */
  113. #if (GUI_NUM_LAYERS > 1)
  114. #if   (COLOR_MODE_1 == _CM_ARGB8888)
  115.   #define COLOR_CONVERSION_1 GUICC_M8888I
  116.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_32
  117. #elif (COLOR_MODE_1 == _CM_RGB888)
  118.   #define COLOR_CONVERSION_1 GUICC_M888
  119.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_24
  120. #elif (COLOR_MODE_1 == _CM_RGB565)
  121.   #define COLOR_CONVERSION_1 GUICC_M565
  122.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  123. #elif (COLOR_MODE_1 == _CM_ARGB1555)
  124.   #define COLOR_CONVERSION_1 GUICC_M1555I
  125.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  126. #elif (COLOR_MODE_1 == _CM_ARGB4444)
  127.   #define COLOR_CONVERSION_1 GUICC_M4444I
  128.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  129. #elif (COLOR_MODE_1 == _CM_L8)
  130.   #define COLOR_CONVERSION_1 GUICC_8666
  131.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  132. #elif (COLOR_MODE_1 == _CM_AL44)
  133.   #define COLOR_CONVERSION_1 GUICC_1616I
  134.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_8
  135. #elif (COLOR_MODE_1 == _CM_AL88)
  136.   #define COLOR_CONVERSION_1 GUICC_88666I
  137.   #define DISPLAY_DRIVER_1   GUIDRV_LIN_16
  138. #else
  139.   #error Illegal color mode 1!
  140. #endif
  141. #else
  142. #undef XSIZE_0
  143. #undef YSIZE_0
  144. #define XSIZE_0       XSIZE_PHYS
  145. #define YSIZE_0       YSIZE_PHYS
  146. #endif
  147. /*11. 配置选项检测,防止配置错误或者某些选项没有配置 */
  148. #ifndef   XSIZE_PHYS
  149.   #error Physical X size of display is not defined!
  150. #endif
  151. #ifndef   YSIZE_PHYS
  152.   #error Physical Y size of display is not defined!
  153. #endif
  154. #ifndef   NUM_VSCREENS
  155.   #define NUM_VSCREENS 1
  156. #else
  157.   #if (NUM_VSCREENS <= 0)
  158.     #error At least one screeen needs to be defined!
  159.   #endif
  160. #endif
  161. #if (NUM_VSCREENS > 1) && (NUM_BUFFERS > 1)
  162.   #error Virtual screens and multiple buffers are not allowed!
  163. #endif
复制代码
        对于这12个配置选项,注释说明已经比较详细。默认情况下,本教程配套的emWin例子都是用的三缓冲,RGB565格式,且仅使用单图层。
程序设计:
栈大小分配:
         系统栈大小在startup_stm32f429_439xx.s文件中配置:
55.28.png

        栈大小的单位是字节,那么这里配置系统栈大小为8192字节。
主函数初始化:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: 标准c程序入口。
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. int main (void)
  10. {   
  11.      /* 初始化外设 */
  12.      bsp_Init();
  13.      /* 进入emWin主函数 */
  14.      MainTask();
  15. }
复制代码
硬件外设初始化
        硬件外设的初始化是在bsp.c文件实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: bsp_Init
  4. *    功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
  5. *    形    参:无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void bsp_Init(void)
  10. {
  11.      /*
  12.          由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
  13.          启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
  14.          系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
  15.      */
  16.      /* 使能CRC 因为使用STemWin前必须要使能 */
  17.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
  18.    
  19.      /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
  20.      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
  21.    
  22.      SystemCoreClockUpdate();    /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
  23.      bsp_InitUart();        /* 初始化串口 */
  24.      bsp_InitKey();         /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
  25.    
  26.      bsp_InitExtIO();       /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */
  27.      bsp_InitLed();         /* 初始LED指示灯端口 */
  28.    
  29.      bsp_InitI2C();         /* 配置I2C总线 */
  30.      bsp_InitSPIBus();       /* 配置SPI总线 */
  31.    
  32.      bsp_InitSFlash();       /* 初始化SPI Flash */
  33.    
  34.      bsp_InitExtSDRAM();   /* 初始化SDRAM */
  35.      bsp_DetectLcdType();  /* 检测触摸板和LCD面板型号, 结果存在全局变量 g_TouchType, g_LcdType */
  36.    
  37.      TOUCH_InitHard();    /* 初始化配置触摸芯片 */
  38.      LCD_ConfigLTDC();     /* 初始化配置LTDC */
  39.    
  40.      result = f_mount(&fs, "0:/", 0);     /* 挂载文件系统 */
  41. }
复制代码
emWin功能的具体实现(在MainTask.c文件里面):
  1. #include "MainTask.h"
  2. #include "bsp.h"
  3. /*
  4. *********************************************************************************************************
  5. *                             添加到多页控件第一个页面窗口的对话框
  6. *********************************************************************************************************
  7. */
  8. /*
  9. *********************************************************************************************************
  10. *                                         宏定义
  11. *********************************************************************************************************
  12. */
  13. #define ID_WINDOW_01 (GUI_ID_USER + 0x10)
  14. #define ID_BUTTON_01 (GUI_ID_USER + 0x11)
  15. /*
  16. *********************************************************************************************************
  17. *                           GUI_WIDGET_CREATE_INFO类型数组
  18. *********************************************************************************************************
  19. */
  20. static const GUI_WIDGET_CREATE_INFO _aDialogCreatePage1[] =
  21. {
  22.      { WINDOW_CreateIndirect, "Window", ID_WINDOW_01, 0, 0, 400, 200, 0, 0x0, 0 },
  23.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_01, 127, 68, 129, 43, 0, 0x0, 0 },
  24. };
  25. /*
  26. *********************************************************************************************************
  27. *    函 数 名: _cbDialogPage1
  28. *    功能说明: 对话框回调函数        
  29. *    形    参: pMsg  回调参数
  30. *    返 回 值: 无
  31. *********************************************************************************************************
  32. */
  33. static void _cbDialogPage1(WM_MESSAGE * pMsg)
  34. {
  35.      WM_HWIN hItem;
  36.      int     NCode;
  37.      int     Id;
  38.      switch (pMsg->MsgId)
  39.      {
  40.          case WM_INIT_DIALOG:
  41.             
  42.               //
  43.               // 初始化按钮控件
  44.               //
  45.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_01);
  46.               BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
  47.               BUTTON_SetText(hItem, "LED1");
  48.               break;
  49.         
  50.          case WM_NOTIFY_PARENT:
  51.               Id    = WM_GetId(pMsg->hWinSrc);
  52.               NCode = pMsg->Data.v;
  53.               switch(Id)
  54.               {
  55.                    case ID_BUTTON_01:
  56.                    switch(NCode)
  57.                    {
  58.                        case WM_NOTIFICATION_CLICKED:
  59.                             bsp_LedToggle(1);
  60.                             break;
  61.                      
  62.                        case WM_NOTIFICATION_RELEASED:
  63.                             break;
  64.                    }
  65.                    break;
  66.               }
  67.               break;
  68.             
  69.          default:
  70.               WM_DefaultProc(pMsg);
  71.               break;
  72.      }
  73. }
  74. /*
  75. *********************************************************************************************************
  76. *    函 数 名: CreateWindowPage1
  77. *    功能说明: 创建对话框      
  78. *    形    参: 无
  79. *    返 回 值: 返回对话框句柄
  80. *********************************************************************************************************
  81. */
  82. WM_HWIN CreateWindowPage1(void)
  83. {
  84.      WM_HWIN hWin;
  85.      hWin = GUI_CreateDialogBox(_aDialogCreatePage1, GUI_COUNTOF(_aDialogCreatePage1), _cbDialogPage1,
  86. WM_HBKWIN, 0, 0);
  87.      return hWin;
  88. }
  89. /*
  90. *********************************************************************************************************
  91. *                             添加到多页控件第二个页面窗口的对话框
  92. *********************************************************************************************************
  93. */
  94. /*
  95. *********************************************************************************************************
  96. *                                         宏定义
  97. *********************************************************************************************************
  98. */
  99. #define ID_WINDOW_02 (GUI_ID_USER + 0x20)
  100. #define ID_BUTTON_02 (GUI_ID_USER + 0x21)
  101. /*
  102. *********************************************************************************************************
  103. *                           GUI_WIDGET_CREATE_INFO类型数组
  104. *********************************************************************************************************
  105. */
  106. static const GUI_WIDGET_CREATE_INFO _aDialogCreatePage2[] =
  107. {
  108.      { WINDOW_CreateIndirect, "Window", ID_WINDOW_02, 0, 0, 400, 200, 0, 0x0, 0 },
  109.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_02, 127, 68, 129, 43, 0, 0x0, 0 },
  110. };
  111. /*
  112. *********************************************************************************************************
  113. *    函 数 名: _cbDialogPage1
  114. *    功能说明: 对话框回调函数        
  115. *    形    参: pMsg  回调参数
  116. *    返 回 值: 无
  117. *********************************************************************************************************
  118. */
  119. static void _cbDialogPage2(WM_MESSAGE * pMsg)
  120. {
  121.      WM_HWIN hItem;
  122.      int     NCode;
  123.      int     Id;
  124.      switch (pMsg->MsgId)
  125.      {
  126.          case WM_INIT_DIALOG:
  127.             
  128.               //
  129.               // 初始化按钮控件
  130.               //
  131.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_02);
  132.               BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
  133.               BUTTON_SetText(hItem, "LED2");
  134.               break;
  135.         
  136.          case WM_NOTIFY_PARENT:
  137.               Id    = WM_GetId(pMsg->hWinSrc);
  138.               NCode = pMsg->Data.v;
  139.               switch(Id)
  140.               {
  141.                    case ID_BUTTON_02:
  142.                    switch(NCode)
  143.                    {
  144.                        case WM_NOTIFICATION_CLICKED:
  145.                             bsp_LedToggle(2);
  146.                             break;
  147.                      
  148.                        case WM_NOTIFICATION_RELEASED:
  149.                             break;
  150.                    }
  151.                    break;
  152.               }
  153.               break;
  154.             
  155.          default:
  156.               WM_DefaultProc(pMsg);
  157.               break;
  158.      }
  159. }
  160. /*
  161. *********************************************************************************************************
  162. *    函 数 名: CreateWindowPage2
  163. *    功能说明: 创建对话框      
  164. *    形    参: 无
  165. *    返 回 值: 返回对话框句柄
  166. *********************************************************************************************************
  167. */
  168. WM_HWIN CreateWindowPage2(void)
  169. {
  170.      WM_HWIN hWin;
  171.      hWin = GUI_CreateDialogBox(_aDialogCreatePage2, GUI_COUNTOF(_aDialogCreatePage2), _cbDialogPage2,
  172. WM_HBKWIN, 0, 0);
  173.      return hWin;
  174. }
  175. /*
  176. *********************************************************************************************************
  177. *                             添加到多页控件第三个页面窗口的对话框
  178. *********************************************************************************************************
  179. */
  180. /*
  181. *********************************************************************************************************
  182. *                                         宏定义
  183. *********************************************************************************************************
  184. */
  185. #define ID_WINDOW_03 (GUI_ID_USER + 0x30)
  186. #define ID_BUTTON_03 (GUI_ID_USER + 0x31)
  187. /*
  188. *********************************************************************************************************
  189. *                           GUI_WIDGET_CREATE_INFO类型数组
  190. *********************************************************************************************************
  191. */
  192. static const GUI_WIDGET_CREATE_INFO _aDialogCreatePage3[] =
  193. {
  194.      { WINDOW_CreateIndirect, "Window", ID_WINDOW_03, 0, 0, 400, 200, 0, 0x0, 0 },
  195.      { BUTTON_CreateIndirect, "Button", ID_BUTTON_03, 127, 68, 129, 43, 0, 0x0, 0 },
  196. };
  197. /*
  198. *********************************************************************************************************
  199. *    函 数 名: _cbDialogPage3
  200. *    功能说明: 对话框回调函数        
  201. *    形    参: pMsg  回调参数
  202. *    返 回 值: 无
  203. *********************************************************************************************************
  204. */
  205. static void _cbDialogPage3(WM_MESSAGE * pMsg)
  206. {
  207.      WM_HWIN hItem;
  208.      int     NCode;
  209.      int     Id;
  210.      switch (pMsg->MsgId)
  211.      {
  212.          case WM_INIT_DIALOG:
  213.             
  214.               //
  215.               // 初始化按钮控件
  216.               //
  217.               hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_03);
  218.               BUTTON_SetFont(hItem, GUI_FONT_16B_ASCII);
  219.               BUTTON_SetText(hItem, "LED3");
  220.               break;
  221.         
  222.          case WM_NOTIFY_PARENT:
  223.               Id    = WM_GetId(pMsg->hWinSrc);
  224.               NCode = pMsg->Data.v;
  225.               switch(Id)
  226.               {
  227.                    case ID_BUTTON_03:
  228.                    switch(NCode)
  229.                    {
  230.                        case WM_NOTIFICATION_CLICKED:
  231.                             bsp_LedToggle(3);
  232.                             break;
  233.                      
  234.                        case WM_NOTIFICATION_RELEASED:
  235.                             break;
  236.                    }
  237.                    break;
  238.               }
  239.               break;
  240.             
  241.          default:
  242.               WM_DefaultProc(pMsg);
  243.               break;
  244.      }
  245. }
  246. /*
  247. *********************************************************************************************************
  248. *    函 数 名: CreateWindowPage3
  249. *    功能说明: 创建对话框      
  250. *    形    参: 无
  251. *    返 回 值: 返回对话框句柄
  252. *********************************************************************************************************
  253. */
  254. WM_HWIN CreateWindowPage3(void)
  255. {
  256.      WM_HWIN hWin;
  257.      hWin = GUI_CreateDialogBox(_aDialogCreatePage3, GUI_COUNTOF(_aDialogCreatePage3), _cbDialogPage3,
  258. WM_HBKWIN, 0, 0);
  259.      return hWin;
  260. }
  261. /*
  262. *********************************************************************************************************
  263. *                                         宏定义
  264. *********************************************************************************************************
  265. */
  266. #define ID_FRAMEWIN_0  (GUI_ID_USER + 0x00)
  267. #define ID_MULTIPAGE_0 (GUI_ID_USER + 0x01)
  268. /*
  269. *********************************************************************************************************
  270. *                           GUI_WIDGET_CREATE_INFO类型数组
  271. *********************************************************************************************************
  272. */
  273. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
  274. {
  275.      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x0, 0 },
  276.      { MULTIPAGE_CreateIndirect, "Multipage", ID_MULTIPAGE_0, 23, 25, 400, 240, 0, 0x0, 0 },
  277. };
  278. /*
  279. *********************************************************************************************************
  280. *    函 数 名: _cbDialog
  281. *    功能说明: 对话框回调函数        
  282. *    形    参: pMsg  回调参数
  283. *    返 回 值: 无
  284. *********************************************************************************************************
  285. */
  286. static void _cbDialog(WM_MESSAGE * pMsg)
  287. {
  288.      WM_HWIN hItem;
  289.      WM_HWIN hWinPage;
  290.      int     NCode;
  291.      int     Id;
  292.      switch (pMsg->MsgId)
  293.      {
  294.          case WM_INIT_DIALOG:
  295.             
  296.               //
  297.               // 初始化框架窗口
  298.               //
  299.               hItem = pMsg->hWin;
  300.               FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII);
  301. FRAMEWIN_SetText(hItem, "armfly")
  302.               FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
  303.         
  304.               //
  305.               // 初始化多页控件
  306.               //
  307.               hItem = WM_GetDialogItem(pMsg->hWin, ID_MULTIPAGE_0);
  308.               MULTIPAGE_SetFont(hItem, GUI_FONT_16_ASCII);
  309.               hWinPage = CreateWindowPage1();
  310.               MULTIPAGE_AddEmptyPage(hItem, hWinPage, "STM32-V4");
  311.               hWinPage = CreateWindowPage2();
  312.               MULTIPAGE_AddEmptyPage(hItem, hWinPage, "STM32-V5");
  313.               hWinPage = CreateWindowPage3();
  314.               MULTIPAGE_AddEmptyPage(hItem, hWinPage, "STM32-V6");
  315.               break;
  316.         
  317.          case WM_NOTIFY_PARENT:
  318.               Id    = WM_GetId(pMsg->hWinSrc);
  319.               NCode = pMsg->Data.v;
  320.               switch(Id)
  321.               {
  322.                    case ID_MULTIPAGE_0:
  323.                    switch(NCode)
  324.                    {
  325.                        case WM_NOTIFICATION_CLICKED:
  326.                             break;
  327.                      
  328.                        case WM_NOTIFICATION_RELEASED:
  329.                             break;
  330.                      
  331.                        case WM_NOTIFICATION_MOVED_OUT:
  332.                             break;
  333.                      
  334.                        case WM_NOTIFICATION_VALUE_CHANGED:
  335.                             break;
  336.                    }
  337.                   break;
  338.               }
  339.               break;
  340.             
  341.          default:
  342.               WM_DefaultProc(pMsg);
  343.               break;
  344.      }
  345. }
  346. /*
  347. *********************************************************************************************************
  348. *    函 数 名: CreateFramewin
  349. *    功能说明: 创建对话框      
  350. *    形    参: 无
  351. *    返 回 值: 返回对话框句柄
  352. *********************************************************************************************************
  353. */
  354. WM_HWIN CreateFramewin(void)
  355. {
  356.      WM_HWIN hWin;
  357.      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  358.      return hWin;
  359. }
  360. /*
  361. *********************************************************************************************************
  362. *    函 数 名: MainTask
  363. *    功能说明: GUI主函数
  364. *    形    参: 无
  365. *    返 回 值: 无
  366. *********************************************************************************************************
  367. */
  368. void MainTask(void)
  369. {
  370.    
  371.      /* 初始化 */
  372.      GUI_Init();
  373.    
  374.      /*
  375.       关于多缓冲和窗口内存设备的设置说明
  376.         1. 使能多缓冲是调用的如下函数,用户要在LCDConf_Lin_Template.c文件中配置了多缓冲,调用此函数才有效:
  377.            WM_MULTIBUF_Enable(1);
  378.         2. 窗口使能使用内存设备是调用函数:WM_SetCreateFlags(WM_CF_MEMDEV);
  379.         3. 如果emWin的配置多缓冲和窗口内存设备都支持,二选一即可,且务必优先选择使用多缓冲,实际使用
  380.            STM32F429BIT6 + 32位SDRAM + RGB565/RGB888平台测试,多缓冲可以有效的降低窗口移动或者滑动时的撕裂
  381.            感,并有效的提高流畅性,通过使能窗口使用内存设备是做不到的。
  382.         4. 所有emWin例子默认是开启三缓冲。
  383.      */
  384.      WM_MULTIBUF_Enable(1);
  385.    
  386.      /*
  387.        触摸校准函数默认是注释掉的,电阻屏需要校准,电容屏无需校准。如果用户需要校准电阻屏的话,执行
  388.         此函数即可,会将触摸校准参数保存到EEPROM里面,以后系统上电会自动从EEPROM里面加载。
  389.      */
  390.     //TOUCH_Calibration();
  391.    
  392.      /* 创建对话框 */
  393.      CreateFramewin();
  394.         
  395.      while(1)
  396.      {
  397.          GUI_Delay(50);
  398.    
  399. }
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-3-13 16:56:39 | 显示全部楼层
55.7 总结


        本期教程主要是跟大家讲解了多页控件的基础知识。多页控件在实际项目中也比较实用,希望大家可以把本期教程
中讲的例子运行下,然后自己设计一个相关的例子进行试验学习。教程中只是使用了部分的多页控件API,其它的API大家都可以试试。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-30 02:49 , Processed in 0.206096 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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