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

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

[复制链接]
baiyongbin2009 发布时间:2015-2-13 16:31
本帖最后由 baiyongbin2009 于 2015-2-13 16:32 编辑 5 _  E. S5 G: Z" W! k% a- }

- B4 F( i# L: E特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接/ K4 r; Q; ~' M8 X4 R6 |% ?! @
第31章 键盘输入(实体按键操作控件)
* d% O% o7 h$ B+ M
    本期教程主要跟大家讲解键盘输入,这里我们通过开发板上面带的按键进行相关的操作,在后面会专门的做一期PS2键盘的教程。
    31. 1  描述
    31. 2 驱动层API
    31. 3 实体按键操作
    31. 4 总结
$ ~8 m% u5 I# [# U+ V3 e4 S
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. /*' @& O0 l, U  r, g8 i# {; `  x5 `
  2. *********************************************************************************************************
    2 p6 r& l7 `5 c4 n( W) C  p
  3. *        函 数 名: AppTaskUserIF
    7 N- v/ a( b2 a! S. Z
  4. *        功能说明: 此函数主要用于得到按键的键值。
    3 f# o1 K4 n7 w2 ~: m9 G4 E
  5. *        形    参:p_arg 是在创建该任务时传递的形参' n* k- U' i" r
  6. *        返 回 值: 无
    + D! t9 ]. Y3 X6 j  a
  7. 优 先 级:23 [1 Y( n' T4 s. W. ?& r% [
  8. *********************************************************************************************************4 G3 W7 w& }. Q9 B
  9. */" h- I/ [0 a6 q) _) {& O) X& i
  10. static void AppTaskUserIF(void *p_arg)
    / q) o& i1 e7 x8 _' |1 R
  11. {
    9 j3 M" W% K* p) v" u0 i8 i" s, [
  12. uint8_t ucKeyCode;
    ) G) i* v7 e# e
  13. % `1 \8 u9 O# l! {$ y
  14. (void)p_arg;                       /* 避免编译器报警 */2 v: a: a6 D5 L; ~6 ~
  15. 1 D- @& P5 Q2 A, M: t
  16. while (1) * E9 ~' l: `( V1 C
  17. {   9 h( r- s3 c/ H
  18. bsp_KeyScan();, Y! D5 E% V. A2 q" `/ Z
  19. ucKeyCode = bsp_GetKey();# r9 c0 e( e/ }- f
  20. if(ucKeyCode != KEY_NONE)
    1 ~3 Z  J, {* W  B/ D7 k2 {- S
  21. {
    ) c. T1 x5 i% d' N; Y
  22. switch (ucKeyCode)
    5 ~: B+ f! Q2 F- Q# J& H
  23. {
    ) {. f( R4 v4 [( ~
  24. case KEY_DOWN_K1:         /* K1键按下 实现截图*/                                (1)
    " d& g) ^/ \: F, C4 u, x
  25. BSP_OS_SemPost(&SEM_SYNCH);
    3 C$ M2 G- _. p0 n: F* r$ S
  26. break;
    ; ~$ m+ T# c3 X: G- r

  27. ( ~8 [, S2 M0 F5 S* p! G1 h* n
  28. case KEY_DOWN_K2:         /* K2键按下 实现TAB按键的功能*/                      (2). G; @2 W  y" k! f
  29. GUI_SendKeyMsg(GUI_KEY_TAB, 1);8 [6 a" u8 b0 W
  30. break;
    & N+ e. H7 c( v* y! D* a
  31. 1 [$ _! `5 D: D) I* ~& @) N" i9 M
  32. case KEY_DOWN_K3:         /* K3键按下 实现CANCEL的功能 */                      (3)
    $ [$ S1 y8 y  P% i' K
  33. GUI_SendKeyMsg(GUI_KEY_ESCAPE, 1);+ a( M/ X% Q8 X3 ?
  34. break;
    ( t" x( e$ h9 X3 O- z  R  M
  35. (4)
    4 D2 ^; k: }, A3 G2 Z
  36. case JOY_DOWN_U:         /* 摇杆UP键按下 实现删除字符功能,注意和BACKSPACE回格的区别*/* S; l3 w# E& Y3 K  f: F  W) W
  37. GUI_SendKeyMsg(GUI_KEY_DELETE, 1);/ u  J4 u/ v. a6 ~- G) S
  38. break;
    5 V% u6 A& p- t/ x9 Q. Y

  39. & p3 w' v) ~% J. i. |, p
  40. case JOY_DOWN_D:         /* 摇杆DOWN键按下 实现删除字符 */                    (5)# l) ^0 S! ~  [1 j! N
  41. GUI_SendKeyMsg(GUI_KEY_BACKSPACE, 1);
    6 N- I, q: i; L: w
  42. break;4 b6 P" z9 x4 n- a, k) B; _, B7 @
  43.   M+ W4 r1 Q/ K6 H, U
  44. case JOY_DOWN_L:         /* 摇杆LEFT键按下 实现光标左移 */                    (6)  Q1 M2 S  b8 A
  45. GUI_SendKeyMsg(GUI_KEY_LEFT, 1);
    0 p1 @# f: H. h% p! Z$ M! S  [1 K
  46. break;
    4 B9 w5 U' [8 A5 C  O

  47. 9 U& d( S7 l+ |3 a. A
  48. case JOY_DOWN_R:         /* 摇杆RIGHT键按下 实现光标右移 */                   (7)7 C, f; m# J: J. z
  49. GUI_SendKeyMsg(GUI_KEY_RIGHT, 1);
    9 L$ e; Y9 `) L4 c
  50. break;! ?4 H& p' D7 y! G% n" J1 C+ d
  51. . E, [" @3 `4 D
  52. case JOY_DOWN_OK:         /* 摇杆OK键按下 实现OK */                           (8)/ U* Y1 u+ O0 }' L
  53. GUI_SendKeyMsg(GUI_KEY_ENTER, 1);6 R- J4 n3 ~- [6 I2 h7 K
  54. break;6 T  ^+ O  P5 e: F' j4 F% B: g

  55. ' |0 a2 k/ @9 T3 {/ ^7 _) N
  56. default:# i4 y! ]+ a" }( U. B4 C( {
  57. /* 其它的键值不处理 */8 [6 N- @' E2 _" S' {- e& E
  58. break;+ y' [% w. E$ o  |. i1 B) H9 R' f
  59. }( |9 |' X1 W# Y9 l+ L' P# ^# n2 A
  60. }* x/ t3 J4 h- J. ~1 L+ w
  61.         BSP_OS_TimeDlyMs(10);) p1 {1 j* T( ]/ L7 w
  62. }' h% s. u6 v1 @( Q) x
  63. }
复制代码
1. 按下按键1实现截图功能。
2. 实现TAB按键的功能。
3. 实现CANCEL的功能
4. 实现删除字符的功能,注意和BACKSPACE回个的区别。
5. 实现删除字符
6. 实现光标左移。
7. 实现光标右移。
8. 实现OK键功能。
STemWin主任务:
  1. #include "includes.h"4 u! Z( t1 U3 j3 [( A! L- \
  2. #include "MainTask.h"6 f0 q3 u3 r( W3 t7 M& L8 {! p6 d" A
  3. " B1 |+ m# L3 X3 f/ Z

  4. : l+ O4 M4 I4 q, f4 T) O; K! G
  5. /*
    , \1 ^1 Y0 c. E; s, B9 J
  6. ********************************************************************************************************' h5 ?% Z, O3 \4 W! o
  7. *                             静态数据# p8 U! C. R$ W' f3 Y; }
  8. ********************************************************************************************************
    9 g9 J# J$ I& N9 I; i$ n
  9. */
    " X# j# P% e3 d7 B
  10. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = 7 b* E! G( f% D9 m: Y+ l1 n! t
  11. {
    / A1 A5 {$ r- {; e
  12. { FRAMEWIN_CreateIndirect, "Edit winmode", 0,         90,  90, 140, 130, FRAMEWIN_CF_MOVEABLE},
    ; L( Q. a: ~5 \
  13. { EDIT_CreateIndirect,     NULL,     GUI_ID_EDIT0,    10,  10, 110,  20, 0, 15},
    * v% I0 Y! m! A8 i' W* d
  14. { EDIT_CreateIndirect,     NULL,     GUI_ID_EDIT1,    10,  40, 110,  20, 0, 15},
    6 b* h9 D" `/ @4 w& n
  15. { BUTTON_CreateIndirect,   "Ok",     GUI_ID_OK,       10,  80,  50,  20 },. M: t3 a9 Y- W+ E/ ?. ]# }
  16. { BUTTON_CreateIndirect,   "Cancel", GUI_ID_CANCEL,   70,  80,  50,  20 },$ `  v/ c7 }6 d4 O) p# M  \/ [
  17. };
    ' P' a' V, z* O8 }  ^/ ?$ A1 M
  18. . l7 C, o7 X# B( L/ n
  19. static char * _apExplain[] =
    5 [' Z  X2 I8 C
  20. {! {. O8 f1 U, y! x" {* N/ _
  21. "This sample shows how to use edit widgets with a",6 F3 e" v; I& d* B. D: a5 l, s
  22. "user defined callback function and how to set a",6 e0 j5 M6 z1 ^! o* F6 ?& B
  23. "user defined AddKey function. It selects the",! }9 k' Z: B6 N6 _4 P8 a0 \$ x$ g
  24. "contents of the edit field on receiving the focus",
    - _* d! k/ o& x) X
  25. "and overwrites the contents if a key other than",1 s& K$ C2 A6 z! ?5 ^) ?# H8 h& |
  26. "a cursor key is pressed.",7 v  G0 P6 j( Q- X% z
  27. };
      o& m; S$ Z6 K

  28. - b, p4 H& E  [6 O' F
  29. /*
    , D% m  P$ Q$ N# ?
  30. *********************************************************************************************************
    9 J9 \% V' p/ s
  31. *        函 数 名: _cbDialog0 q2 X1 y& V; a$ S3 c$ s
  32. *        功能说明: 对话框的回调函数. G6 z( b. L: Q
  33. *        形    参:pMsg 消息指针
    ( C1 f% X+ P8 r3 R& y
  34. *        返 回 值: 无! s# A4 |) }$ |; O( I: {
  35. *********************************************************************************************************
    : C* v7 \9 G8 Y- t# o
  36. */
    . A; c. E1 r) n; r, V2 q' W
  37. static void _cbDialog(WM_MESSAGE * pMsg) 6 G  v# C% e+ A2 _  ^
  38. {
    2 `* [7 D9 c1 M0 p
  39. int     i;
    1 J  m4 K8 K$ I8 N3 p
  40. int     NCode;3 H! d5 q! C2 m
  41. int     Id;
    + S' ?$ a! t" A/ \; s: W* Y
  42. WM_HWIN hDlg;2 p' z9 B0 T( q
  43. WM_HWIN hItem;0 Z& Q6 {5 Y9 e# e: r

  44. 7 h* Y& f- j9 z& o! E. ^3 |& m
  45. hDlg = pMsg->hWin;
    9 ]  ?  M3 ~# n% Y' [
  46. switch (pMsg->MsgId) 5 m# N+ N4 w0 W
  47. {
    " S8 `" j9 V8 |8 X5 p
  48. case WM_INIT_DIALOG:) o0 A4 f: u" K, E0 H
  49. FRAMEWIN_SetFont(pMsg->hWin, &GUI_Font13_ASCII);
    % p% V; _; Y# R0 K& n4 g9 c
  50. FRAMEWIN_SetTextAlign(pMsg->hWin, GUI_TA_HCENTER);
    0 ]( m* R' Y! ~8 H) V" Q
  51. for (i = 0; i < 2; i++) ! ^  \+ x- y1 H
  52. {8 Q+ E# Y' V8 M+ Z
  53. hItem = WM_GetDialogItem(hDlg, GUI_ID_EDIT0 + i);  // Get the handle of the edit widget1 U$ e1 z1 l( y' Y9 g3 ^* v$ H
  54. }
    : z# f0 G; w  ?' P2 {
  55. break;& [; p; A: H( n  q; i
  56. case WM_KEY:0 H. Z3 t7 z& J! }5 z( A
  57.             switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key)
    2 U  b) y0 W* a- v2 _, K
  58.             {
    : o  B7 P3 i- f
  59. case GUI_KEY_ESCAPE:
    5 G" d/ b; }: c6 A# T
  60.                     GUI_EndDialog(hDlg, 1);
    & U. X8 h- p7 U. x" x
  61.                     break;
    3 O* D1 q6 v5 s  z9 x
  62.                 case GUI_KEY_ENTER:- W2 {3 V. J2 o6 B& _
  63.                     GUI_EndDialog(hDlg, 0);
    % }) g& ]) C! P6 U
  64.                     break;! \" P; P" }! T% A1 d
  65.             }
    8 R; ~& K+ [- d4 b' ~
  66.             break;4 s! |) e! B5 C# s
  67. case WM_NOTIFY_PARENT:2 K6 O) S' c5 \% _. ^" b: \
  68. Id    = WM_GetId(pMsg->hWinSrc);      // Id of widget
    . I# Z. e) h% e0 A- f
  69. NCode = pMsg->Data.v;                 // Notification code; l- d3 K* X# Y% c. m, v0 J
  70. switch (NCode) # t  ~4 q2 S: Q8 _: t" P; w7 G
  71. {
    ' u% j% [5 f8 N. D6 @
  72. case WM_NOTIFICATION_RELEASED:      // React only if released
    8 |6 H; D" S% K* M# u
  73. if (Id == GUI_ID_OK)
    ) [! I8 X1 Y% P3 r  |
  74. {         // OK Button
    : X1 _& c" A! }8 a
  75. GUI_EndDialog(hDlg, 0);. m( c$ i6 ^5 P; Z/ t
  76. }
      O% \; @, ^+ \% n! Y* z4 u
  77. if (Id == GUI_ID_CANCEL)
    ! N: r9 o; U8 ~: Y% j
  78. {        // Cancel Button
    ( Z. G) V6 K4 ~0 r4 q
  79. GUI_EndDialog(hDlg, 1);) K: c& f3 j, D$ L
  80. }
    & |- {+ X9 @/ _9 j, v0 R
  81. break;, y, S+ c2 Y2 o3 ?: z8 u
  82. }7 L1 g6 u& [6 Y* y6 ?6 ~- C7 _  c
  83. break;
    1 a+ a: @3 P; s  Y! s
  84. default:8 K  \# G& P2 }6 E
  85. WM_DefaultProc(pMsg);
    / D" _; }# {& e3 D) }
  86. }+ `- ?6 h0 @" z7 f3 W: }. U$ }: \+ V
  87. }
    , a# w5 a/ F' l
  88. ( j* k/ N! ?* ?5 ]$ p  {' d) D
  89. /*
    / O% f# s- w: U. [
  90. *********************************************************************************************************; C7 D7 V! H+ k1 n- Y2 j
  91. *        函 数 名: _cbDesktop
    : g6 G0 G1 d. g/ N/ l7 n
  92. *        功能说明: 桌面窗口的回调函数& n( y4 b9 {' W
  93. *        形    参:pMsg 消息指针
    % ^) o2 g4 q. {1 z. Q; a; I0 j
  94. *        返 回 值: 无
    3 s# z1 Z* A; ~! K( y; K
  95. *********************************************************************************************************
    5 V, \. Q! \( W8 {% n4 J
  96. */( x( x; I6 X5 @* Q+ F% Y
  97. static void _cbDesktop(WM_MESSAGE * pMsg) : O4 C$ q- @9 o0 Y0 e, G- k  b
  98. {$ \9 {5 o* w/ C( x  p
  99. unsigned i;7 l! i5 ^1 ]3 j/ [
  100. - k' e, s( p, P0 K6 n) X
  101. switch (pMsg->MsgId)
    9 W8 Q/ j3 y6 J( E/ y  U
  102. {
    1 k/ i) }- W4 q9 L7 l
  103. /* 重绘 */
    1 ^% N7 J, p& I2 {. s
  104. case WM_PAINT:
    / p1 u( R+ v4 a
  105. GUI_SetBkColor(GUI_RED);
    , ]. Q& O. H: I) ^9 n; {
  106. GUI_Clear();
    5 E3 G& r# q7 p- V( u7 u
  107. GUI_SetFont(&GUI_Font24_ASCII);
    & E8 J# p# ^# o$ u6 H$ X) L
  108. GUI_DispStringHCenterAt("WIDGET_EditWinmode", 160, 5);4 X# G7 _+ p$ T4 ]: u
  109. GUI_DispNextLine();/ o( e7 A  K4 g  R
  110. GUI_SetFont(GUI_DEFAULT_FONT);1 h' s% p7 l8 U8 @- M
  111. GUI_DispNextLine();
    7 n. a4 U  E5 z
  112. for (i = 0; i < GUI_COUNTOF(_apExplain); i++) # y4 L0 K; w/ w
  113. {' z. j; J; C( l/ A8 c" j
  114. GUI_DispStringHCenterAt(_apExplain[i], 160, GUI_GetDispPosY());# B* c2 N/ T. p8 d9 V
  115. GUI_DispNextLine();2 ]) s2 f  U' H( V
  116. }8 C2 S8 }& P2 e2 ~/ P
  117. break;
    + ]# E3 @' N* P$ o6 [
  118. }, c2 ^; y6 R9 s: a) ^
  119. }, ~3 M: s* B  v' s' ~! |( L2 ]0 M+ d
  120. 1 Q. Y$ g+ Q0 o$ n3 m: Z
  121. /*$ y- W2 j- m- Z) h- |
  122. *********************************************************************************************************/ x. E+ D5 v% X; |+ ~
  123. *        函 数 名: MainTask
    1 C# v, ~7 C. c# M" q4 I9 T
  124. *        功能说明: GUI主函数
    : K; q0 T) A; |2 Z. G& ^
  125. *        形    参:无
    6 ]; y" {* f# `0 u, m
  126. *        返 回 值: 无
    5 P# H1 \9 N* B8 u# H" w9 w
  127. *********************************************************************************************************; |0 {; h, F: z) _; ?+ N4 l0 c
  128. */
    * b3 G; x) H# \0 n( v
  129. void MainTask(void) ! [% _/ R8 [# K! m3 ?2 G5 {+ L5 s
  130. {, j" {# P3 u9 f
  131. GUI_Init();) M" K$ T( j( j/ I+ _- z6 j9 C% u+ ?  y
  132. WM_SetCallback(WM_HBKWIN, _cbDesktop);
    ! y# L* M5 F2 [; V1 U) q7 Q
  133. while(1) ! v0 H* l, y$ [$ \4 U: `
  134. {
    ' {9 ]$ V& A- R- P& P5 t6 g% u
  135. /* 创建阻塞式对话框 */0 u9 h- C: ^: s* \9 H
  136. GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, 0, 0, 0);8 t/ @+ `7 x' B( I/ Q% [
  137. GUI_Delay(1000);
    & H3 C" ?, ?4 ]7 Q
  138. }. p2 I0 z- [, c1 p
  139. }
复制代码
1. 上面的程序比较简单,主要是在对话框上面显示一个编辑框(初学的不要担心,后面教程会有这些控件的讲解)。
2. K1按键实现的是TAB键的功能,主要是实现对话框上面控件的聚焦切换。
    其余的按键功能比较简单,实际操作下就明白了,上面的代码中也有相应的注释。
    尝试了一下自定义按键消息没有成功,后面再试试。
3. 按键具体的通讯机制会在后面的教程中再跟大家讲解。
实际的显示效果如下:
31.2.png
31.4 总结
    本期教程就跟大家讲这么多,主要是想通过本期教程让大家对实体按键操作控件有一个了解。这个过程还需要大家对通信机制有所了解。在后面的教程中会跟大家详细讲解通信机制这块。
, m0 N# S- S8 E7 \5 I
收藏 评论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 手机版