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

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

[复制链接]
baiyongbin2009 发布时间:2015-2-13 16:31
本帖最后由 baiyongbin2009 于 2015-2-13 16:32 编辑 7 v1 r6 s$ T( `( z. _
) L/ p8 j4 j+ ?- \" h' M0 s) Y* n- c  L
特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接
$ q6 b' m5 P- g' A. g1 ^
第31章 键盘输入(实体按键操作控件)
: _7 W" n" l" u5 G
    本期教程主要跟大家讲解键盘输入,这里我们通过开发板上面带的按键进行相关的操作,在后面会专门的做一期PS2键盘的教程。
    31. 1  描述
    31. 2 驱动层API
    31. 3 实体按键操作
    31. 4 总结

+ Z5 u) K" ?  R  \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. /*
    0 a) A0 ^' E' w# e$ g
  2. *********************************************************************************************************2 j% p8 ^8 s0 @7 G* q0 i- a
  3. *        函 数 名: AppTaskUserIF
    + h6 S! b8 e' t7 P7 D
  4. *        功能说明: 此函数主要用于得到按键的键值。
    1 W! h0 m: f! ]3 J! i
  5. *        形    参:p_arg 是在创建该任务时传递的形参
    ( D- ]0 l7 S- [2 f
  6. *        返 回 值: 无
    3 T+ s1 j" D: i- s1 h% C3 U
  7. 优 先 级:2" k  W7 m) N% Y7 Q. Q
  8. *********************************************************************************************************: D1 E! g2 s( P# f
  9. */
    + e0 o4 r# X9 p0 v& G7 O) s8 C
  10. static void AppTaskUserIF(void *p_arg)
    * `2 {" o/ v/ x8 N+ d
  11. {
    # Z: D1 U7 E) Z6 C# `, o5 |. W
  12. uint8_t ucKeyCode;8 m6 F8 s& C4 \. e

  13. 6 u; G9 A1 S1 f2 e/ h
  14. (void)p_arg;                       /* 避免编译器报警 */* X+ D0 F% }3 ^; n

  15. % X+ S" h3 h) F; L- Q8 M9 N# b" l
  16. while (1)
    9 L: w, C% i' V) B) ]* V9 L4 t
  17. {   ; J" G" ~& n# w3 ^! E3 |! d
  18. bsp_KeyScan();) o, {) G# V$ T5 Y$ I/ K' Z! C% k
  19. ucKeyCode = bsp_GetKey();
    8 \! C; S) a+ e+ W: P* [  j/ N' T  y
  20. if(ucKeyCode != KEY_NONE). Z3 {) p; z; J1 N
  21. {# f. u) e6 j9 j9 b2 M' U' w
  22. switch (ucKeyCode)  [. Z& K* ?* b* f3 h! A
  23. {
    8 p# e1 s7 n7 F# B( a& q# U/ [$ i
  24. case KEY_DOWN_K1:         /* K1键按下 实现截图*/                                (1)1 @6 E! r5 b# S
  25. BSP_OS_SemPost(&SEM_SYNCH);
    - X  Z/ n9 s( `& J+ F
  26. break;% y9 ?1 B* q. E7 H9 m7 h5 r& E. ]
  27. % D/ ?6 ~/ |# ]5 A# N1 g
  28. case KEY_DOWN_K2:         /* K2键按下 实现TAB按键的功能*/                      (2)
    6 ?7 ?, v7 S, a6 |* e5 V3 ]
  29. GUI_SendKeyMsg(GUI_KEY_TAB, 1);
    $ R6 e8 o% R; Q) c# L& f2 K
  30. break;
    ! z" g7 g! O* B) w6 }* K+ c

  31. ' e3 \' ?0 H* M$ V1 s- b) ?- _7 C
  32. case KEY_DOWN_K3:         /* K3键按下 实现CANCEL的功能 */                      (3)
    0 o2 T0 T: y7 v) E2 e
  33. GUI_SendKeyMsg(GUI_KEY_ESCAPE, 1);. n1 G6 R& G5 b8 L0 i6 z
  34. break;  q* z( D. w" W. T  R7 G5 d1 u, x
  35. (4)" I8 s3 D/ X1 I2 p2 r2 J: F, l* k
  36. case JOY_DOWN_U:         /* 摇杆UP键按下 实现删除字符功能,注意和BACKSPACE回格的区别*/
    : G8 U  u, @) q& _3 F1 q3 @
  37. GUI_SendKeyMsg(GUI_KEY_DELETE, 1);# Y( ^/ j( m  g8 a; j" |
  38. break;
    ! j; F+ ^- P) h: z2 _

  39. 7 J/ Z2 Q$ a5 h: c
  40. case JOY_DOWN_D:         /* 摇杆DOWN键按下 实现删除字符 */                    (5)  N5 {, G3 V7 V
  41. GUI_SendKeyMsg(GUI_KEY_BACKSPACE, 1);) v' Z2 @7 B4 m- r( Y
  42. break;* y% ?3 k  q- S5 q- l6 g& [+ g

  43. " w) m" y/ A( N% b2 z2 c' G
  44. case JOY_DOWN_L:         /* 摇杆LEFT键按下 实现光标左移 */                    (6)
    8 x3 l" \; a' n4 W+ k* _
  45. GUI_SendKeyMsg(GUI_KEY_LEFT, 1);* D) u- c" t( y4 D
  46. break;
    ' X" V( Y% P& }! [# O# _8 Q5 \: o# W
  47. - ]! s  k. s9 X. F% c- c$ C, A, A
  48. case JOY_DOWN_R:         /* 摇杆RIGHT键按下 实现光标右移 */                   (7)
    - m" J9 _/ g# @5 f6 J1 D
  49. GUI_SendKeyMsg(GUI_KEY_RIGHT, 1);5 m4 N7 h" E( m/ l  n
  50. break;. {- ^& R+ I6 {( v! l, Q- y2 R- n
  51. / ]+ [3 Q7 d5 f
  52. case JOY_DOWN_OK:         /* 摇杆OK键按下 实现OK */                           (8)! @4 m. b3 |) m# s( e  t# X6 t" O0 T
  53. GUI_SendKeyMsg(GUI_KEY_ENTER, 1);
    ' l, T% R% i" x7 m7 j
  54. break;
    & s* W3 I, Z  t7 f0 D: D; ^

  55. ' F6 @9 M+ E. `( K( d/ ]  ^
  56. default:6 }, C+ z- s2 n6 L/ `' G0 s, I
  57. /* 其它的键值不处理 */
    & V6 @% b& D: `& k6 T/ K. M
  58. break;
    9 t1 a, ?/ O) ~  K  Q
  59. }; x3 W6 C- k7 ~% s
  60. }1 a5 b$ p' e9 h, d4 V
  61.         BSP_OS_TimeDlyMs(10);
    # ~. X* w- o* K0 R  W! \
  62. }  q& I$ p: K0 \
  63. }
复制代码
1. 按下按键1实现截图功能。
2. 实现TAB按键的功能。
3. 实现CANCEL的功能
4. 实现删除字符的功能,注意和BACKSPACE回个的区别。
5. 实现删除字符
6. 实现光标左移。
7. 实现光标右移。
8. 实现OK键功能。
STemWin主任务:
  1. #include "includes.h"* @0 A2 D1 I8 X+ s
  2. #include "MainTask.h"$ }/ K  R7 x# Z5 X. z5 o" i9 F
  3. , m' H% K% T, U3 a$ w
  4. $ d  U3 ]  U$ f' R2 E
  5. /*8 ^% @9 J; S! X. G5 |
  6. ********************************************************************************************************& N) k6 Y& O1 w) T$ h; E
  7. *                             静态数据. J8 U" P/ o2 }
  8. ********************************************************************************************************) `) t) |+ `3 D' k% Z
  9. */+ _7 L) k0 L9 G1 q8 R
  10. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
    " K1 k/ d' D- j# @" `2 n% T
  11. {
    1 C5 m  S% }  f4 g7 D) V0 t, r
  12. { FRAMEWIN_CreateIndirect, "Edit winmode", 0,         90,  90, 140, 130, FRAMEWIN_CF_MOVEABLE},
    ( D7 V8 i9 A8 ^9 D( [5 L) r* @
  13. { EDIT_CreateIndirect,     NULL,     GUI_ID_EDIT0,    10,  10, 110,  20, 0, 15},
    ( V4 N% N! M' q
  14. { EDIT_CreateIndirect,     NULL,     GUI_ID_EDIT1,    10,  40, 110,  20, 0, 15},/ R5 R5 h. |. {1 }% V% m8 @
  15. { BUTTON_CreateIndirect,   "Ok",     GUI_ID_OK,       10,  80,  50,  20 },
    0 t! L5 D- K  i0 Y
  16. { BUTTON_CreateIndirect,   "Cancel", GUI_ID_CANCEL,   70,  80,  50,  20 },. h+ w, H. o6 T2 l
  17. };
    ) u1 p# j% L) b8 f

  18. . ?( P0 _* B! `& o
  19. static char * _apExplain[] = 0 f. y1 E; [# Q
  20. {
    0 O  p" z: u  E3 w: B4 K. l  ]4 O
  21. "This sample shows how to use edit widgets with a",
    6 X9 }' L+ S9 _) K3 G
  22. "user defined callback function and how to set a",4 ?' h( c! J- b4 ^+ Q  O
  23. "user defined AddKey function. It selects the",4 r5 O. B( h; g3 ^4 B& R9 v& k
  24. "contents of the edit field on receiving the focus",
    $ b) i3 l8 o" R$ O& W' o9 d4 k
  25. "and overwrites the contents if a key other than",4 x+ A: i4 C# L. P* p+ C
  26. "a cursor key is pressed.",' G' |. O) L/ v9 m
  27. };
    ) _9 C0 Z: H' K, u5 n) K: D2 H
  28. , d/ h" P* d! {  b/ I3 L
  29. /*6 X) c, ~) o! ?" D' [" _- y& T
  30. *********************************************************************************************************
    * Y# ^' R% t! [4 `1 [+ F* s3 U
  31. *        函 数 名: _cbDialog) g2 g* V  H$ q
  32. *        功能说明: 对话框的回调函数  M! h5 H7 `" }# t; D; ?( p
  33. *        形    参:pMsg 消息指针0 X# M' \' W3 @- {0 v) r$ k0 b
  34. *        返 回 值: 无) J/ M# q* k7 m9 R% N) `
  35. *********************************************************************************************************# F- U$ _' O; E: q6 ^1 `
  36. */
    2 m( k" G+ R# I. S* U/ |' }4 A
  37. static void _cbDialog(WM_MESSAGE * pMsg) 6 O) {2 v6 \: z/ X- ?3 h% D1 X: D/ q
  38. {2 q  Z  Q+ h6 ]8 E
  39. int     i;
    8 C3 f+ T7 p; ^
  40. int     NCode;/ J1 \3 w  [' H+ i  }  x6 _5 ?
  41. int     Id;
    , u0 A" K, {1 x: R; o
  42. WM_HWIN hDlg;5 v7 y* R, w3 L' H' j5 D: y, @3 {* ?
  43. WM_HWIN hItem;
    9 |- J) c# [0 s: G5 `% V) E/ w
  44. & p  {  u7 c# x2 M+ V8 {
  45. hDlg = pMsg->hWin;
    7 S2 S& ~3 z# f) Q& q1 m
  46. switch (pMsg->MsgId)
    , e0 _0 |5 }9 B1 ]( E
  47. {
    - f. d6 a7 S. D% K8 n
  48. case WM_INIT_DIALOG:
    : a2 t5 R- x6 \2 C4 Y0 D
  49. FRAMEWIN_SetFont(pMsg->hWin, &GUI_Font13_ASCII);
    6 c2 W8 h3 j) v5 v! |6 w& P
  50. FRAMEWIN_SetTextAlign(pMsg->hWin, GUI_TA_HCENTER);
    * Z" L$ U$ i% ~8 c, ~2 `+ m
  51. for (i = 0; i < 2; i++)
    8 d, K+ Z; S  A% A" ^  t6 _9 P
  52. {
    , o0 h% l8 V' h- V' L8 Z$ g( d9 y
  53. hItem = WM_GetDialogItem(hDlg, GUI_ID_EDIT0 + i);  // Get the handle of the edit widget
    2 w6 Q6 u: i7 `; M. h1 i8 B
  54. }5 i) ~: o9 i9 B* {+ c
  55. break;
    8 k) R, ?0 J$ }8 r
  56. case WM_KEY:
    ' U! p: R7 [1 o
  57.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) 2 r/ v3 k+ z. n" @
  58.             { " ~/ y, s# h! F& X
  59. case GUI_KEY_ESCAPE:
    , H! E7 P, H2 w3 g  n! g2 d( A4 |
  60.                     GUI_EndDialog(hDlg, 1);
    2 D/ D0 r+ Q% Z$ D7 t
  61.                     break;
    & H7 Q5 G5 `% M! m9 W
  62.                 case GUI_KEY_ENTER:
    4 S/ J3 t- o- I9 r! M8 M
  63.                     GUI_EndDialog(hDlg, 0);% f& w( f3 H3 Q+ Z# P% ]
  64.                     break;6 {' {. o1 Y  m  e
  65.             }
    6 S+ p) L2 J. v9 p- D
  66.             break;3 y) ]- h; m, F. @, j; T5 z, A% r
  67. case WM_NOTIFY_PARENT:- h8 F: y7 b5 V$ R6 L0 r( C
  68. Id    = WM_GetId(pMsg->hWinSrc);      // Id of widget# E3 [3 ]9 }8 ~. H: X, }
  69. NCode = pMsg->Data.v;                 // Notification code* }; Z4 H, l: ^3 `2 B
  70. switch (NCode) - J: m5 C6 H" k- [7 l& K  X7 y
  71. {1 W1 O8 h; Z3 _8 |$ _* C
  72. case WM_NOTIFICATION_RELEASED:      // React only if released
    7 J2 o. a2 k" Z6 f/ I- q1 U
  73. if (Id == GUI_ID_OK) 6 v" w* o  ^9 J
  74. {         // OK Button
    % }+ k! [) a( z" ~
  75. GUI_EndDialog(hDlg, 0);
    2 v& h+ M/ G/ S0 f: @1 t' m
  76. }/ y9 R% c. \/ B
  77. if (Id == GUI_ID_CANCEL) % F! @3 z+ f/ }$ P4 {1 _- S# ?
  78. {        // Cancel Button
    8 B2 Z# r0 |+ |7 @4 I) j
  79. GUI_EndDialog(hDlg, 1);: T+ _4 D% U  n  j) H, j+ U
  80. }
    ' d+ |+ m# ^9 D% k# D# D( g
  81. break;- W6 G/ y% l0 ?, X) D; t/ @+ {  u/ b
  82. }$ t% ?, D1 {* ]+ x' ], i
  83. break;$ S) l! U$ j$ S; f3 Y6 h. ^
  84. default:
    & Y4 }9 x# B" K+ w  \: `6 P
  85. WM_DefaultProc(pMsg);
    , J. G9 r! u$ I8 S7 Z- N; O2 n$ d% g
  86. }
    9 M5 Y0 I; a! ^: _+ i  {
  87. }8 _% ~: c! S/ I+ T9 m# j8 p0 E

  88. & e6 h4 u4 N( L( U
  89. /*
    8 Z& w, u0 ~( \8 x* [
  90. *********************************************************************************************************
    ) w3 J( H" c" I
  91. *        函 数 名: _cbDesktop
      M: x. v" i) f- g4 ]# W3 A5 E
  92. *        功能说明: 桌面窗口的回调函数' }& J4 h5 g) B" D) U, I$ L& m! _
  93. *        形    参:pMsg 消息指针
    / q2 k3 g5 K- M& G
  94. *        返 回 值: 无
    - z/ \) f' g8 p2 M: B# X
  95. *********************************************************************************************************, A% G. `: j' V* g& D$ j
  96. */+ @+ C# ]: X1 u7 A9 ~1 V9 E
  97. static void _cbDesktop(WM_MESSAGE * pMsg) : ~6 q7 a& O1 @' f/ y
  98. {
    % w& B. w2 I+ I; U6 X+ z
  99. unsigned i;
    / F% i! p3 _1 n  L
  100. : G# l7 d# N" c0 @9 [# W
  101. switch (pMsg->MsgId)
    : T! ^3 E7 _. b  V) L2 ?
  102. {
    - ], l$ s' v1 e* i
  103. /* 重绘 */
    ) O' z5 P* V% e2 J/ B
  104. case WM_PAINT:
    , K( L  t. T5 T: b* z
  105. GUI_SetBkColor(GUI_RED);
    ( X* N4 A$ w  X* n) ?& ~' ~
  106. GUI_Clear();
    4 P8 c2 m# M  Z" c0 d8 N, p
  107. GUI_SetFont(&GUI_Font24_ASCII);7 P( U8 i' d- X
  108. GUI_DispStringHCenterAt("WIDGET_EditWinmode", 160, 5);, X9 k! C9 k; [' E
  109. GUI_DispNextLine();
    4 M+ Z5 f8 d9 N
  110. GUI_SetFont(GUI_DEFAULT_FONT);
    4 E" C# @6 y' v/ |% X+ C+ w' A
  111. GUI_DispNextLine();; r' L3 F# Y7 j
  112. for (i = 0; i < GUI_COUNTOF(_apExplain); i++) 9 ]) ^- e1 p3 i# l- p) N& j. K
  113. {  b% Z. {0 x& q2 R
  114. GUI_DispStringHCenterAt(_apExplain[i], 160, GUI_GetDispPosY());; N7 X9 D# T( T4 W2 G- ^2 s" A
  115. GUI_DispNextLine();
    + v/ S& R+ N* D5 U
  116. }6 ?1 H7 }2 T; x& v1 @, k
  117. break;
    $ I" s. E& P7 \5 M7 h! X6 J. z
  118. }
    ) [- Y# M# p, `
  119. }
    " z( ^3 h. x' G: s3 b$ m
  120. # f* ^; H2 y6 k9 u
  121. /*  A# ^% P$ B9 ^- S' T; |
  122. *********************************************************************************************************4 z7 \5 i, e$ Q, s9 [
  123. *        函 数 名: MainTask
    ' {: f' U0 }! [3 L
  124. *        功能说明: GUI主函数
    ' n; o3 c7 ]$ e% T2 O' A# u7 G
  125. *        形    参:无
    7 _6 y( y0 T/ ~# C. `
  126. *        返 回 值: 无
    3 K$ B4 ?4 p; }. d, x% C: r' _+ b
  127. *********************************************************************************************************. a! P  f/ b% r8 t
  128. */
    / j% i# v; o! Q8 ]' W1 `' |, e
  129. void MainTask(void) % F) N/ c! _- S- E% d
  130. {
    5 U  {- l4 L' @( c3 W2 F0 p
  131. GUI_Init();1 I% Q0 a" q( r- j
  132. WM_SetCallback(WM_HBKWIN, _cbDesktop);$ l* _- I( a  G0 D
  133. while(1) - ]7 e, @# T! O0 @
  134. {
    % w2 w/ @& l# w. b
  135. /* 创建阻塞式对话框 */
    5 K$ V: Y0 X& l0 }
  136. GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, 0, 0, 0);1 S* I* \8 z1 D$ k: l
  137. GUI_Delay(1000);
    $ m# m0 z; ^) f: U6 v
  138. }0 _9 \8 Y0 X/ b6 z
  139. }
复制代码
1. 上面的程序比较简单,主要是在对话框上面显示一个编辑框(初学的不要担心,后面教程会有这些控件的讲解)。
2. K1按键实现的是TAB键的功能,主要是实现对话框上面控件的聚焦切换。
    其余的按键功能比较简单,实际操作下就明白了,上面的代码中也有相应的注释。
    尝试了一下自定义按键消息没有成功,后面再试试。
3. 按键具体的通讯机制会在后面的教程中再跟大家讲解。
实际的显示效果如下:
31.2.png
31.4 总结
    本期教程就跟大家讲这么多,主要是想通过本期教程让大家对实体按键操作控件有一个了解。这个过程还需要大家对通信机制有所了解。在后面的教程中会跟大家详细讲解通信机制这块。
7 G( U: n. u1 L$ |! c9 X% l
收藏 评论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 手机版