特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接0 U0 U5 ?* z* k9 r' H* M6 \6 x
第44章 FrameWin-框架窗口控件
% S' o- B# N7 S6 K9 h4 y. v 本期教程讲解STemWin支持的框架窗口控件。 44. 1 框架窗口控件介绍 44 2 官方WIDGET_FrameWin实例 44. 3 总结 44.1 框架窗口控件介绍 框架窗口为您的应用提供一个PC应用程序的窗口外观。这些窗口由周围框架、标题栏和用户区组成。标题栏的颜色改变以显示窗口是否激活,如下图所示: 如下图所示,可将预定义的按钮附加到标题栏,也可将自己的按钮附加到标题栏: 设置皮肤后显示效果如下: 44.1.1 框架窗口的结构 下图显示了框架窗口的详细结构和外观: 框架窗口实际上由2种窗口组成;主窗口和子窗口。子窗口称为客户端窗口。处理回调函数时意识到此点非常重要:存在具有2种不同回调函数的2种窗口。创建子窗口时,这些子窗口通常作为客户端窗口的子窗口而创建;它们的父窗口因此是客户端窗口。 | | | | | | | | | | | 客户端窗口是一个单独的窗口,作为框架窗口的子窗口创建。 | 44.2 官方WIDGET_FrameWin实例 官方的这个实例简单的演示了FrameWin的部分功能,这个例子在模拟器中的位置: 源代码如下: - #include <stddef.h>8 z. {5 H. k c9 A$ R
- #include <string.h>1 t% D- m0 w; j" ?$ C* D" b' P' L$ a# [
- #include "GUI.h"
: i* a# G) R6 I - #include "FRAMEWIN.h"0 m2 O+ o: a" I% u
- . v% O+ `$ m, {+ u3 |% f) g8 Z
- /*********************************************************************
7 H2 f; q7 }; m4 f' W$ G& v- j0 | - */ o9 L& H0 ^% h
- * Defines
+ a, ?- x+ T* J( u: r8 c3 d - *
2 v3 b5 C+ j0 c$ q0 W! y9 m - **********************************************************************" l, }/ v* [2 [- D; p
- */* [& }! l7 E) T" v! B
- #define SPEED 1200
, r/ Z1 \0 V" ~8 M h$ O -
+ @1 T* O# X- J+ `- ? - #define MSG_CHANGE_MAIN_TEXT (WM_USER + 0) (1)9 N F/ Z4 y( ?/ f; G& H5 P! \6 n7 Y
- , G1 K/ K u! b8 C0 x
- /*********************************************************************
9 A7 J$ u: D" O) u! l - *) T0 W- S" X" c: a f) |, F6 @
- * Static data
. x5 y# U+ ?, z6 g0 T9 C - */ j$ x$ i) O& G9 \3 D: D8 z) l
- **********************************************************************
9 O; Q8 ~3 L' S: { - */8 B: m3 b7 E: v0 L @
- static FRAMEWIN_Handle _hFrame;$ T, t! T- b( {7 s% m" D' ^
- static WM_CALLBACK* _pcbOldFrame;# \& ]6 B9 O7 C2 y
- static char _acMainText[100];& n- J. T- W! K$ T+ Z6 H
- static int _LockClose = 1;
6 o- `; {5 i) k% O+ [7 F ` -
" y; o) i, z6 P - /*******************************************************************( `1 G& a& V1 j
- *
0 K0 _7 ?+ F. @. ?8 ]; R - * Static code
$ b5 @1 ~- H* F9 {7 h D Y - *
( u/ Z7 X$ t' y6 V7 T9 i - ********************************************************************
0 }5 C3 [; K' r, v - */
2 n ^: f6 W% T5 C& R6 s1 ^ - /*******************************************************************
Q/ m/ X1 x1 k5 I - *2 A }5 w: d0 d5 w1 B) |. H+ v3 A
- * _ChangeMainText5 u, N1 k7 t# U7 P. Y
- *
0 E7 Z0 g8 d% j: O. R - * Sends a message to the background window and invalidate it, so
% `% ~! Z: S F. \/ d* B - * the callback of the background window display the new text.
/ n& z7 M$ \$ }2 V+ R4 x( y9 ] - */' s$ C8 q4 M( s* X' \$ F+ q
- static void _ChangeMainText(char* pStr, int Delay) {(2)8 @# ~3 A7 {2 i; W: B2 c: Z
- WM_MESSAGE Message;6 T+ y) K' A& L, ]
- Message.MsgId = MSG_CHANGE_MAIN_TEXT;1 v( Y- s/ P5 v3 B& M
- Message.Data.p = pStr;( `$ p- C6 N8 i3 u. o4 x
- GUI_Delay(Delay);% I1 ^( J# v1 r, J/ z
- WM_SendMessage(WM_HBKWIN, &Message);+ K, |! u ~4 Y$ v4 z" k4 d7 e
- WM_InvalidateWindow(WM_HBKWIN);/ H1 Y6 Y, w* t3 P8 q% W
- GUI_Delay(Delay/3);
4 x0 M8 \2 \+ U( l3 _0 ? - }& c7 T- z7 |' i4 t) G7 |3 }+ D
-
! H* p; [* n3 t/ R4 c - /*******************************************************************
, B0 h6 a( R% p( \( h6 q - *
1 |0 K+ i% c, u2 B7 m - * _cbChild
% i' R" r8 y% _* j8 T3 M f& B - */: P0 E0 `" t; y7 C. R
- static void _cbChild(WM_MESSAGE * pMsg) {(3)
5 o6 ^% `- G5 f2 g0 m; m4 d, ^ - WM_HWIN hWin = (FRAMEWIN_Handle)(pMsg->hWin);1 o6 n. g! N) U( n: q5 a% Z
- switch (pMsg->MsgId) {8 G0 o4 F$ l6 t3 c% c
- case WM_PAINT:
" x/ n" Z. q" h j) F; H8 c2 D" N/ b - //
: Y' O' b' D1 B" j0 p - // Handle the paint message
/ M$ H6 e) N8 `4 Z7 s! ] - //
; G) t; `, R, H - GUI_SetBkColor(GUI_WHITE);0 Q7 F, Q0 p7 F/ F
- GUI_SetColor(GUI_BLACK);
9 q5 f5 [7 q3 r0 H - GUI_SetFont(&GUI_FontComic24B_ASCII);6 i* a; z: ?6 ^: ^# c4 G) Q0 R
- GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
& m7 S: }; L" ? - GUI_Clear();
5 A6 |$ Q% r% F1 S - GUI_DispStringHCenterAt("Client window",
4 r) N6 f4 c, |9 e" n - WM_GetWindowSizeX(hWin) / 2,
* u( U0 H! R4 @* J, j - WM_GetWindowSizeY(hWin) / 2);4 d7 f! R- I5 E
- break;) l* f, F- [. I p, I/ Q
- default:
/ ]) f U8 O s& \) b - WM_DefaultProc(pMsg);
% Z# t. M1 ?) x* i& W5 n( ]$ R0 h - }3 I! q% P- s/ Q3 r; I% k& k$ ~8 I
- }
( g$ q% z9 q7 Q* X- U1 _. ^ -
2 \! E: n' J" j9 R - /*******************************************************************1 r/ Z3 d! s! s* p+ a" Y
- *
2 h8 e; ?( S+ W4 v N - * _cbFrame
) B1 |8 R6 K" I. n - */
" }# J( E; X5 M4 u - static void _cbFrame(WM_MESSAGE * pMsg) { (4)
& j' ~3 z4 |# D7 P1 p i - switch (pMsg->MsgId) {, K9 r) ]% E# } N; \ N/ h, Z3 S
- case WM_NOTIFY_PARENT:) |1 _' P* y6 @$ o1 X$ m0 O2 q
- if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
% E& ~+ j Z) \1 f& [9 k4 T - int Id = WM_GetId(pMsg->hWinSrc); // Id of widget& o9 B% P( u8 D! o
- if (Id == GUI_ID_CLOSE) {0 Z. i' @0 ?! l6 u* w9 f, g
- if (_LockClose) {
* z. X$ m$ j, V# _# I' v - return;
5 d) k/ z$ J5 L* g1 v - }( S( Y6 R" Q1 n% Y6 o
- _hFrame = 0;
! o" X4 O5 }# B9 Q - }
# T7 L- c. E# { - }
6 Q( r; R( @" J) a! y - break;5 s2 x! j0 e( {$ f5 v3 b
- }- Y, ]5 i5 r" z% _( w2 b" C. O6 F2 k
- if (_pcbOldFrame) {
# p# d. h& A! C - (*_pcbOldFrame)(pMsg);; j ?& U& [5 b, G/ }
- }$ Q4 j7 [3 ^5 `. j. K C1 n r5 x
- }5 w4 `% H; i* ]
-
. r8 V3 m) K8 g( I2 L - /*******************************************************************
# W4 F4 d: S- X4 D3 q - *
0 y0 D3 V8 ?5 U9 A: u - * _cbBkWindow
, o h, b& r7 d5 C9 } g: t( ]5 \5 a - * \1 A) B2 [/ b, A4 u
- * Function description
1 ]# j& p* u6 x( t4 L# D - * This callback is necessary to redraw the background when
; m. g- l1 F. g& p - * frame window is moved
8 t: l# Q x o$ j( d( s3 A - */
5 \' J8 D) u* K - static void _cbBkWindow(WM_MESSAGE * pMsg) {(5)
+ J5 s4 X0 }: N9 X3 [7 D! z - switch (pMsg->MsgId) {1 e, |7 q, @1 O1 Q$ O
- case MSG_CHANGE_MAIN_TEXT:3 \' Q, s$ _ v- F
- strcpy(_acMainText, (char const *)pMsg->Data.p);
" J& O2 |8 B! J4 j - WM_InvalidateWindow(pMsg->hWin);3 Y- v) m* x, Y) ~9 m J
- break;8 y- g6 c1 V6 j9 I4 k! [
- case WM_PAINT:
/ J* }# x" {) g, q1 U- e - GUI_SetBkColor(GUI_BLACK);; ]. a7 X# s. t
- GUI_Clear();
; @" D7 ~) I+ C5 t+ g7 @ - GUI_SetColor(GUI_WHITE);, [2 y* H4 w8 g. v1 X+ @
- GUI_SetFont(&GUI_Font24_ASCII);$ Z. o+ Q% }8 s
- GUI_DispStringHCenterAt("WIDGET_FrameWin - Sample", 160, 5);3 `$ m+ u1 r8 Z6 V( x! c" V2 T
- GUI_SetFont(&GUI_Font8x16);
6 [* M3 {' s5 {9 o6 B$ e - GUI_DispStringHCenterAt(_acMainText, 160, 40);
1 O$ }; w, P% o( ?2 a- @- f4 N. k. p - GUI_SetFont(&GUI_Font6x8);
4 ^& e& q/ {( K4 R6 f6 L - GUI_DispStringHCenterAt("The function FRAMEWIN_Create creates both the\n"
: d& |4 c/ `8 ~- |- ]) e' P - "frame window and the client window.", 160, 190);
4 b5 J2 h4 s) ]! _: Q- p. ~6 i6 M - break;9 `* Y: f; \' r# x. e6 @! A; b2 l6 H
- default:1 O, b0 d! q3 @2 ], O
- WM_DefaultProc(pMsg);
7 o$ b' V4 d8 C% o) F - }
6 E) [) g. P) D7 c6 I2 W: D1 L - }7 l! H1 }; d) ?: j+ D" K
-
) C1 C9 \5 x- S2 `! N - /*******************************************************************
: e4 k; ], Y: Q$ g: f/ i$ z - *
. M8 d7 _# }2 D) j - * _DemoFramewin
7 H1 B5 R$ ~ h3 f/ \5 |# b( `% C+ ? - *
: ?* E) N' k* ? F - * Function description/ R; b2 T8 }/ w/ B8 Y: q
- * Creates the frame window and sets the callback for frame, child
) E& Q& \: M& w5 o6 k - * and background window6 N* y0 ^* f; }9 Y8 S; h4 `, c
- */2 u+ ]. j8 F5 r2 i1 Z: c: ^ G
- static void _DemoFramewin(void) {(6)
( y* b. n9 u( ?9 \- I - int i;
- O3 ]. V' [/ ]( e7 ?3 c" F - char acInfoText[] = "-- sec to play with window";$ q# p7 X8 o5 T0 G2 r( ^
- WM_HWIN hChild;
; q9 d' Q' d P/ d5 F2 T( y4 t - : c4 M& R( ` I! i
- 8 ]" S' n7 ~& R9 ^& V' H$ m
- WM_SetCallback(WM_HBKWIN, _cbBkWindow);
7 M2 M, P. K- g2 k7 }+ X, b - //
6 o- N N ^' F1 p; o) ^ - // Create and configure frame window8 m; r2 w- k2 J3 I
- //
0 N) i: s! P3 n6 \2 B# G. b/ c - _ChangeMainText("FRAMEWIN_Create", SPEED);
$ D. y; r+ G" N/ J, @ - _hFrame = FRAMEWIN_Create("Frame window", 0, WM_CF_SHOW, 50, 75, 220, 100);(7)/ j& t4 V5 j1 E' k/ \) `
- _pcbOldFrame = WM_SetCallback(_hFrame, _cbFrame);(8)& g, ]$ O/ X7 l
- hChild = WM_GetClientWindow(_hFrame);(9). o, ?5 @9 d% U) `% @
- WM_SetCallback(hChild, _cbChild);(10)7 h- _+ B, I' k2 c u! E% H9 W
- FRAMEWIN_SetMoveable(_hFrame, 1);(11)
1 }7 i' g1 W3 y: r% y- w - //
3 b2 g, W, J; X' i - // Create buttons6 w3 a/ b0 e# \
- //
- M2 e1 q8 n, `2 h' n* D - FRAMEWIN_AddCloseButton(_hFrame, FRAMEWIN_BUTTON_LEFT, 0);(12)4 T5 H' C# }) m) `) k0 R2 }2 }3 c
- FRAMEWIN_AddMaxButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 0);
3 w1 e' \: u7 D* f8 B - FRAMEWIN_AddMinButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 2);
; C* l1 q: m( C- I/ I - //: {& r. P' C! e1 R0 L1 x( v
- // Modify frame window attributes9 O0 q! r6 s$ [3 z! U# [- f
- //
$ k$ ^; X; s* l8 G - _ChangeMainText("FRAMEWIN_SetActive", SPEED);9 w6 b: H6 ?. F0 W5 u
- FRAMEWIN_SetActive(_hFrame, 1);(13)
8 w4 E; G* t4 o* V+ f6 t& y- M `; s - _ChangeMainText("FRAMEWIN_SetFont", SPEED);
1 A' p3 Y2 d3 S8 s+ U4 ^: S' j! e - FRAMEWIN_SetFont(_hFrame, &GUI_Font16B_ASCII); (14)
) g$ E+ H, t7 ^ - FRAMEWIN_SetTitleHeight(_hFrame, 20);
% o3 j% t- Q9 d6 t+ Y( z2 N+ B - _ChangeMainText("FRAMEWIN_SetTextColor", SPEED);! C/ i/ \& _# E
- FRAMEWIN_SetTextColor(_hFrame, GUI_YELLOW); (15)
% u' a/ Q4 @2 g - _ChangeMainText("FRAMEWIN_SetTextAlign", SPEED);
+ o& \& G& o- q$ v& I" X - FRAMEWIN_SetTextAlign(_hFrame, GUI_TA_HCENTER);(16)' G C; W# f% I6 U" m) S, E6 F
- _ChangeMainText("FRAMEWIN_Minimize", SPEED);
- ~5 ^' O- H. @; m. o - FRAMEWIN_Minimize(_hFrame);(17)/ T0 @% ?9 U4 `! ]" |' f/ y
- _ChangeMainText("FRAMEWIN_Maximize", SPEED);
" K6 l& d% U. } - FRAMEWIN_Maximize(_hFrame); (18)
1 R# O9 ]% c$ m9 }/ Q - _ChangeMainText("FRAMEWIN_Restore", SPEED);9 N; ~. c1 _# W' e8 W% i! H9 T# F' u! W
- FRAMEWIN_Restore(_hFrame);(19); A1 j j e* ~# |1 T- N, j
- _ChangeMainText("FRAMEWIN_SetTitleVis", SPEED);
! d% R% x: ~/ [# o* ?7 K2 _% x - for (i = 0; i < 5; i++) {
/ H4 S4 y+ z2 H1 X; h% I* q - FRAMEWIN_SetTitleVis(_hFrame, 0); (20)! o8 a( O% d; i. L6 O9 d$ n
- GUI_Delay(200);# M/ Z8 ] ]; O- J7 } d4 H
- FRAMEWIN_SetTitleVis(_hFrame, 1);
" o; @5 |; A6 a# v2 o - GUI_Delay(200);
W- j* h! H/ H - }0 ^7 U8 K. {" f! i+ q) X6 S
- //0 m/ |+ v8 V3 S8 o, ~) }
- // Time to play with frame window7 G6 e+ u$ W }4 }
- //
% l/ V: t; ]5 ?1 y! S - _LockClose = 0;
: w6 M+ [9 c+ J! s0 [ [ - for (i = 250; (i > 0) && _hFrame; i--) {. q) G; C7 v' K% l4 s! p4 r
- acInfoText[0] = '0' + ((i + 9) / 100);
1 a* B: E0 B$ h8 e( i | - acInfoText[1] = '0' + (((i + 9) / 10) % 10);- U" J5 N; U: @, F6 a
- _ChangeMainText(acInfoText, 0);; ]7 {% Q& K8 Q6 j% |
- GUI_Delay(100);
; a4 g$ i# p- | - }
+ a' x5 ^ g4 e. x% G8 C - if (_hFrame) {7 i- h+ }; M' ~
- _ChangeMainText("FRAMEWIN_Delete", SPEED);
7 n& B8 o+ p& W7 v1 D - FRAMEWIN_Delete(_hFrame);(21)
2 X6 X" r9 p' e; D6 a3 I3 M" z* C9 _ - } else {
9 q' O1 i# A7 w( H8 `9 D - _ChangeMainText("", 50);
K, K6 {$ B6 e' q: W7 V - }
! L* Q C- x- Z1 G/ U2 o3 O - }2 V! E* c3 K2 x) B( ~9 _0 d8 N
- Q9 I8 W8 G! D u8 s! P% m' m/ L
- /*********************************************************************+ O" e. @# |. j( k' t
- *
/ \# ]+ d9 c) j2 A4 v9 H - * Public code( ^4 {1 ~) s J/ f" M1 S4 Z8 y* ]
- *
( ^* e. ?% g* t6 r- f$ p+ F - **********************************************************************
( Q# E. a- A, _* {: a2 @" t) }+ p3 U1 e - */
# T# J4 M- ~* I' x, j1 Q0 y - /*********************************************************************
* d6 B& d7 z* R1 t& F( w' F! | - *: U8 C1 B+ r0 ^$ w( J: b
- * MainTask
" B# W- B+ N5 P; `0 W; h+ i - */
5 c% s; `) ~. w - void MainTask(void) {( c/ u* Y+ V7 f3 @9 D+ m6 k
- GUI_Init();
$ Z# l1 _) y* w% g - WM_EnableMemdev(WM_HBKWIN); (22)& \% V) W# y8 i. R( w1 P. Z5 G
- while(1) {+ c' A& Y: C4 R$ Q" b' U, z
- _DemoFramewin();
: w1 ^% v' ^% f - } K# U/ z6 Q4 `( p. g
- }
复制代码1. 自定义的一个回调消息类型。 2. 用于给桌面窗口发送自定义的回调函数消息类型。发送后将桌面窗口变得无效,然后系统就会去执行桌面窗口回调函数中的WM_PAINT消息。 3. 框架窗口中客户窗口的回调函数。 4. 框架窗口的回调函数。 5. 桌面窗口的回调函数。 6. 框架窗口中部分API函数的演示函数。 7. 创建框架窗口。 8. 设置框架窗口的回调函数。 9. 得到框架窗口中客户端窗口句柄。 10. 设置客户端窗口的回调函数。 11. 设置框架窗口可移动。 12. 为框架窗口添加最小化,最大化和关闭按钮。 13. 激活框架窗口。 14. 设置框架窗口中标题的字体。 15. 设置框架窗口中标题的颜色。 16. 设置框架窗口中标题文本的对齐。 17. 最小化框架窗口。 18. 最大化框架窗口。 19. 恢复最小化或最大化的框架窗口。 20. 设置框架窗口的标题可见。 21. 删除框架窗口。 22. 使能桌面窗口的内存设备。 这个例子中变量_LockClose的作用也很重要,它的主要作用就是在演示框架窗口时锁住关闭按钮,防止在演示的时候,用户点击了关闭按钮。大家也特别注意框架窗口回调函数_cbFrame的处理。 实际显示效果如下: 44.3 总结 本期教程主要是跟大家讲解了框架窗口的使用,希望大家可以把本期教程中讲的这个例子跑跑,然后自己设计一个相关的例子进行试验学习。教程中只是使用了部分的框架窗口API,其它的API大家都可以试试。
0 { y) F6 k! _& } |