|
完整65章+12章附件教程下载地址:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=19834
第51章 实用的官方小键盘实例讲解
初学者经常问这方面的问题,特此将官方的这个小键盘例子跟大家进行讲解,非常具有代表性,极具参考价值。
51.1 初学者重要提示
51.2 官方WIDGET_NumPad.c实例
51.3 总结
51.1 初学者重要提示
本章节没有提供开发板上面运行的例子,如果要在开发板上面运行官方的这个例子,直接将所有内容复制粘贴到本教程配套的任意例子的MainTask.C文件里面,这个文件里面之前的内容全部删掉即可。
51.2 官方WIDGET_NumPad.c实例
这个例子在模拟器中的位置:
主要功能介绍:
本例子很好的演示了数字小键盘的实现方法。主界面上面创建了两个对话框,一个对话框上面创建了两个编辑框控件,为了方便说明,我们将其命名为对话框A,另一个对话框上面创建了15个按钮,用于给对话框A上面的编辑框发送消息,我们将其命名为对话框B。实现这个小键盘功能,有两个关键点,初次学习时一定要认识到。
1、通过对话框B上面的15个按钮给对话框A的编辑框发送消息是通过函数GUI_SendKeyMsg来发送键盘消息的。编辑框控件支持接收的键盘消息已经在第50章的50.2.2小节里面进行讲解。
2、对话框B上面的15个按钮控件一定要设置禁止聚焦,并将对话框B上面的编辑框控件设置为聚焦,因为只有聚焦的控件才可以接收键盘消息,这个问题我们在讲解每个控件的时候都有强调。将按钮控件设置为禁止聚焦是因为用户一旦触摸了按钮控件,这个按钮会被聚焦,由于同一时刻只有一个控件能够聚焦,编辑框上面的聚焦就消失了,使用函数GUI_SendKeyMsg发送的按键消息将无法传达到编辑框上面。
程序代码如下:
- #include "DIALOG.h"
-
- /*********************************************************************
- *
- * Defines
- *
- **********************************************************************
- */
- //
- // Recommended memory to run the sample with adequate performance
- //
- #define RECOMMENDED_MEMORY (1024L * 10)
-
- /*********************************************************************
- *
- * Static data
- *
- **********************************************************************
- */
- //
- // Bitmap data for arrow keys
- //
- static GUI_CONST_STORAGE GUI_COLOR _aColorsArrow[] = {
- 0xFFFFFF, 0x000000
- };
-
- static GUI_CONST_STORAGE GUI_LOGPALETTE _PalArrow = {
- 2, /* number of entries */
- 1, /* No transparency */
- &_aColorsArrow[0]
- };
-
- static GUI_CONST_STORAGE unsigned char _acArrowRight[] = {
- ____XX__, ________,
- ____XXXX, ________,
- XXXXXXXX, XX______,
- ____XXXX, ________,
- ____XX__, ________
- };
-
- static GUI_CONST_STORAGE unsigned char _acArrowLeft[] = {
- ____XX__, ________,
- __XXXX__, ________,
- XXXXXXXX, XX______,
- __XXXX__, ________,
- ____XX__, ________
- };
-
- static GUI_CONST_STORAGE GUI_BITMAP _bmArrowRight = {
- 10, /* XSize */
- 5, /* YSize */
- 2, /* BytesPerLine */
- 1, /* BitsPerPixel */
- _acArrowRight, /* Pointer to picture data (indices) */
- &_PalArrow /* Pointer to palette */
- };
-
- static GUI_CONST_STORAGE GUI_BITMAP _bmArrowLeft = {
- 10, /* XSize */
- 5, /* YSize */
- 2, /* BytesPerLine */
- 1, /* BitsPerPixel */
- _acArrowLeft, /* Pointer to picture data (indices) */
- &_PalArrow /* Pointer to palette */
- };
- //
- // Array of keys
- //
- static int _aKey[] = {GUI_KEY_DELETE, GUI_KEY_TAB, GUI_KEY_LEFT, GUI_KEY_RIGHT}; //--------------(1)
-
- //
- // Dialog resource of numpad
- //
- static const GUI_WIDGET_CREATE_INFO _aDialogNumPad[] = { //--------------(2)
- //
- // Function Text Id Px Py Dx Dy
- //
- { WINDOW_CreateIndirect, 0, 0, 225, 110, 95, 130},
- { BUTTON_CreateIndirect, "7", GUI_ID_USER + 7, 5, 5, 25, 20},
- { BUTTON_CreateIndirect, "8", GUI_ID_USER + 8, 35, 5, 25, 20},
- { BUTTON_CreateIndirect, "9", GUI_ID_USER + 9, 65, 5, 25, 20},
- { BUTTON_CreateIndirect, "4", GUI_ID_USER + 4, 5, 30, 25, 20},
- { BUTTON_CreateIndirect, "5", GUI_ID_USER + 5, 35, 30, 25, 20},
- { BUTTON_CreateIndirect, "6", GUI_ID_USER + 6, 65, 30, 25, 20},
- { BUTTON_CreateIndirect, "1", GUI_ID_USER + 1, 5, 55, 25, 20},
- { BUTTON_CreateIndirect, "2", GUI_ID_USER + 2, 35, 55, 25, 20},
- { BUTTON_CreateIndirect, "3", GUI_ID_USER + 3, 65, 55, 25, 20},
- { BUTTON_CreateIndirect, "0", GUI_ID_USER + 0, 5, 80, 25, 20},
- { BUTTON_CreateIndirect, ".", GUI_ID_USER + 10, 35, 80, 25, 20},
- { BUTTON_CreateIndirect, "Del", GUI_ID_USER + 11, 65, 80, 25, 20},
- { BUTTON_CreateIndirect, "Tab", GUI_ID_USER + 12, 5, 105, 25, 20},
- { BUTTON_CreateIndirect, 0, GUI_ID_USER + 13, 35, 105, 25, 20},
- { BUTTON_CreateIndirect, 0, GUI_ID_USER + 14, 65, 105, 25, 20},
- };
-
- //
- // Dialog resource of user dialog
- //
- static const GUI_WIDGET_CREATE_INFO _aDialogUser[] = { //--------------(3)
- //
- // Function Text Id Px Py Dx Dy
- //
- { FRAMEWIN_CreateIndirect, "Dialog", 0, 40, 90, 140, 115, FRAMEWIN_CF_MOVEABLE},
- { EDIT_CreateIndirect, 0, GUI_ID_EDIT0, 10, 10, 110, 20, 0, 12},
- { EDIT_CreateIndirect, 0, GUI_ID_EDIT1, 10, 40, 110, 20, 0, 12},
- { BUTTON_CreateIndirect, "Ok", GUI_ID_OK, 10, 70, 50, 20 },
- { BUTTON_CreateIndirect, "Cancel", GUI_ID_CANCEL, 70, 70, 50, 20 },
- };
-
- //
- // Title of sample
- //
- static char _aTitle[] = {"WIDGET_NumPad"};
-
- //
- // Explanation of sample
- //
- static char * _apExplain[] = {
- "This sample shows how to use a numpad as input",
- "device. This can be useful if no keyboard",
- "is available and the user should edit numeric",
- "values or text on a touch screen.",
- };
-
- /*********************************************************************
- *
- * Static code
- *
- **********************************************************************
- */
- /*********************************************************************
- *
- * _cbDialogNumPad
- *
- * Function description
- * Callback function of the numpad.
- */
- static void _cbDialogNumPad(WM_MESSAGE * pMsg) { //--------------(4)
- GUI_RECT r;
- unsigned i;
- int NCode;
- unsigned Id;
- int Pressed;
- WM_HWIN hDlg;
- WM_HWIN hItem;
-
- Pressed = 0;
- hDlg = pMsg->hWin;
- switch (pMsg->MsgId) {
- case WM_PAINT: //--------------(5)
- WM_GetClientRect(&r);
- GUI_SetColor(0x000000);
- GUI_DrawRect(r.x0, r.y0, r.x1, r.y1); /* Draw rectangle around it */
- /* Draw the bright sides */
- GUI_SetColor(0xffffff);
- GUI_DrawHLine(r.y0 + 1, r.x0 + 1, r.x1 - 2); /* Draw top line */
- GUI_DrawVLine(r.x0 + 1, r.y0 + 1, r.y1 - 2);
- /* Draw the dark sides */
- GUI_SetColor(0x555555);
- GUI_DrawHLine(r.y1-1, r.x0 + 1, r.x1 - 1);
- GUI_DrawVLine(r.x1-1, r.y0 + 1, r.y1 - 2);
- break;
- case WM_INIT_DIALOG: //--------------(6)
- for (i = 0; i < GUI_COUNTOF(_aDialogNumPad) - 1; i++) {
- hItem = WM_GetDialogItem(hDlg, GUI_ID_USER + i);
- BUTTON_SetFocussable(hItem, 0); /* Set all buttons non focussable */ //--------------(7)
- switch (i) {
- case 13:
- BUTTON_SetBitmapEx(hItem, 0, &_bmArrowLeft, 7, 7); /* Set bitmap for arrow left button (unpressed) */
- BUTTON_SetBitmapEx(hItem, 1, &_bmArrowLeft, 7, 7); /* Set bitmap for arrow left button (pressed) */
- break;
- case 14:
- BUTTON_SetBitmapEx(hItem, 0, &_bmArrowRight, 7, 7); /* Set bitmap for arrow right button (unpressed) */
- BUTTON_SetBitmapEx(hItem, 1, &_bmArrowRight, 7, 7); /* Set bitmap for arrow right button (pressed) */
- break;
- }
- }
- WM_GetDialogItem(hDlg, GUI_ID_USER + 12);
- break;
- case WM_NOTIFY_PARENT:
- Id = WM_GetId(pMsg->hWinSrc); /* Id of widget */
- NCode = pMsg->Data.v; /* Notification code */
- switch (NCode) {
- case WM_NOTIFICATION_CLICKED: //--------------(8)
- Pressed = 1;
- case WM_NOTIFICATION_RELEASED: //--------------(9)
- if ((Id >= GUI_ID_USER) && (Id <= (GUI_ID_USER + GUI_COUNTOF(_aDialogNumPad) - 1))) {
- int Key;
- if (Id < GUI_ID_USER + 11) {
- char acBuffer[10];
- BUTTON_GetText(pMsg->hWinSrc, acBuffer, sizeof(acBuffer)); /* Get the text of the button */
- Key = acBuffer[0];
- } else {
- Key = _aKey[Id - GUI_ID_USER - 11]; /* Get the text from the array */
- }
- GUI_SendKeyMsg(Key, Pressed); /* Send a key message to the focussed window */
- }
- break;
- }
- default:
- WM_DefaultProc(pMsg);
- }
- }
-
- /*********************************************************************
- *
- * _cbDialogUser
- *
- * Purpose:
- * Callback function of the user dialog.
- */
- static void _cbDialogUser(WM_MESSAGE * pMsg) { //--------------(10)
- int i;
- int NCode;
- int Id;
- WM_HWIN hDlg;
- WM_HWIN hItem;
-
- hDlg = pMsg->hWin;
- switch (pMsg->MsgId) {
- case WM_INIT_DIALOG:
- for (i = 0; i < 2; i++) { //--------------(11)
- hItem = WM_GetDialogItem(hDlg, GUI_ID_EDIT0 + i); /* Get the handle of the edit widget */
- EDIT_SetText(hItem, "12345678"); /* Set text */
- }
- 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 */ //--------------(12)
- 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
- *
- * Function description
- * This routine handles the drawing of the desktop window.
- */
- static void _cbDesktop(WM_MESSAGE * pMsg) { //--------------(13)
- unsigned i;
-
- switch (pMsg->MsgId) {
- case WM_PAINT:
- GUI_SetBkColor(GUI_RED);
- GUI_Clear();
- GUI_SetFont(&GUI_Font24_ASCII);
- GUI_DispStringHCenterAt(_aTitle, 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;
- }
- }
-
- /*********************************************************************
- *
- * Exported code
- *
- **********************************************************************
- */
- /*********************************************************************
- *
- * MainTask
- */
- void MainTask(void) {
- WM_HWIN hNumPad;
-
- GUI_Init();
- //
- // Check if recommended memory for the sample is available
- //
- if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
- GUI_ErrorOut("Not enough memory available.");
- return;
- }
- WM_SetCallback(WM_HBKWIN, _cbDesktop); //--------------(14)
- hNumPad = GUI_CreateDialogBox(_aDialogNumPad,
- GUI_COUNTOF(_aDialogNumPad), //--------------(15)
- _cbDialogNumPad, WM_HBKWIN, 0, 0); /* Create the numpad dialog */
- WM_SetStayOnTop(hNumPad, 1);
- while (1) {
- GUI_ExecDialogBox(_aDialogUser, //--------------(16)
- GUI_COUNTOF(_aDialogUser),
- _cbDialogUser, WM_HBKWIN, 0, 0); /* Execute the user dialog */
- GUI_Delay(1000);
- }
- }
复制代码 1. 对话框上15个按钮中,最后四个按钮可以发送的键盘消息。
2. 创建了15个按钮的对话框上的资源列表,为了方便描述,我们将其命名为对话框B。
3. 创建了两个编辑框和两个按钮的对话框上的资源列表,为了方便描述,我们将其命名为对话框A。
4. 对话框B的回调函数。
5. 对话框B回调函数的WM_PAINT消息,主要是重绘背景显示效果。
6. 对话框B回调函数的WM_INIT_DIALOG消息,主要是初始化控件。
7. 对话框B上面的所有按钮控件都被设置禁止聚焦。
8. 对话框B上面按钮的点击消息,这个消息里面设置了变量Pressed =1,表示按钮按下。特别注意这个消息里面没有加break语句,也就是会继续往下执行:
- /* 确定这15个按键的ID是否在范围内 */
- if ((Id >= GUI_ID_USER) && (Id <= (GUI_ID_USER + GUI_COUNTOF(_aDialogNumPad) - 1))) {
- int Key;
- /* 按钮的ID在范围GUI_ID_USER + 0到GUI_ID_USER + 10这11个按钮的消息处理 */
- if (Id < GUI_ID_USER + 11) {
- char acBuffer[10];
- /* 获得此按钮上面显示的字符 */
- BUTTON_GetText(pMsg->hWinSrc, acBuffer, sizeof(acBuffer));
- Key = acBuffer[0];
- }
- /* 按钮的ID在范围GUI_ID_USER + 11到GUI_ID_USER + 14这4个按钮的消息处理 */
- else {
- /* 获得此按钮对应的键盘消息,即全局变量_aKey里面存的4个键盘消息 */
- Key = _aKey[Id - GUI_ID_USER - 11];
- }
-
- /* 发送消息给当前聚焦的窗口,即对话框A上面的编辑框控件,此时Pressed = 1表示按下消息 */
- GUI_SendKeyMsg(Key, Pressed); *
- }
复制代码 9. 对话框B上面按钮的释放消息,功能跟第8条相同,唯一不同的是这里发送的键盘释放消息,在这个回调函数的开头已经设置变量Pressed = 0,所以使用函数GUI_SendKeyMsg发送的时候,发送的是释放消息。
10. 对话框A的回调函数。
11. 对话框A回调函数的WM_INIT_DIALOG消息,主要是初始化控件,这里是初始化编辑框上面显示的字符。
12. 对话框A上面两个按钮的回调消息处理,都是通过函数GUI_EndDialog来关闭对话框。不同的是第二个参数,这个参数设置的数值是作为阻塞式对话框的返回值。
13. 桌面窗口的回调函数。
14. 设置桌面窗口的回调函数。
15. 创建对话框B。
16. 创建对话框A。
实际显示效果如下:
51.3 总结
本章节为大家讲解的这个例子非常具有代表性,建议初学者尝试做一个自己的小键盘,并在开发板上面测试运行。
|
|