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

【安富莱STemWin教程】第31章 键盘输入(实体按键操作控件)

[复制链接]
baiyongbin2009 发布时间:2015-2-13 16:31
本帖最后由 baiyongbin2009 于 2015-2-13 16:32 编辑

特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接
第31章 键盘输入(实体按键操作控件)

    本期教程主要跟大家讲解键盘输入,这里我们通过开发板上面带的按键进行相关的操作,在后面会专门的做一期PS2键盘的教程。
    31. 1  描述
    31. 2 驱动层API
    31. 3 实体按键操作
    31. 4 总结

31.1 描述
    键盘输入设备使用ASCII字符编码,以便区分不同的字符。例如,键盘上只有一个“A”键,但大写的“A”与小写的“a”拥有不同的ASCII编码 (分别为0x41和0x61)
STemWin预定义字符编码
    STemWin 同时定义了其他“虚拟”键盘操作的字符编码。这些编码如下表所示,由GUI.h中的标识符表中定义。因此,在emWin中,字符编码可以是任意扩展ASCII字符值,也可以是任意下列预定义的emWin值。
预定义的虚拟键盘码
描述
GUI_KEY_BACKSPACE
退格键
GUI_KEY_TAB
制表键
GUI_KEY_ENTER
回车键
GUI_KEY_LEFT
左箭头键
GUI_KEY_UP
上箭头键
GUI_KEY_RIGHT
右箭头键
GUI_KEY_DOWN
下箭头键
GUI_KEY_HOME
本位键(移至当前行的开头)
GUI_KEY_END
结束键(移至当前行的末尾)
GUI_KEY_SHIFT
换挡键
GUI_KEY_CONTROL
控制键
GUI_KEY_ESCAPE
换码键
GUI_KEY_INSERT
插入键
GUI_KEY_DELETE
删除键
31.2 驱动层API
   键盘驱动层处理键盘消息函数。这些程序会在具体键 (或组合键)被按下或松开时通知窗口管理器。
下表按字母顺序列出了驱动层键盘程序。详细描述
程序
描述
GUI_StoreKeyMsg()
把消息存储于指定键
GUI_SendKeyMsg()
把消息发送至指定键。
l 函数GUI_StoreKeyMsg()
    把消息数据(Key, PressedCnt)存进键盘缓冲器,Key表示可以是任意扩展ASCII字符 (范围为0x20至0xFF)或者任意预定义的emWin字符编码。PressedCnt表示松开或者未按下的状态。
    该函数可从中断服务程序调用。STemWin的键盘输入管理器含有一个FIFO缓冲器,默认情况下最多可以保存10个键盘事件。如果需要不同的尺寸,可以更改该值。
l 函数GUI_SendKeyMsg()
    把键盘数据发送到输入焦点所在窗口。如果没有窗口有输入焦点,则调用GUI_StoreKeyMsg()函数将数据存储至输入缓冲器之中。该函数不可从中断服务程序调用。该函数的参数和上面函数的参数是一样的。
    应用层的如下几个函数就先不做介绍了,使用到的时候再做介绍:
31.1.png
31.3 实体按键操作
下面给大家讲解一下通过开发板上面带的按键来操作控件。按键的驱动请看安富莱STM32-V5开发板_用户手册的第20章:按键FIFO教程。此工程主 要分为两部分:
  Ø 按键任务
  Ø STemWin主任务
按键任务:
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: AppTaskUserIF
  4. *        功能说明: 此函数主要用于得到按键的键值。
  5. *        形    参:p_arg 是在创建该任务时传递的形参
  6. *        返 回 值: 无
  7. 优 先 级:2
  8. *********************************************************************************************************
  9. */
  10. static void AppTaskUserIF(void *p_arg)
  11. {
  12. uint8_t ucKeyCode;

  13. (void)p_arg;                       /* 避免编译器报警 */

  14. while (1)
  15. {   
  16. bsp_KeyScan();
  17. ucKeyCode = bsp_GetKey();
  18. if(ucKeyCode != KEY_NONE)
  19. {
  20. switch (ucKeyCode)
  21. {
  22. case KEY_DOWN_K1:         /* K1键按下 实现截图*/                                (1)
  23. BSP_OS_SemPost(&SEM_SYNCH);
  24. break;

  25. case KEY_DOWN_K2:         /* K2键按下 实现TAB按键的功能*/                      (2)
  26. GUI_SendKeyMsg(GUI_KEY_TAB, 1);
  27. break;

  28. case KEY_DOWN_K3:         /* K3键按下 实现CANCEL的功能 */                      (3)
  29. GUI_SendKeyMsg(GUI_KEY_ESCAPE, 1);
  30. break;
  31. (4)
  32. case JOY_DOWN_U:         /* 摇杆UP键按下 实现删除字符功能,注意和BACKSPACE回格的区别*/
  33. GUI_SendKeyMsg(GUI_KEY_DELETE, 1);
  34. break;

  35. case JOY_DOWN_D:         /* 摇杆DOWN键按下 实现删除字符 */                    (5)
  36. GUI_SendKeyMsg(GUI_KEY_BACKSPACE, 1);
  37. break;

  38. case JOY_DOWN_L:         /* 摇杆LEFT键按下 实现光标左移 */                    (6)
  39. GUI_SendKeyMsg(GUI_KEY_LEFT, 1);
  40. break;

  41. case JOY_DOWN_R:         /* 摇杆RIGHT键按下 实现光标右移 */                   (7)
  42. GUI_SendKeyMsg(GUI_KEY_RIGHT, 1);
  43. break;

  44. case JOY_DOWN_OK:         /* 摇杆OK键按下 实现OK */                           (8)
  45. GUI_SendKeyMsg(GUI_KEY_ENTER, 1);
  46. break;

  47. default:
  48. /* 其它的键值不处理 */
  49. break;
  50. }
  51. }
  52.         BSP_OS_TimeDlyMs(10);
  53. }
  54. }
复制代码
1. 按下按键1实现截图功能。
2. 实现TAB按键的功能。
3. 实现CANCEL的功能
4. 实现删除字符的功能,注意和BACKSPACE回个的区别。
5. 实现删除字符
6. 实现光标左移。
7. 实现光标右移。
8. 实现OK键功能。
STemWin主任务:
  1. #include "includes.h"
  2. #include "MainTask.h"


  3. /*
  4. ********************************************************************************************************
  5. *                             静态数据
  6. ********************************************************************************************************
  7. */
  8. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
  9. {
  10. { FRAMEWIN_CreateIndirect, "Edit winmode", 0,         90,  90, 140, 130, FRAMEWIN_CF_MOVEABLE},
  11. { EDIT_CreateIndirect,     NULL,     GUI_ID_EDIT0,    10,  10, 110,  20, 0, 15},
  12. { EDIT_CreateIndirect,     NULL,     GUI_ID_EDIT1,    10,  40, 110,  20, 0, 15},
  13. { BUTTON_CreateIndirect,   "Ok",     GUI_ID_OK,       10,  80,  50,  20 },
  14. { BUTTON_CreateIndirect,   "Cancel", GUI_ID_CANCEL,   70,  80,  50,  20 },
  15. };

  16. static char * _apExplain[] =
  17. {
  18. "This sample shows how to use edit widgets with a",
  19. "user defined callback function and how to set a",
  20. "user defined AddKey function. It selects the",
  21. "contents of the edit field on receiving the focus",
  22. "and overwrites the contents if a key other than",
  23. "a cursor key is pressed.",
  24. };

  25. /*
  26. *********************************************************************************************************
  27. *        函 数 名: _cbDialog
  28. *        功能说明: 对话框的回调函数
  29. *        形    参:pMsg 消息指针
  30. *        返 回 值: 无
  31. *********************************************************************************************************
  32. */
  33. static void _cbDialog(WM_MESSAGE * pMsg)
  34. {
  35. int     i;
  36. int     NCode;
  37. int     Id;
  38. WM_HWIN hDlg;
  39. WM_HWIN hItem;

  40. hDlg = pMsg->hWin;
  41. switch (pMsg->MsgId)
  42. {
  43. case WM_INIT_DIALOG:
  44. FRAMEWIN_SetFont(pMsg->hWin, &GUI_Font13_ASCII);
  45. FRAMEWIN_SetTextAlign(pMsg->hWin, GUI_TA_HCENTER);
  46. for (i = 0; i < 2; i++)
  47. {
  48. hItem = WM_GetDialogItem(hDlg, GUI_ID_EDIT0 + i);  // Get the handle of the edit widget
  49. }
  50. break;
  51. case WM_KEY:
  52.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
  53.             {
  54. case GUI_KEY_ESCAPE:
  55.                     GUI_EndDialog(hDlg, 1);
  56.                     break;
  57.                 case GUI_KEY_ENTER:
  58.                     GUI_EndDialog(hDlg, 0);
  59.                     break;
  60.             }
  61.             break;
  62. case WM_NOTIFY_PARENT:
  63. Id    = WM_GetId(pMsg->hWinSrc);      // Id of widget
  64. NCode = pMsg->Data.v;                 // Notification code
  65. switch (NCode)
  66. {
  67. case WM_NOTIFICATION_RELEASED:      // React only if released
  68. if (Id == GUI_ID_OK)
  69. {         // OK Button
  70. GUI_EndDialog(hDlg, 0);
  71. }
  72. if (Id == GUI_ID_CANCEL)
  73. {        // Cancel Button
  74. GUI_EndDialog(hDlg, 1);
  75. }
  76. break;
  77. }
  78. break;
  79. default:
  80. WM_DefaultProc(pMsg);
  81. }
  82. }

  83. /*
  84. *********************************************************************************************************
  85. *        函 数 名: _cbDesktop
  86. *        功能说明: 桌面窗口的回调函数
  87. *        形    参:pMsg 消息指针
  88. *        返 回 值: 无
  89. *********************************************************************************************************
  90. */
  91. static void _cbDesktop(WM_MESSAGE * pMsg)
  92. {
  93. unsigned i;

  94. switch (pMsg->MsgId)
  95. {
  96. /* 重绘 */
  97. case WM_PAINT:
  98. GUI_SetBkColor(GUI_RED);
  99. GUI_Clear();
  100. GUI_SetFont(&GUI_Font24_ASCII);
  101. GUI_DispStringHCenterAt("WIDGET_EditWinmode", 160, 5);
  102. GUI_DispNextLine();
  103. GUI_SetFont(GUI_DEFAULT_FONT);
  104. GUI_DispNextLine();
  105. for (i = 0; i < GUI_COUNTOF(_apExplain); i++)
  106. {
  107. GUI_DispStringHCenterAt(_apExplain[i], 160, GUI_GetDispPosY());
  108. GUI_DispNextLine();
  109. }
  110. break;
  111. }
  112. }

  113. /*
  114. *********************************************************************************************************
  115. *        函 数 名: MainTask
  116. *        功能说明: GUI主函数
  117. *        形    参:无
  118. *        返 回 值: 无
  119. *********************************************************************************************************
  120. */
  121. void MainTask(void)
  122. {
  123. GUI_Init();
  124. WM_SetCallback(WM_HBKWIN, _cbDesktop);
  125. while(1)
  126. {
  127. /* 创建阻塞式对话框 */
  128. GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, 0, 0, 0);
  129. GUI_Delay(1000);
  130. }
  131. }
复制代码
1. 上面的程序比较简单,主要是在对话框上面显示一个编辑框(初学的不要担心,后面教程会有这些控件的讲解)。
2. K1按键实现的是TAB键的功能,主要是实现对话框上面控件的聚焦切换。
    其余的按键功能比较简单,实际操作下就明白了,上面的代码中也有相应的注释。
    尝试了一下自定义按键消息没有成功,后面再试试。
3. 按键具体的通讯机制会在后面的教程中再跟大家讲解。
实际的显示效果如下:
31.2.png
31.4 总结
    本期教程就跟大家讲这么多,主要是想通过本期教程让大家对实体按键操作控件有一个了解。这个过程还需要大家对通信机制有所了解。在后面的教程中会跟大家详细讲解通信机制这块。

收藏 评论1 发布时间:2015-2-13 16:31

举报

1个回答
lkl0305 回答时间:2015-2-13 23:31:04
多谢分享,学习下

所属标签

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