特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接% u" b5 Z0 q' B6 X: Z
第36章 窗口管理器之定时器使用 , b) W/ n( i. W5 d
本期教程跟大家讲一下STemWin自带的定时器使用方法,这个定时器使用起来非常简单,而且很实用。在需要定时更新的时候可以用这个定时器。 36. 1 定时器功能介绍 36. 2 桌面窗口上使用定时器实例 36. 3 对话框上使用定时器实例 36. 4 总结 36.1 定时器功能介绍 STemWin中有四个定时器相关的API函数供用户调用。 这四个函数都是简单易用,下面通过两个例子跟大家讲解一下定时器的使用。 36.2 桌面窗口上使用定时器实例 源代码如下(可以将其直接的复制到开发板或者模拟器上面运行) - #include <stddef.h>
1 K( {# t2 w) J4 `; V$ ?0 g& { - #include "GUI.h"
8 x) ]6 d5 T' G6 x: O! G - #include "DIALOG.h"0 x/ b& t6 B8 w; t$ e& [
- 5 N- @! K/ z, Y: [, P2 e# d
- #include "WM.h"7 H6 z. r6 x0 C% ]# f
- #include "BUTTON.h"
6 _1 l# x: x: i' D( A" s - #include "CHECKBOX.h"
9 w/ [! y* L+ H; l5 E - #include "DROPDOWN.h"
% r. i/ ]) x( b5 x) D - #include "EDIT.h"
* a4 v: X3 I# E! t/ N) o- F - #include "FRAMEWIN.h"
6 |0 w1 s; a2 `! T1 Q/ Y - #include "LISTBOX.h"5 N4 T" m4 W1 ^7 v8 t1 s7 |* E
- #include "MULTIEDIT.h"
1 @2 h k9 j4 ~6 T$ k4 m, R( v( i - #include "RADIO.h"
! f5 _% R2 `$ j0 u3 q - #include "SLIDER.h"# w' V1 L6 L# s5 e' W, ~
- #include "TEXT.h") u. Z' x- [+ |* t7 E7 i0 ~
- #include "PROGBAR.h"
. D8 U p/ p/ _& k% n; a - #include "SCROLLBAR.h"
/ \4 M J% Y: h$ L8 e - #include "LISTVIEW.h"& Z* W# u4 V/ h5 Q6 U1 ~( v
- 9 Q& Y5 G4 K: s$ r# c
- ^: X$ E5 Z _8 V
- GUI_COLOR _acColor[3] = {GUI_BLUE,GUI_RED,GUI_YELLOW};
% `: ~" v4 Z& }* t u: [1 O# u - static char ucBackColor;: ]: ]( V; K0 d9 w9 @/ ^6 M
- 9 f" Q8 g$ H/ d- v3 f
- /*********************************************************************7 K+ ?# N4 T( z) V; d4 y" D: q F0 V, [
- *$ _& i, c. l( V
- * Dialog callback routine4 p' @* S' k+ ~% @; ?
- */# e; z E9 l" k" V( {5 c
- static void _cbBkWindow(WM_MESSAGE * pMsg) ( S5 J- t% P" P4 _/ z$ A
- {
2 v D# l# v( Y; a& L - WM_HWIN hWin = pMsg->hWin;; [/ G& H& A1 Y" J9 N2 g) r* ~. y9 F
- 8 `0 E; ?- s/ q9 |$ c& F
- switch (pMsg->MsgId)
- c6 N' N7 o; h4 x) G/ p: g' ` - {
5 z3 {8 B: q3 i' |2 l - case WM_PAINT:( x7 p I7 ~) ?0 X5 \9 i' S0 W8 J
- ucBackColor++;
0 K' h/ U& z) k5 j" [ - if (ucBackColor == 3)
4 s3 w4 K) n7 p) F1 x - {& Q/ G8 C% q, Q* s. T
- ucBackColor = 0;( ^6 O- |5 K7 S5 H: s4 c3 K' V$ [
- }
3 t1 _" v8 @, q# @( l - GUI_SetBkColor(_acColor[ucBackColor]);
( D( B# W6 ~2 E* z, I - GUI_Clear();
0 ?" ^9 @( H; i - break;1 c9 O& s& y7 |' T
- case WM_TIMER: (1)8 ^" B- q4 {$ P. s% R* ?
- WM_RestartTimer(pMsg->Data.v, 1000);) o0 T' r O6 b q% ?
- WM_InvalidateWindow(hWin);9 M, f6 T: i7 j. L! K" t
- break;
. M& w8 a; O5 V* i6 W# o) u - default:
" H* v6 n; M$ e# |! P: d - WM_DefaultProc(pMsg);
) J* V: ~" J( m - } N) E" V( o3 |, Q
- }
8 i6 [& w% M3 S& n, a+ t9 z -
6 u+ u# W) o) T' ?9 r" ?/ u - /*********************************************************************
" T, N# {8 O5 ^% h1 A' { - *
: ^+ l+ e% D+ l! b1 z - * MainTask1 {, t: t3 M2 k! w! {3 ~* S0 ]
- *
. Y7 A+ G$ r+ d0 _. `7 W% ] - **********************************************************************1 v3 ?; ]2 j1 _& f3 ~
- */* P) h6 m: |( f! Q0 e y6 p- R4 c+ o
- void MainTask(void) 7 u2 I! N/ k- w4 ^6 E& s
- {
% o! c$ y; R* y! t* A - WM_HTIMER hTimer;7 L+ p5 v7 | |8 ~
-
; B# |2 z& a0 b8 u, k0 I - GUI_Init();- z8 G( _9 [ F- K
- /* 设置桌面窗口回调函数 *// m4 j1 s2 D5 @+ z5 m' B
- WM_SetCallback(WM_HBKWIN, _cbBkWindow);6 Q. y+ M- T1 F/ K! \( y
- hTimer = WM_CreateTimer(WM_HBKWIN, 0, 1000, 0);(2)
; D. U& F; r" b0 ^ w2 V/ Z* g - while (1)
- k4 `3 y4 X# O) Z) ` - {9 s6 m7 M3 v9 e
- GUI_Delay(500);) D' G A2 ?( g& e# Z1 W
- }4 V4 J- v3 ~# C& Z0 @) O+ `
- }
复制代码这个Demo主要是实现每隔1000ms改变一下桌面窗口的颜色。 1. 定时器消息,这里要特别注意,如果想要定时器每隔一段时间执行一次,而不是只执行一次,必须得调用WM_RestartTimer()。在这个消息里面将桌面窗口无效进而会执行桌面窗口的重绘消息。 2. 创建定时器函数 WM_CreateTimer(WM_HBKWIN, //接受信息的窗口的句柄,注意是窗口而不是对话框 0, //用户定义的Id。如果不对同一窗口使用多个定时器,此值可以设置为零。 1000, //周期,此周期过后指定窗口应收到消息。 0) //保留,留作将来使用 这个Demo的实际显示效果如下: 36.3 对话框上使用定时器实例 这个Demo的主要功能是在对话框上面实现一个计数功能。下面是源码(可以将其直接的复制到开发板或者模拟器上面运行) - #include <stddef.h>3 z, u/ Z8 m3 _
- #include "stdio.h"
, L; H& H$ l1 z Q - #include "GUI.h"
: i1 y7 q" _$ x! A9 b/ K - #include "DIALOG.h"( t& R& o$ t( b# K) k3 Y3 q6 z
- ! Z% N) W6 L* C
- #include "WM.h"
0 d. L( n: y" j* _4 j1 b. ~ - #include "BUTTON.h"- L: R3 h, B5 p4 m D
- #include "CHECKBOX.h"
5 l8 I2 W7 ?1 L" L9 W6 y8 u+ z - #include "DROPDOWN.h"
# P2 U% c. t& n: B1 `9 P5 Q - #include "EDIT.h"
1 n' U5 P: w; d - #include "FRAMEWIN.h"
; R7 }+ O4 m! `4 _) c+ z5 ^, H - #include "LISTBOX.h"& ]& n d7 m/ A/ E
- #include "MULTIEDIT.h"
# r n5 t6 o" h: x& ^. [3 o - #include "RADIO.h" C, k' [7 r+ y. ]
- #include "SLIDER.h"9 w, i9 O% r1 \6 G0 W
- #include "TEXT.h"
# V7 _, {' p& {8 @% {" K - #include "PROGBAR.h"
7 [) M0 w i4 r0 f - #include "SCROLLBAR.h"
( _# e9 U' Q( n% G0 @ - #include "LISTVIEW.h"0 g1 D2 V$ G, ^7 |0 B0 h# U4 Q- w
- : t$ X$ ~# B. ~0 d
- static int Count;& n( \6 U' T9 P* G4 {. H$ x
- /*********************************************************************' I- v% k6 U }5 y3 S) }! w |+ y
- *; k- P! I: P' y) T' V; Z( O/ h
- * Dialog resource) C- z& b& U! y' u8 b3 b* R
- *
: H( S2 e! A7 \" v' e - * This table conatins the info required to create the dialog.
# @+ n; k: M. S* k- \ - * It has been created by ucGUIbuilder.
2 r9 R3 X2 j5 `3 Z6 ^, |- h$ A! h - */( W7 E t: k4 g( k
- 2 P9 ^% [) N% |" i6 d7 y7 ]
- static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
: O2 G# t, n- c7 L. M - { FRAMEWIN_CreateIndirect, "armfly", 0, 0, 0, 800,480,FRAMEWIN_CF_MOVEABLE,0},/ }! R- f5 S& x* F# g1 q2 |" t; S
- { BUTTON_CreateIndirect, "BUTTON0", GUI_ID_BUTTON0, 82, 122,162,37, 0,0},
- ?) L1 @0 i+ Q - { BUTTON_CreateIndirect, "BUTTON1", GUI_ID_BUTTON1, 357,123,152,35, 0,0},6 c" |' k9 G8 p5 W5 r
- { TEXT_CreateIndirect, "0000", GUI_ID_TEXT0, 278,264,300,48, 0,0}
( W4 P' I* c4 g2 j5 a4 X - };9 c F7 h% Q, `& g
-
4 f) ]& E2 b' L - /*****************************************************************
$ H. x6 x! I5 f) D4 E, C& V - ** FunctionName:void PaintDialog(WM_MESSAGE * pMsg)9 L/ e3 {1 _5 a* p# ^) \
- ** Function: to initialize the Dialog items$ R X8 h3 h3 @2 u
- ** ) y6 W9 G6 T1 b) G2 ~! J+ _
- ** call this function in _cbCallback --> WM_PAINT
1 h* N) J) x8 ~ - *****************************************************************/
) l3 W$ d# a, S -
, U; X. W: S) m' p0 f' E - void PaintDialog(WM_MESSAGE * pMsg), B$ N2 I3 d2 F* ]. i1 b+ E7 h
- {
; K" H; N8 Q7 {: g - WM_HWIN hWin = pMsg->hWin;8 }+ S* v" n: K' C& F6 I
-
1 n; i) P2 x: t* ^ - }8 ^: i& e' U' T0 O# N
- $ e# E1 Z; x0 v3 V& \
- /*****************************************************************! Q- m& @7 A- j0 L4 B. N
- ** FunctionName:void InitDialog(WM_MESSAGE * pMsg)
6 \1 D, D6 o& _: z/ z1 l0 l8 ^ - ** Function: to initialize the Dialog items* W0 e0 @+ C: M! o. b' v. Q9 H
- ** 0 g4 W3 p; H$ R
- ** call this function in _cbCallback --> WM_INIT_DIALOG
- \- S" @" j) S& k - *****************************************************************/2 J; H- Y) V5 r( A2 X7 j* f
-
- w, |! a" _7 _4 I - void InitDialog(WM_MESSAGE * pMsg)) v1 j' R+ R" D2 h! H" \+ @
- { N! H2 u5 O. ^' y" k4 f( B
- WM_HWIN hWin = pMsg->hWin;1 l- p# K7 Y" W/ J9 \) D7 p
- //
. e' P% k) j" ]8 N3 \$ b - //FRAMEWIN
( E1 s4 {0 @" c) ?& M - //
s' J0 ~1 P' J - FRAMEWIN_SetFont(hWin,&GUI_Font24B_ASCII);
b" p/ Q+ K1 L% K5 h& k - FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);
% H& f% M: B% D( S: n - FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);
) p; G9 u9 k( R( }0 s - FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);
3 P# e( p3 M x7 p3 m - FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);
7 a5 z% R+ T5 @$ t1 V& j8 r1 o - FRAMEWIN_SetTitleHeight(hWin,30);; x# l. C, p1 S- H: \5 n7 U
- + |7 ^* \/ W( I' W1 R
- //
, V& X1 K, J) j# c+ W8 b) Z& J - //GUI_ID_TEXT0
_; m* M# Z6 @9 m; ~5 i ? - //$ v% o8 u. d8 o6 b; _
- TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT0),&GUI_FontD36x48);: K6 c7 Q$ H+ ^5 l# W
- * @) S* s8 [: B! d7 f$ ]# _
- }* ]- D3 a: c+ t: }, N: s2 l0 ]
- 1 t- D7 f2 ^) W8 |" ~$ E( Z
- /*********************************************************************
2 i4 X) E/ ~; j7 ?5 j6 V - *
{# t ~ _0 f" r }' _( r - * Dialog callback routine
1 K* S) ?2 a; @: m( C* S4 b" T - */
. t5 E* t$ o! v, F1 W& T9 o2 B& u - static void _cbCallback(WM_MESSAGE * pMsg)
7 R- o0 E$ M4 ? - {
9 |4 p4 q( ]% l9 C; L c/ @ - int NCode, Id;% b. J6 q/ a4 I/ }( ]
- char buf[10];) ^' i, T$ F, X6 G8 y9 r' u
- WM_HWIN hWin = pMsg->hWin;2 ?) j; J* ~$ N' x8 O B; a$ n
- 9 ?( J8 i6 r, F( L! z, i
- switch (pMsg->MsgId)
( I& r+ }! ~9 p: c" ]8 D - {
& l- Z8 e8 T+ R2 A, I - case WM_TIMER:(1)7 Y9 t- t. W3 Q" u3 C1 i/ R
- Count++;9 A$ h7 J( f! j
- sprintf(buf, "%04d", Count);
- J* Q; \+ V+ g0 ^8 o! T: g - TEXT_SetText(WM_GetDialogItem(hWin,GUI_ID_TEXT0), (const char *)buf);
# L: v# F! \9 K* n# C+ I6 X - WM_RestartTimer(pMsg->Data.v, 100);
8 X3 K* k. ^9 Y( a3 ^ h2 g D4 _ - break;
7 R4 y0 R2 }& Y& S/ ?7 f9 G - case WM_PAINT:) r) R2 M6 ~* N1 P2 A. c8 k) _% B, C
- PaintDialog(pMsg);. K* |) J* ~; a- }! Z, G& t7 n
- break;
% i1 n6 b6 ^2 ?! ]& u8 O- P - case WM_INIT_DIALOG:1 ?; a2 s; }* ~2 a0 ]
- InitDialog(pMsg);1 z9 v( {" D; j4 b
- break;
0 x6 F1 u' e6 f% y3 Z - case WM_KEY:$ X# [2 d0 @. R" l* W
- switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) ; B I/ x) ?" m/ y
- {2 J- z# a& i* s1 D8 M2 R
- case GUI_KEY_ESCAPE:
: C; N) O& p) R. | - GUI_EndDialog(hWin, 1);! s( g1 F* U: l* w
- break;
, I! ~7 Y. |% |" T8 ~+ }+ W - case GUI_KEY_ENTER:7 c9 P- \% O- ^4 O1 ]
- GUI_EndDialog(hWin, 0);, U [! \) m) v. X- o
- break;
. ?7 h9 W! z& G% ]: w% p - }
* a. p4 P* S3 t. A$ f$ a' Y7 X - break;
" }0 ?' V) P; j% F - case WM_NOTIFY_PARENT:3 n! J/ f3 C+ ~! A0 _
- Id = WM_GetId(pMsg->hWinSrc);
: \) { N+ I! Q) [& P M( C8 R - NCode = pMsg->Data.v;
+ F4 t3 b2 m4 ` ]0 |5 {% v0 u - switch (Id)
Z, g6 d; }6 i& T( T+ J - {8 v+ s/ m! W I# Q& c2 W5 D
- case GUI_ID_OK:0 P5 L) r. \( Z1 V( k& K1 ^
- if(NCode==WM_NOTIFICATION_RELEASED): K8 n& t9 g) s5 o" e8 @- l
- GUI_EndDialog(hWin, 0);
" K- S0 l4 h! s p% i - break;/ ^: B/ }+ o+ X+ @# D0 Z f
- case GUI_ID_CANCEL:
! u; U" l2 c8 |; O% i# u9 b - if(NCode==WM_NOTIFICATION_RELEASED)7 ?( {* i! p. e. H C
- GUI_EndDialog(hWin, 0);
& W; t3 \& F9 L# u9 O - break;) F( |5 C) D/ C* `& b- H7 p$ c
- case GUI_ID_BUTTON0:
( v! G9 M, x0 v4 L: v8 H - switch(NCode)
" b' t; u8 p. b2 q; w0 G T - {
8 `' M: }/ o3 @7 h! \0 ]& U" F - case WM_NOTIFICATION_CLICKED:
3 d- A; Y5 y6 r7 | - break;, Q4 A2 y% _+ j. C0 V
- case WM_NOTIFICATION_RELEASED:. w* ?- w4 [: O% l J8 i
- # r6 D0 h M' b* G- P4 K7 ? b
- break;" A' K) z1 p5 N+ f- L+ s" h
- case WM_NOTIFICATION_MOVED_OUT:# I: v3 z& s3 Q9 Q4 `
- - S6 X! D: k3 V6 v7 b7 Y0 {# d
- break;% C/ l( T1 i" z) ]" g( B! x
- }
1 @8 u9 ^) O! X# g- _ e2 Z - break;
# ]9 w% t* a0 u - case GUI_ID_BUTTON1:
/ C0 t( g- v3 E+ f - switch(NCode)
1 S0 h3 y5 z- w' i' O: s2 s - {9 h- z. K, ^; n1 Q2 T
- case WM_NOTIFICATION_CLICKED:
' u: q& w6 `$ u* Z - 1 I. @% h4 f% _ R% [. v
- break;
( D; F5 l; H4 ` L$ B - case WM_NOTIFICATION_RELEASED:
+ g1 |! g' b% i, h& P, u! ~ - 9 R7 B0 U. @4 q- c' R" Z
- break;
# B; [6 A$ O. @+ p# C2 O6 T7 ` - case WM_NOTIFICATION_MOVED_OUT:
; F: L9 F) P6 B( \) X: } -
. X7 A4 A+ a+ X$ L# h - break;8 _' E& e8 c+ H
- }
6 j! f& ^! j& `! b5 h - break;
, R1 T F) \$ |) m -
+ P* A: P- p8 J5 ?! X7 T1 u g0 i - }
+ ?9 O, q+ {: {' K) B - break;
" d: \ D: x- Z" Y+ U - default:2 C. v" J9 L$ j
- WM_DefaultProc(pMsg);; h- B- F) J# n4 y5 [# p0 C4 M
- }
! ^+ `8 y( L- C8 X+ ] - }
) J1 R+ y! E6 n8 O. v* f- Y - ! x' l3 m0 _: L0 k$ }& s2 K, E
- /*********************************************************************% h, q" m$ G9 V1 ~% J' R7 h y
- *+ Y, \# m. v! t: e* ~, a% C
- * MainTask
9 G) P( c2 V) Q8 p& o/ G" e6 @8 ? - *
3 L3 T3 \9 D& M6 v! s7 t - **********************************************************************8 q/ h, \9 [0 i6 ?& F
- */
4 ]* |+ B% W3 D* b - void MainTask(void)
7 q) O/ w5 B0 P7 F; v5 p6 ? - {
/ Y9 N1 Q& v: u - WM_HWIN hDlg;7 }, R& \2 X+ x, Y' b+ \% ~
- WM_HTIMER hTimer;
# W4 t6 ~( T: J% z - Count = 0;1 x" u- E" w! t5 b/ @. N% ?, _# X
- /* 2 O6 S. R S# X1 t3 e# H/ r
- 使能窗口使用内存设备,这样可以有效避免闪烁 放在GUI_Init前面就包括桌面
; J2 [; L7 \- ^! ]0 a+ e! U - 窗口,如果放在后面就不包括桌面窗口。5 |9 Q3 p7 X! s* |
- */; \ H6 o) E: D5 N$ F( {
- WM_SetCreateFlags(WM_CF_MEMDEV);
6 q/ q0 @6 c, l) @4 V - GUI_Init();
# l* K/ h! G i - WM_SetDesktopColor(GUI_BLUE); /* Automacally update desktop window */
2 g! d3 a0 K6 q - PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);" E' O& X7 B( \7 g
- FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);- Q' ]$ G4 f$ I& w! m/ O- d
- PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);
" C) }- v& d% q, V6 ~# Q. @% I) p - BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);( {0 G0 h3 k4 N3 l1 U% \$ W
- CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);
8 m' R1 X! f0 i( |6 Y9 b% [ - DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);
6 Z& D L8 R' f- J - SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);
$ R- t! }6 X1 Z/ a0 x/ `3 H7 s8 w# H4 P - SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);6 ^! ?5 W$ b9 ?" e2 K0 K
- HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);; @) p0 o# _ l( G$ Q+ |
- RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);
w) d! m" _9 g# k' Q7 ~- L+ {$ B - ///* 创建一个对话框 */$ }" U* t+ Q7 z' ]+ ?6 _: L
- hDlg = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);6 K- k$ h+ I) _1 X% t- ]
- hTimer = WM_CreateTimer(WM_GetClientWindow(hDlg), 0, 100, 0);(2)
# c5 R! ~$ I# _4 n6 v0 L: k - while (1)
0 ?" W( c0 n% O) n4 F - {( \1 d2 f* f. Q7 E/ T
- GUI_Delay(500);
2 ?% w. P( U$ j( f - }
% x$ `, Z$ Y) Y( @0 d: } - }
复制代码1. 定时器消息,在定时器消息中实现文件控件计数值的更新。 2. 给对话框创建一个定时器,特别注意这里需要获取对话框中窗口的句柄才可以使用。 这个例子的实际显示效果如下(分辨率800*480): 36.4 总结 大家学完本期教程后,可以考虑在实际项目中使用这个功能,很实用。
: E: I, H% { t* V- k4 H c- ~ |