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

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

[复制链接]
baiyongbin2009 发布时间:2015-2-13 16:31
本帖最后由 baiyongbin2009 于 2015-2-13 16:32 编辑
5 `% m2 q8 J9 z4 Z  B( A3 c% P" ?) H* A! I: B
特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接
) y9 a2 X' f" z# A; n
第31章 键盘输入(实体按键操作控件)
# v$ d% ]4 f1 q
    本期教程主要跟大家讲解键盘输入,这里我们通过开发板上面带的按键进行相关的操作,在后面会专门的做一期PS2键盘的教程。
    31. 1  描述
    31. 2 驱动层API
    31. 3 实体按键操作
    31. 4 总结

3 m9 J6 }# i" `  p( l9 A31.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. /*
    $ O) H4 h  w. c% o& n0 }( e9 j
  2. *********************************************************************************************************
    " L; @) N) w5 n8 M
  3. *        函 数 名: AppTaskUserIF
    . _( w- Z* U( e! G$ d
  4. *        功能说明: 此函数主要用于得到按键的键值。
    3 k2 L8 t5 U3 ]  F1 q) E+ ?
  5. *        形    参:p_arg 是在创建该任务时传递的形参2 l1 Q1 M- u: j2 |6 U( g* G' C5 |/ {
  6. *        返 回 值: 无
    / U$ r+ i# U0 O" O# m1 `! ]
  7. 优 先 级:24 P& R: m: \4 S4 f# `; w5 }
  8. *********************************************************************************************************
    + x4 d7 v4 y# e% u! C, G/ V
  9. */
      a; i1 d$ J7 ?, J; L% k# o* x! r( c1 A
  10. static void AppTaskUserIF(void *p_arg)% \! @! `. Y* y! ]! v
  11. {/ Q2 O. A1 ?( b
  12. uint8_t ucKeyCode;2 }' X: j! o- u. ?# U: s' y
  13. 0 o7 q& f, `2 ]* y1 b. l
  14. (void)p_arg;                       /* 避免编译器报警 */
    " L$ [0 X9 s/ U8 T7 _9 t* v' y" _/ v1 T
  15. ( m0 M: B( c* U" B, ^
  16. while (1) * p( K* v9 X" h- m
  17. {   
    $ m+ R* V7 k4 {  o
  18. bsp_KeyScan();
    . O# m( ?3 g% h1 `, I( J
  19. ucKeyCode = bsp_GetKey();
    2 @7 n' p5 U  z4 p( ?
  20. if(ucKeyCode != KEY_NONE)
    ; V& C5 _9 H3 Z  b+ A0 t
  21. {$ X" [, B- V( W
  22. switch (ucKeyCode)
    6 K: {: r, o: q. o* R, S% c2 r* v
  23. {
    + }) t& N9 p  N  z9 n
  24. case KEY_DOWN_K1:         /* K1键按下 实现截图*/                                (1)
    " D8 `0 [1 u$ G
  25. BSP_OS_SemPost(&SEM_SYNCH);" w' F4 a% V6 h% D" r) H# C
  26. break;
    7 Q8 ]1 M! r- j5 M

  27. 3 E+ n/ h; j$ [( d! \, X1 b0 p
  28. case KEY_DOWN_K2:         /* K2键按下 实现TAB按键的功能*/                      (2)
    ! D1 K3 X, z; r. W4 }* K; P
  29. GUI_SendKeyMsg(GUI_KEY_TAB, 1);
    ) c, M/ P7 {3 y5 e! j
  30. break;
    & C. E. k5 y8 [" ]0 X
  31. ( Y& M3 N' z4 J) ~
  32. case KEY_DOWN_K3:         /* K3键按下 实现CANCEL的功能 */                      (3)) _7 G" R3 b6 y2 O5 m4 W' Q
  33. GUI_SendKeyMsg(GUI_KEY_ESCAPE, 1);
    * n" D: p, K2 f. |( T
  34. break;
    / w' k. X$ d9 A- N
  35. (4)
    + \8 j0 W) W: u5 ?, P; k) ^5 M
  36. case JOY_DOWN_U:         /* 摇杆UP键按下 实现删除字符功能,注意和BACKSPACE回格的区别*/
    % Q7 U' h: [' r& P
  37. GUI_SendKeyMsg(GUI_KEY_DELETE, 1);
    6 r6 Y! H5 ~1 G
  38. break;6 d3 |; p+ h8 u6 D
  39. $ {0 W7 [0 E2 l1 X0 \% [* z. b3 x
  40. case JOY_DOWN_D:         /* 摇杆DOWN键按下 实现删除字符 */                    (5)
    % `! Y8 {2 y. z: L
  41. GUI_SendKeyMsg(GUI_KEY_BACKSPACE, 1);* K& c9 b# h$ K4 W- v- T2 u
  42. break;/ \# k# D- u# G& t1 K) e8 @0 \) `
  43. 4 O2 p( n8 b7 H* }
  44. case JOY_DOWN_L:         /* 摇杆LEFT键按下 实现光标左移 */                    (6)1 n, L' K" G& w
  45. GUI_SendKeyMsg(GUI_KEY_LEFT, 1);: A* j0 N2 ]( v* X0 c( I! c
  46. break;
    , R* Y! D( U: l
  47. " M( K$ g# G3 H6 p! t! f9 T0 f$ Y
  48. case JOY_DOWN_R:         /* 摇杆RIGHT键按下 实现光标右移 */                   (7)# t1 J* q# J6 b# o4 L
  49. GUI_SendKeyMsg(GUI_KEY_RIGHT, 1);$ w" X$ W& g! ~( N8 J
  50. break;
    ; F4 m: E* v7 f
  51. 2 e. J6 @( N( M. a$ v) |
  52. case JOY_DOWN_OK:         /* 摇杆OK键按下 实现OK */                           (8)$ t1 s6 i* b! i% q( B& \
  53. GUI_SendKeyMsg(GUI_KEY_ENTER, 1);1 r: S9 u, D8 e" h
  54. break;+ Z. |' u; ~8 `2 v+ [; d6 j( w

  55.   f3 V0 g5 W" Y( B
  56. default:
    + H: V/ q" t1 Y: J
  57. /* 其它的键值不处理 */
    & K$ j% L/ f! L9 C5 c% `2 n( P& W
  58. break;
    & \& H7 ~% c9 p( R# ]$ a: y
  59. }$ Z8 E) k3 g; _% B9 u  W
  60. }
    3 B8 ?# \# r* m. X- g2 s$ [
  61.         BSP_OS_TimeDlyMs(10);" i8 v' W# w& J* T* s! ?9 _; `9 m
  62. }
    5 @$ Q: g* }  X  \( z
  63. }
复制代码
1. 按下按键1实现截图功能。
2. 实现TAB按键的功能。
3. 实现CANCEL的功能
4. 实现删除字符的功能,注意和BACKSPACE回个的区别。
5. 实现删除字符
6. 实现光标左移。
7. 实现光标右移。
8. 实现OK键功能。
STemWin主任务:
  1. #include "includes.h"0 `- P4 q' O) u. E6 _9 Z
  2. #include "MainTask.h"
    : R# ?4 S' v8 t. j# r: s8 I, ~( r0 M
  3. 7 W& w4 w+ f8 R- R7 `# k

  4. 1 i  y: O1 l" I' C4 j! x& G& F
  5. /*
    ! n) N! G& J# ]: x" x% p: x) x. W
  6. ********************************************************************************************************. @) B8 g% B- X! ]
  7. *                             静态数据
    5 M: o$ B; q3 m0 k8 D" ~2 a
  8. ********************************************************************************************************
    ; w+ d/ K. N* R/ G
  9. */& x2 A. o7 A# J, Z
  10. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = 2 P$ a, ]- C" e" q
  11. {
    % D- V: N" L- P
  12. { FRAMEWIN_CreateIndirect, "Edit winmode", 0,         90,  90, 140, 130, FRAMEWIN_CF_MOVEABLE},
    9 n: w( g6 r) q7 X! K
  13. { EDIT_CreateIndirect,     NULL,     GUI_ID_EDIT0,    10,  10, 110,  20, 0, 15},% \- `# U1 p' f8 V) L( W/ n5 B/ S
  14. { EDIT_CreateIndirect,     NULL,     GUI_ID_EDIT1,    10,  40, 110,  20, 0, 15},
    9 J9 j7 i7 s- Q6 {0 I- N/ K) f( O
  15. { BUTTON_CreateIndirect,   "Ok",     GUI_ID_OK,       10,  80,  50,  20 },3 [, h- _3 L: c4 O& G6 a8 t
  16. { BUTTON_CreateIndirect,   "Cancel", GUI_ID_CANCEL,   70,  80,  50,  20 },  S- `3 T9 r+ V! K/ d
  17. };. ~: l1 z( o* ?8 Y- \* Z- J

  18. ( C' W6 {7 p+ A& l" q1 R
  19. static char * _apExplain[] = * X1 g) O6 g/ {- S* e% O; T5 L1 J
  20. {
    2 _, b4 Q+ P6 M. w8 t0 W
  21. "This sample shows how to use edit widgets with a",& t) N8 s1 F+ j1 J$ |, z0 u' G
  22. "user defined callback function and how to set a",
      x, z; h( c8 x, F! f  {" x6 l' o9 B
  23. "user defined AddKey function. It selects the",
      U+ U+ b8 Z6 V
  24. "contents of the edit field on receiving the focus",9 u1 d. S8 ]' [" Q- V
  25. "and overwrites the contents if a key other than",
    $ v/ H. K) |1 u9 z
  26. "a cursor key is pressed.",
    , z! j3 d- V+ e( ~0 v( f% Y+ {4 d
  27. };$ \' ]2 S7 i8 ^* J
  28. 6 l# N3 |6 i. \
  29. /*3 C  V" M( I; `/ O
  30. *********************************************************************************************************
    ( z4 M* l3 g& V: k7 `
  31. *        函 数 名: _cbDialog  m( J& X' @% M1 P8 s
  32. *        功能说明: 对话框的回调函数
    8 R) V( v# E/ J  q' ^" y" Y- a
  33. *        形    参:pMsg 消息指针% k; ?9 `) }/ a' t
  34. *        返 回 值: 无
    % b( m0 C5 x0 \, Y
  35. *********************************************************************************************************8 m, J2 t7 H# Z3 {9 S+ C
  36. */
    ( h0 P/ I0 o9 P, I7 b
  37. static void _cbDialog(WM_MESSAGE * pMsg) $ @6 a' W4 h& h. l, i
  38. {2 Q* O3 L  _% s# t( Q8 p& V
  39. int     i;1 C% m3 W# f$ f: m7 n
  40. int     NCode;0 ^7 p% x, q2 p
  41. int     Id;/ B$ e) M( D7 a$ G" F4 s# l6 a
  42. WM_HWIN hDlg;
    4 L9 T2 {: u7 r6 m3 [
  43. WM_HWIN hItem;
    * f* I- u# X7 K' f) h( A
  44. # B7 k1 N! U. f0 ~
  45. hDlg = pMsg->hWin;
    ) w& m7 U, h' a" ~+ Z
  46. switch (pMsg->MsgId)
    . J: I5 i+ l8 N
  47. {
    - C8 n% b( N" I$ G1 e0 o, e0 F
  48. case WM_INIT_DIALOG:
    * q3 X% A. V6 m; d9 s9 k
  49. FRAMEWIN_SetFont(pMsg->hWin, &GUI_Font13_ASCII);
    0 ~; j: H7 m2 A* C; w9 m7 x9 V
  50. FRAMEWIN_SetTextAlign(pMsg->hWin, GUI_TA_HCENTER);. I# ?: m: N' H; h2 f! f4 L
  51. for (i = 0; i < 2; i++) ) h$ q# A2 q( w. d  d
  52. {) b  m! N4 o9 x6 Z  T7 B9 i
  53. hItem = WM_GetDialogItem(hDlg, GUI_ID_EDIT0 + i);  // Get the handle of the edit widget
    - e' X- b' {  A2 K/ R2 i$ Z# U! p
  54. }4 H: I% ?/ x- B5 R' {6 u  A: `- h8 p
  55. break;
    + v9 [  {0 p: w( r+ W) p
  56. case WM_KEY:
    ( y% f+ [" v' X$ I1 ~
  57.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) & U5 q* l* f8 x9 n" F! b( y
  58.             {
    # C3 X6 e. n+ a3 g4 o4 z3 C; V
  59. case GUI_KEY_ESCAPE:
    6 ~) p/ r! h0 i+ z8 A  ?
  60.                     GUI_EndDialog(hDlg, 1);/ \" h, c5 Q+ n- Y. S& |! f) Y+ c$ l
  61.                     break;
    ! Z) v/ E) N) b% l
  62.                 case GUI_KEY_ENTER:! @# K$ W) j' x1 K( O  {/ C
  63.                     GUI_EndDialog(hDlg, 0);1 s- W: r0 Y( f: k1 B7 A! I
  64.                     break;7 T8 L2 z& @- Q- c
  65.             }
    1 U; T8 |. Z' @7 x
  66.             break;- u  `: q# O9 r( ~. V) w1 ~1 G
  67. case WM_NOTIFY_PARENT:+ l8 u6 u- k; }8 I9 y5 N5 A5 S( d
  68. Id    = WM_GetId(pMsg->hWinSrc);      // Id of widget4 N  v/ I+ Y* P* M$ l: a; Y
  69. NCode = pMsg->Data.v;                 // Notification code- w5 O. l; m  y
  70. switch (NCode) 5 u6 Y$ C8 x- K, k
  71. {2 H/ \% `( J# m+ P
  72. case WM_NOTIFICATION_RELEASED:      // React only if released
    : j& c- x) u* `5 ?: e
  73. if (Id == GUI_ID_OK)   t" j$ q2 P8 F; {# S
  74. {         // OK Button
    # a: z/ R; I; a3 p3 _+ j
  75. GUI_EndDialog(hDlg, 0);
    - J3 _4 M7 z+ T$ U! f
  76. }
    " o$ i( a8 ^( I  f. b0 H
  77. if (Id == GUI_ID_CANCEL)
    ' t" T7 b9 `+ ^0 m% a
  78. {        // Cancel Button' ~3 j# [8 x$ `
  79. GUI_EndDialog(hDlg, 1);
    ! Z/ r9 S% [+ c( k2 ~4 M; ^5 _) A/ j
  80. }5 y. @7 r* b- H$ v) F
  81. break;0 ?7 Y! N% K+ i, q0 r: O4 r5 |
  82. }7 U4 ^0 |+ |2 i% ^8 N5 {) U
  83. break;0 Q- b0 ], ?' C" l  P1 j) r: {( G
  84. default:1 f5 s* ^3 j4 l* T( w" R3 ]
  85. WM_DefaultProc(pMsg);1 P! ~- U2 }; S$ Z
  86. }
    / f/ o# }; i/ c: s+ m1 g
  87. }
    ( ]$ m9 L# b: c# ^
  88. % R7 m# c* j( ]
  89. /*
    5 L, @7 t2 b0 V) L; C
  90. *********************************************************************************************************
    ( m% @6 \$ |4 N) p1 q
  91. *        函 数 名: _cbDesktop8 ~2 L6 X& L; v" S8 O
  92. *        功能说明: 桌面窗口的回调函数
    , K' D6 c9 r; M" y/ m" x. C9 q
  93. *        形    参:pMsg 消息指针
    2 e6 J1 H& e$ [# w% f( G
  94. *        返 回 值: 无+ p/ y# [" v/ U. p
  95. *********************************************************************************************************
    , y) Z' v7 h  z6 K8 |) g; _
  96. */
    ; v- U0 U/ ~) g. t- F% i9 @
  97. static void _cbDesktop(WM_MESSAGE * pMsg) 9 F" L% m4 P7 `1 D: ~: ]! h# N% n. r+ z
  98. {
    , D$ `- b2 G" Z
  99. unsigned i;
    8 U6 \2 h- l2 J4 Y

  100. 2 `( G% D% }- X* k
  101. switch (pMsg->MsgId) 4 r* y1 `! Q0 j2 B- ~
  102. {! [- c' F2 n/ x5 U* V. A
  103. /* 重绘 */
    9 j0 P9 O2 I' {3 ~- c
  104. case WM_PAINT:
    3 f0 @. y  ?- `) {6 j
  105. GUI_SetBkColor(GUI_RED);( x& H, z8 e- p, ?
  106. GUI_Clear();5 a4 ~# O, ~& i6 O
  107. GUI_SetFont(&GUI_Font24_ASCII);$ M) p9 \' ~2 M1 l9 Q
  108. GUI_DispStringHCenterAt("WIDGET_EditWinmode", 160, 5);& Y% q& |/ Y$ [  x% `) v. t
  109. GUI_DispNextLine();
    6 C% g; `) I: T- e) L
  110. GUI_SetFont(GUI_DEFAULT_FONT);4 B8 V/ ]* u- h# r8 j3 Z
  111. GUI_DispNextLine();" g1 P3 D0 n8 H, x
  112. for (i = 0; i < GUI_COUNTOF(_apExplain); i++) & E' |/ @" f1 i  ^/ R. ]& u# A
  113. {
    : i7 J7 F* I8 G) p
  114. GUI_DispStringHCenterAt(_apExplain[i], 160, GUI_GetDispPosY());/ C( U: P7 _! k# x- y, y* h1 c
  115. GUI_DispNextLine();
    - j1 y1 {2 p. X8 D
  116. }
    $ g1 w. v4 ^4 Y. k
  117. break;3 o& }+ @) c& y# w4 w3 Q4 _
  118. }
      W: C' r" I& s$ c% O
  119. }/ B& z$ T: @/ d1 u; w2 H; H
  120. 5 o; P2 n# o! I, W& k
  121. /*
    ' a6 G. m( e! V3 u) i1 h  Z
  122. *********************************************************************************************************
    : H. v) L8 E6 @6 P/ S& t# ~. _
  123. *        函 数 名: MainTask
    0 g( ]! W4 t" a. p6 a# w$ M
  124. *        功能说明: GUI主函数
    + [0 N7 D& |; u' t* f% k  o
  125. *        形    参:无; G# [  ]+ ~" l3 m+ `8 K; ?
  126. *        返 回 值: 无6 E# G1 l8 t2 G: C3 t4 N& e
  127. *********************************************************************************************************
    - l" u- `, a+ |- n: y: X" {
  128. */0 e. A; C6 R9 {3 a% @/ K! t$ c
  129. void MainTask(void) 1 L1 P2 t, H2 I/ S6 `$ T
  130. {
    3 x0 Q3 r3 o' c# U% |
  131. GUI_Init();: c* ^3 G) i4 V) a0 \
  132. WM_SetCallback(WM_HBKWIN, _cbDesktop);
    9 f+ w7 h% k% C' m
  133. while(1) + w7 ]6 L' \, {
  134. {% P, M0 n7 y1 [$ V7 k
  135. /* 创建阻塞式对话框 */& G0 z, Y- O: h6 B% C! F
  136. GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, 0, 0, 0);
    9 ]- z  }! G3 P( n  {, p
  137. GUI_Delay(1000);
    , x/ }# K1 A. H1 Z, }- C
  138. }' E. S  ^2 S# _. b$ N% }7 D
  139. }
复制代码
1. 上面的程序比较简单,主要是在对话框上面显示一个编辑框(初学的不要担心,后面教程会有这些控件的讲解)。
2. K1按键实现的是TAB键的功能,主要是实现对话框上面控件的聚焦切换。
    其余的按键功能比较简单,实际操作下就明白了,上面的代码中也有相应的注释。
    尝试了一下自定义按键消息没有成功,后面再试试。
3. 按键具体的通讯机制会在后面的教程中再跟大家讲解。
实际的显示效果如下:
31.2.png
31.4 总结
    本期教程就跟大家讲这么多,主要是想通过本期教程让大家对实体按键操作控件有一个了解。这个过程还需要大家对通信机制有所了解。在后面的教程中会跟大家详细讲解通信机制这块。

& C- J  h( h. Z
收藏 评论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 手机版