第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值。
31.2 驱动层API
键盘驱动层处理键盘消息函数。这些程序会在具体键 (或组合键)被按下或松开时通知窗口管理器。下表按字母顺序列出了驱动层键盘程序。详细描述
把消息数据(Key, PressedCnt)存进键盘缓冲器,Key表示可以是任意扩展ASCII字符 (范围为0x20至0xFF)或者任意预定义的emWin字符编码。PressedCnt表示松开或者未按下的状态。
l 函数GUI_StoreKeyMsg()
该函数可从中断服务程序调用。STemWin的键盘输入管理器含有一个FIFO缓冲器,默认情况下最多可以保存10个键盘事件。如果需要不同的尺寸,可以更改该值。
l 函数GUI_SendKeyMsg()
把键盘数据发送到输入焦点所在窗口。如果没有窗口有输入焦点,则调用GUI_StoreKeyMsg()函数将数据存储至输入缓冲器之中。该函数不可从中断服务程序调用。该函数的参数和上面函数的参数是一样的。
应用层的如下几个函数就先不做介绍了,使用到的时候再做介绍:
31.3 实体按键操作
下面给大家讲解一下通过开发板上面带的按键来操作控件。按键的驱动请看安富莱STM32-V5开发板_用户手册的第20章:按键FIFO教程。此工程主要分为两部分:
? 按键任务
? STemWin主任务
按键任务:
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskUserIF
- * 功能说明: 此函数主要用于得到按键的键值。
- * 形 参:p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- 优 先 级:2
- *********************************************************************************************************
- */
- static void AppTaskUserIF(void *p_arg)
- {
- uint8_t ucKeyCode;
-
- (void)p_arg; /* 避免编译器报警 */
-
- while (1)
- {
- bsp_KeyScan();
- ucKeyCode = bsp_GetKey();
- if(ucKeyCode != KEY_NONE)
- {
- switch (ucKeyCode)
- {
- case KEY_DOWN_K1: /* K1键按下 实现截图*/ (1)
- BSP_OS_SemPost(&SEM_SYNCH);
- break;
-
- case KEY_DOWN_K2: /* K2键按下 实现TAB按键的功能*/ (2)
- GUI_SendKeyMsg(GUI_KEY_TAB, 1);
- break;
-
- case KEY_DOWN_K3: /* K3键按下 实现CANCEL的功能 */ (3)
- GUI_SendKeyMsg(GUI_KEY_ESCAPE, 1);
- break;
- (4)
- case JOY_DOWN_U: /* 摇杆UP键按下 实现删除字符功能,注意和BACKSPACE回格的区别*/
- GUI_SendKeyMsg(GUI_KEY_DELETE, 1);
- break;
-
- case JOY_DOWN_D: /* 摇杆DOWN键按下 实现删除字符 */ (5)
- GUI_SendKeyMsg(GUI_KEY_BACKSPACE, 1);
- break;
-
- case JOY_DOWN_L: /* 摇杆LEFT键按下 实现光标左移 */ (6)
- GUI_SendKeyMsg(GUI_KEY_LEFT, 1);
- break;
-
- case JOY_DOWN_R: /* 摇杆RIGHT键按下 实现光标右移 */ (7)
- GUI_SendKeyMsg(GUI_KEY_RIGHT, 1);
- break;
-
- case JOY_DOWN_OK: /* 摇杆OK键按下 实现OK */ (8)
- GUI_SendKeyMsg(GUI_KEY_ENTER, 1);
- break;
-
- default:
- /* 其它的键值不处理 */
- break;
- }
- }
- BSP_OS_TimeDlyMs(10);
- }
- }
1. 按下按键1实现截图功能。
2. 实现TAB按键的功能。
3. 实现CANCEL的功能
4. 实现删除字符的功能,注意和BACKSPACE回个的区别。
5. 实现删除字符
6. 实现光标左移。
7. 实现光标右移。
8. 实现OK键功能。
STemWin主任务:
- #include "includes.h"
- #include "MainTask.h"
-
-
- /*
- ********************************************************************************************************
- * 静态数据
- ********************************************************************************************************
- */
- static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
- {
- { FRAMEWIN_CreateIndirect, "Edit winmode", 0, 90, 90, 140, 130, FRAMEWIN_CF_MOVEABLE},
- { EDIT_CreateIndirect, NULL, GUI_ID_EDIT0, 10, 10, 110, 20, 0, 15},
- { EDIT_CreateIndirect, NULL, GUI_ID_EDIT1, 10, 40, 110, 20, 0, 15},
- { BUTTON_CreateIndirect, "Ok", GUI_ID_OK, 10, 80, 50, 20 },
- { BUTTON_CreateIndirect, "Cancel", GUI_ID_CANCEL, 70, 80, 50, 20 },
- };
-
- static char * _apExplain[] =
- {
- "This sample shows how to use edit widgets with a",
- "user defined callback function and how to set a",
- "user defined AddKey function. It selects the",
- "contents of the edit field on receiving the focus",
- "and overwrites the contents if a key other than",
- "a cursor key is pressed.",
- };
-
- /*
- *********************************************************************************************************
- * 函 数 名: _cbDialog
- * 功能说明: 对话框的回调函数
- * 形 参:pMsg 消息指针
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void _cbDialog(WM_MESSAGE * pMsg)
- {
- int i;
- int NCode;
- int Id;
- WM_HWIN hDlg;
- WM_HWIN hItem;
-
- hDlg = pMsg->hWin;
- switch (pMsg->MsgId)
- {
- case WM_INIT_DIALOG:
- FRAMEWIN_SetFont(pMsg->hWin, &GUI_Font13_ASCII);
- FRAMEWIN_SetTextAlign(pMsg->hWin, GUI_TA_HCENTER);
- for (i = 0; i < 2; i++)
- {
- hItem = WM_GetDialogItem(hDlg, GUI_ID_EDIT0 + i); // Get the handle of the edit widget
- }
- break;
- case WM_KEY:
- switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
- {
- case GUI_KEY_ESCAPE:
- GUI_EndDialog(hDlg, 1);
- break;
- case GUI_KEY_ENTER:
- GUI_EndDialog(hDlg, 0);
- break;
- }
- break;
- case WM_NOTIFY_PARENT:
- Id = WM_GetId(pMsg->hWinSrc); // Id of widget
- NCode = pMsg->Data.v; // Notification code
- switch (NCode)
- {
- case WM_NOTIFICATION_RELEASED: // React only if released
- if (Id == GUI_ID_OK)
- { // OK Button
- GUI_EndDialog(hDlg, 0);
- }
- if (Id == GUI_ID_CANCEL)
- { // Cancel Button
- GUI_EndDialog(hDlg, 1);
- }
- break;
- }
- break;
- default:
- WM_DefaultProc(pMsg);
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: _cbDesktop
- * 功能说明: 桌面窗口的回调函数
- * 形 参:pMsg 消息指针
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void _cbDesktop(WM_MESSAGE * pMsg)
- {
- unsigned i;
-
- switch (pMsg->MsgId)
- {
- /* 重绘 */
- case WM_PAINT:
- GUI_SetBkColor(GUI_RED);
- GUI_Clear();
- GUI_SetFont(&GUI_Font24_ASCII);
- GUI_DispStringHCenterAt("WIDGET_EditWinmode", 160, 5);
- GUI_DispNextLine();
- GUI_SetFont(GUI_DEFAULT_FONT);
- GUI_DispNextLine();
- for (i = 0; i < GUI_COUNTOF(_apExplain); i++)
- {
- GUI_DispStringHCenterAt(_apExplain[i], 160, GUI_GetDispPosY());
- GUI_DispNextLine();
- }
- break;
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: MainTask
- * 功能说明: GUI主函数
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void MainTask(void)
- {
- GUI_Init();
- WM_SetCallback(WM_HBKWIN, _cbDesktop);
- while(1)
- {
- /* 创建阻塞式对话框 */
- GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, 0, 0, 0);
- GUI_Delay(1000);
- }
- }
1. 上面的程序比较简单,主要是在对话框上面显示一个编辑框(初学的不要担心,后面教程会有这些控件的讲解)。
2. K1按键实现的是TAB键的功能,主要是实现对话框上面控件的聚焦切换。
其余的按键功能比较简单,实际操作下就明白了,上面的代码中也有相应的注释。
尝试了一下自定义按键消息没有成功,后面再试试。
3. 按键具体的通讯机制会在后面的教程中再跟大家讲解。
实际的显示效果如下:
31.4 总结
本期教程就跟大家讲这么多,主要是想通过本期教程让大家对实体按键操作控件有一个了解。这个过程还需要大家对通信机制有所了解。在后面的教程中会跟大家详细讲解通信机制这块。