硬汉嵌入式论坛

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

[emWin教程入门篇] 【emWin实战教程V2.0】第51章      实用的官方小键

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
发表于 2017-3-7 15:09:34 | 显示全部楼层 |阅读模式
完整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实例

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


主要功能介绍:
        本例子很好的演示了数字小键盘的实现方法。主界面上面创建了两个对话框,一个对话框上面创建了两个编辑框控件,为了方便说明,我们将其命名为对话框A,另一个对话框上面创建了15个按钮,用于给对话框A上面的编辑框发送消息,我们将其命名为对话框B。实现这个小键盘功能,有两个关键点,初次学习时一定要认识到。
        1、通过对话框B上面的15个按钮给对话框A的编辑框发送消息是通过函数GUI_SendKeyMsg来发送键盘消息的。编辑框控件支持接收的键盘消息已经在第50章的50.2.2小节里面进行讲解。
        2、对话框B上面的15个按钮控件一定要设置禁止聚焦,并将对话框B上面的编辑框控件设置为聚焦,因为只有聚焦的控件才可以接收键盘消息,这个问题我们在讲解每个控件的时候都有强调。将按钮控件设置为禁止聚焦是因为用户一旦触摸了按钮控件,这个按钮会被聚焦,由于同一时刻只有一个控件能够聚焦,编辑框上面的聚焦就消失了,使用函数GUI_SendKeyMsg发送的按键消息将无法传达到编辑框上面。
程序代码如下:
  1. #include "DIALOG.h"
  2. /*********************************************************************
  3. *
  4. *       Defines
  5. *
  6. **********************************************************************
  7. */
  8. //
  9. // Recommended memory to run the sample with adequate performance
  10. //
  11. #define RECOMMENDED_MEMORY (1024L * 10)
  12. /*********************************************************************
  13. *
  14. *       Static data
  15. *
  16. **********************************************************************
  17. */
  18. //
  19. // Bitmap data for arrow keys
  20. //
  21. static GUI_CONST_STORAGE GUI_COLOR _aColorsArrow[] = {
  22.   0xFFFFFF, 0x000000
  23. };
  24. static GUI_CONST_STORAGE GUI_LOGPALETTE _PalArrow = {
  25.   2, /* number of entries */
  26.   1,     /* No transparency */
  27.   &_aColorsArrow[0]
  28. };
  29. static GUI_CONST_STORAGE unsigned char _acArrowRight[] = {
  30.   ____XX__, ________,
  31.   ____XXXX, ________,
  32.   XXXXXXXX, XX______,
  33.   ____XXXX, ________,
  34.   ____XX__, ________
  35. };
  36. static GUI_CONST_STORAGE unsigned char _acArrowLeft[] = {
  37.   ____XX__, ________,
  38.   __XXXX__, ________,
  39.   XXXXXXXX, XX______,
  40.   __XXXX__, ________,
  41.   ____XX__, ________
  42. };
  43. static GUI_CONST_STORAGE GUI_BITMAP _bmArrowRight = {
  44.   10,            /* XSize */
  45.   5,             /* YSize */
  46.   2,             /* BytesPerLine */
  47.   1,             /* BitsPerPixel */
  48.   _acArrowRight, /* Pointer to picture data (indices) */
  49.   &_PalArrow     /* Pointer to palette */
  50. };
  51. static GUI_CONST_STORAGE GUI_BITMAP _bmArrowLeft = {
  52.   10,            /* XSize */
  53.   5,             /* YSize */
  54.   2,             /* BytesPerLine */
  55.   1,             /* BitsPerPixel */
  56.   _acArrowLeft,  /* Pointer to picture data (indices) */
  57.   &_PalArrow     /* Pointer to palette */
  58. };
  59. //
  60. // Array of keys
  61. //
  62. static int _aKey[] = {GUI_KEY_DELETE, GUI_KEY_TAB, GUI_KEY_LEFT, GUI_KEY_RIGHT};  //--------------(1)
  63. //
  64. // Dialog resource of numpad
  65. //
  66. static const GUI_WIDGET_CREATE_INFO _aDialogNumPad[] = {   //--------------(2)
  67. //
  68. //  Function                 Text      Id                 Px   Py   Dx   Dy
  69. //
  70.   { WINDOW_CreateIndirect,   0,        0,                225, 110,  95, 130},
  71.   { BUTTON_CreateIndirect,   "7",      GUI_ID_USER +  7,   5,   5,  25,  20},
  72.   { BUTTON_CreateIndirect,   "8",      GUI_ID_USER +  8,  35,   5,  25,  20},
  73.   { BUTTON_CreateIndirect,   "9",      GUI_ID_USER +  9,  65,   5,  25,  20},
  74.   { BUTTON_CreateIndirect,   "4",      GUI_ID_USER +  4,   5,  30,  25,  20},
  75.   { BUTTON_CreateIndirect,   "5",      GUI_ID_USER +  5,  35,  30,  25,  20},
  76.   { BUTTON_CreateIndirect,   "6",      GUI_ID_USER +  6,  65,  30,  25,  20},
  77.   { BUTTON_CreateIndirect,   "1",      GUI_ID_USER +  1,   5,  55,  25,  20},
  78.   { BUTTON_CreateIndirect,   "2",      GUI_ID_USER +  2,  35,  55,  25,  20},
  79.   { BUTTON_CreateIndirect,   "3",      GUI_ID_USER +  3,  65,  55,  25,  20},
  80.   { BUTTON_CreateIndirect,   "0",      GUI_ID_USER +  0,   5,  80,  25,  20},
  81.   { BUTTON_CreateIndirect,   ".",      GUI_ID_USER + 10,  35,  80,  25,  20},
  82.   { BUTTON_CreateIndirect,   "Del",    GUI_ID_USER + 11,  65,  80,  25,  20},
  83.   { BUTTON_CreateIndirect,   "Tab",    GUI_ID_USER + 12,   5, 105,  25,  20},
  84.   { BUTTON_CreateIndirect,   0,        GUI_ID_USER + 13,  35, 105,  25,  20},
  85.   { BUTTON_CreateIndirect,   0,        GUI_ID_USER + 14,  65, 105,  25,  20},
  86. };
  87. //
  88. // Dialog resource of user dialog
  89. //
  90. static const GUI_WIDGET_CREATE_INFO _aDialogUser[] = {  //--------------(3)
  91. //
  92. //  Function                 Text      Id                 Px   Py   Dx   Dy
  93. //
  94.   { FRAMEWIN_CreateIndirect, "Dialog", 0,                 40,  90, 140, 115, FRAMEWIN_CF_MOVEABLE},
  95.   { EDIT_CreateIndirect,     0,        GUI_ID_EDIT0,      10,  10, 110,  20, 0, 12},
  96.   { EDIT_CreateIndirect,     0,        GUI_ID_EDIT1,      10,  40, 110,  20, 0, 12},
  97.   { BUTTON_CreateIndirect,   "Ok",     GUI_ID_OK,         10,  70,  50,  20 },
  98.   { BUTTON_CreateIndirect,   "Cancel", GUI_ID_CANCEL,     70,  70,  50,  20 },
  99. };
  100. //
  101. // Title of sample
  102. //
  103. static char _aTitle[] = {"WIDGET_NumPad"};
  104. //
  105. // Explanation of sample
  106. //
  107. static char * _apExplain[] = {
  108.   "This sample shows how to use a numpad as input",
  109.   "device. This can be useful if no keyboard",
  110.   "is available and the user should edit numeric",
  111.   "values or text on a touch screen.",
  112. };
  113. /*********************************************************************
  114. *
  115. *       Static code
  116. *
  117. **********************************************************************
  118. */
  119. /*********************************************************************
  120. *
  121. *       _cbDialogNumPad
  122. *
  123. * Function description
  124. *   Callback function of the numpad.
  125. */
  126. static void _cbDialogNumPad(WM_MESSAGE * pMsg) {  //--------------(4)
  127.   GUI_RECT r;
  128.   unsigned i;
  129.   int      NCode;
  130.   unsigned Id;
  131.   int      Pressed;
  132.   WM_HWIN  hDlg;
  133.   WM_HWIN  hItem;
  134.   Pressed = 0;
  135.   hDlg = pMsg->hWin;
  136.   switch (pMsg->MsgId) {
  137.   case WM_PAINT:    //--------------(5)
  138.     WM_GetClientRect(&r);
  139.     GUI_SetColor(0x000000);
  140.     GUI_DrawRect(r.x0, r.y0, r.x1, r.y1);          /* Draw rectangle around it */
  141.     /* Draw the bright sides */
  142.     GUI_SetColor(0xffffff);
  143.     GUI_DrawHLine(r.y0 + 1, r.x0 + 1, r.x1 - 2);   /* Draw top line */
  144.     GUI_DrawVLine(r.x0 + 1, r.y0 + 1, r.y1 - 2);
  145.     /* Draw the dark sides */
  146.     GUI_SetColor(0x555555);
  147.     GUI_DrawHLine(r.y1-1, r.x0 + 1, r.x1 - 1);
  148.     GUI_DrawVLine(r.x1-1, r.y0 + 1, r.y1 - 2);
  149.     break;
  150.   case WM_INIT_DIALOG:  //--------------(6)
  151.     for (i = 0; i < GUI_COUNTOF(_aDialogNumPad) - 1; i++) {
  152.       hItem = WM_GetDialogItem(hDlg, GUI_ID_USER + i);
  153.       BUTTON_SetFocussable(hItem, 0);  /* Set all buttons non focussable */  //--------------(7)
  154.       switch (i) {
  155.       case 13:
  156.         BUTTON_SetBitmapEx(hItem, 0, &_bmArrowLeft, 7, 7);  /* Set bitmap for arrow left button (unpressed) */
  157.         BUTTON_SetBitmapEx(hItem, 1, &_bmArrowLeft, 7, 7);  /* Set bitmap for arrow left button (pressed) */
  158.         break;
  159.       case 14:
  160.         BUTTON_SetBitmapEx(hItem, 0, &_bmArrowRight, 7, 7); /* Set bitmap for arrow right button (unpressed) */
  161.         BUTTON_SetBitmapEx(hItem, 1, &_bmArrowRight, 7, 7); /* Set bitmap for arrow right button (pressed) */
  162.         break;
  163.       }
  164.     }
  165.     WM_GetDialogItem(hDlg, GUI_ID_USER + 12);
  166.     break;
  167.   case WM_NOTIFY_PARENT:
  168.     Id    = WM_GetId(pMsg->hWinSrc);      /* Id of widget */
  169.     NCode = pMsg->Data.v;                 /* Notification code */
  170.     switch (NCode) {
  171.     case WM_NOTIFICATION_CLICKED:     //--------------(8)
  172.       Pressed = 1;
  173.     case WM_NOTIFICATION_RELEASED:    //--------------(9)
  174.       if ((Id >= GUI_ID_USER) && (Id <= (GUI_ID_USER + GUI_COUNTOF(_aDialogNumPad) - 1))) {
  175.         int Key;
  176.         if (Id < GUI_ID_USER + 11) {
  177.           char acBuffer[10];
  178.           BUTTON_GetText(pMsg->hWinSrc, acBuffer, sizeof(acBuffer)); /* Get the text of the button */
  179.           Key = acBuffer[0];
  180.         } else {
  181.           Key = _aKey[Id - GUI_ID_USER - 11]; /* Get the text from the array */
  182.         }
  183.         GUI_SendKeyMsg(Key, Pressed);  /* Send a key message to the focussed window */
  184.       }
  185.       break;
  186.     }
  187.   default:
  188.     WM_DefaultProc(pMsg);
  189.   }
  190. }
  191. /*********************************************************************
  192. *
  193. *       _cbDialogUser
  194. *
  195. * Purpose:
  196. *   Callback function of the user dialog.
  197. */
  198. static void _cbDialogUser(WM_MESSAGE * pMsg) {  //--------------(10)
  199.   int      i;
  200.   int      NCode;
  201.   int      Id;
  202.   WM_HWIN  hDlg;
  203.   WM_HWIN  hItem;
  204.   hDlg = pMsg->hWin;
  205.   switch (pMsg->MsgId) {
  206.   case WM_INIT_DIALOG:
  207.     for (i = 0; i < 2; i++) {   //--------------(11)
  208.       hItem = WM_GetDialogItem(hDlg, GUI_ID_EDIT0 + i);  /* Get the handle of the edit widget */
  209.       EDIT_SetText(hItem, "12345678");                   /* Set text */
  210.     }
  211.     break;
  212.   case WM_NOTIFY_PARENT:
  213.     Id    = WM_GetId(pMsg->hWinSrc);      /* Id of widget */
  214.     NCode = pMsg->Data.v;                 /* Notification code */
  215.     switch (NCode) {
  216.       case WM_NOTIFICATION_RELEASED:      /* React only if released */  //--------------(12)
  217.         if (Id == GUI_ID_OK) {            /* OK Button */
  218.           GUI_EndDialog(hDlg, 0);
  219.         }
  220.         if (Id == GUI_ID_CANCEL) {        /* Cancel Button */
  221.           GUI_EndDialog(hDlg, 1);
  222.         }
  223.         break;
  224.     }
  225.     break;
  226.   default:
  227.     WM_DefaultProc(pMsg);
  228.   }
  229. }
  230. /*********************************************************************
  231. *
  232. *       _cbDesktop
  233. *
  234. * Function description
  235. *   This routine handles the drawing of the desktop window.
  236. */
  237. static void _cbDesktop(WM_MESSAGE * pMsg) {  //--------------(13)
  238.   unsigned i;
  239.   switch (pMsg->MsgId) {
  240.   case WM_PAINT:
  241.     GUI_SetBkColor(GUI_RED);
  242.     GUI_Clear();
  243.     GUI_SetFont(&GUI_Font24_ASCII);
  244.     GUI_DispStringHCenterAt(_aTitle, 160, 5);
  245.     GUI_DispNextLine();
  246.     GUI_SetFont(GUI_DEFAULT_FONT);
  247.     GUI_DispNextLine();
  248.     for (i = 0; i < GUI_COUNTOF(_apExplain); i++) {
  249.       GUI_DispStringHCenterAt(_apExplain[i], 160, GUI_GetDispPosY());
  250.       GUI_DispNextLine();
  251.     }
  252.     break;
  253.   }
  254. }
  255. /*********************************************************************
  256. *
  257. *       Exported code
  258. *
  259. **********************************************************************
  260. */
  261. /*********************************************************************
  262. *
  263. *       MainTask
  264. */
  265. void MainTask(void) {
  266.   WM_HWIN hNumPad;
  267.   GUI_Init();
  268.   //
  269.   // Check if recommended memory for the sample is available
  270.   //
  271.   if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
  272.     GUI_ErrorOut("Not enough memory available.");
  273.     return;
  274.   }
  275.   WM_SetCallback(WM_HBKWIN, _cbDesktop);  //--------------(14)
  276.   hNumPad = GUI_CreateDialogBox(_aDialogNumPad,
  277.                                 GUI_COUNTOF(_aDialogNumPad),  //--------------(15)
  278.                                 _cbDialogNumPad, WM_HBKWIN, 0, 0); /* Create the numpad dialog */
  279.   WM_SetStayOnTop(hNumPad, 1);
  280.   while (1) {
  281.     GUI_ExecDialogBox(_aDialogUser,      //--------------(16)
  282.                       GUI_COUNTOF(_aDialogUser),
  283.                       _cbDialogUser, WM_HBKWIN, 0, 0);             /* Execute the user dialog */
  284.     GUI_Delay(1000);
  285.   }
  286. }
复制代码
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语句,也就是会继续往下执行:
  1. /* 确定这15个按键的ID是否在范围内 */           
  2.    if ((Id >= GUI_ID_USER) && (Id <= (GUI_ID_USER + GUI_COUNTOF(_aDialogNumPad) - 1))) {
  3.         int Key;
  4.      /* 按钮的ID在范围GUI_ID_USER + 0到GUI_ID_USER + 10这11个按钮的消息处理 */
  5.         if (Id < GUI_ID_USER + 11) {
  6.           char acBuffer[10];
  7.           /* 获得此按钮上面显示的字符 */
  8.           BUTTON_GetText(pMsg->hWinSrc, acBuffer, sizeof(acBuffer));
  9.           Key = acBuffer[0];
  10.         }
  11.          /* 按钮的ID在范围GUI_ID_USER + 11到GUI_ID_USER + 14这4个按钮的消息处理 */
  12. else {
  13. /* 获得此按钮对应的键盘消息,即全局变量_aKey里面存的4个键盘消息 */
  14.           Key = _aKey[Id - GUI_ID_USER - 11];
  15.         }
  16.      /* 发送消息给当前聚焦的窗口,即对话框A上面的编辑框控件,此时Pressed = 1表示按下消息 */
  17.         GUI_SendKeyMsg(Key, Pressed);  *
  18.       }
复制代码
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.2.png


51.3 总结


        本章节为大家讲解的这个例子非常具有代表性,建议初学者尝试做一个自己的小键盘,并在开发板上面测试运行。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

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

本版积分规则

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

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

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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