特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接
4 |& K; G4 `- u! ?4 ~ H第44章 FrameWin-框架窗口控件 / y/ \5 Y& L) V$ H: f
本期教程讲解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>
+ n! }& l8 g7 T- N - #include <string.h>
8 o+ c: ?6 A/ d" ~0 q7 m - #include "GUI.h"
: s# o% G, M! D$ d4 x( R - #include "FRAMEWIN.h"
# p) F0 |& z g G, u- q -
6 k- m- t1 z3 x% G) L - /*********************************************************************! @! ?) @5 z( ~# s% n0 Q
- *
& ~. Z7 M0 m9 \! f( w% e- _, L - * Defines2 j; |5 u {! Z1 v7 G- ~* y
- *; t' l9 P1 \2 A; V
- **********************************************************************
9 m9 e5 r' y% { - */
; H# f+ Q& m" T& r3 v - #define SPEED 12008 B; N1 |5 s7 U/ T
- % Z* ~& i5 x6 L1 R: A
- #define MSG_CHANGE_MAIN_TEXT (WM_USER + 0) (1)' E$ J) c2 I+ L8 ]7 T& a- ^
-
& c. V/ ?1 ^ N" U5 [ - /*********************************************************************
3 Y5 T/ f. U" r: a - *, U1 A. \, _" b* z$ H3 ]0 H/ |" b
- * Static data" K5 [. p. B( U4 T6 J/ z! F
- *% a$ A+ D, A: u$ ?) x! F
- **********************************************************************
f8 ?/ I" M( I, u+ c. F - */
( X) @2 R8 K6 u( i - static FRAMEWIN_Handle _hFrame;' S+ f2 Z) u7 E: \2 V0 w
- static WM_CALLBACK* _pcbOldFrame;
, X0 z; _. i" g3 T - static char _acMainText[100];
7 m/ w* P( w5 F; R' b - static int _LockClose = 1;
y7 S4 Z$ B4 d6 ~ - 9 i! U% V7 D" [
- /*******************************************************************0 c- K- P; @0 M) I" a
- *! K# v4 w- S, A8 O: i1 s4 p
- * Static code" s, L7 E& c* @
- *" _5 J1 o, \- s7 j, T' |% }8 e. Z
- ********************************************************************
+ P n4 C$ G2 Y2 C! c4 { - */
$ U6 j3 N$ }- r B - /*******************************************************************
+ i: R* M% j* I. l5 ~ - *
4 n4 ~" f& n# F$ h4 C* D4 u5 D3 F - * _ChangeMainText7 M. W( ]# u6 A3 g
- *+ ?( P7 h, A: [0 a- d3 A2 p( C2 g
- * Sends a message to the background window and invalidate it, so
7 J- B, f; C3 N! C) Q$ P7 R: \4 V - * the callback of the background window display the new text.
. z2 r4 l" Y$ o3 v1 Y - */& [3 I! l$ k7 m3 [% o+ O
- static void _ChangeMainText(char* pStr, int Delay) {(2)" c! L. x( n* G0 }' T2 p) e% u
- WM_MESSAGE Message;/ M0 A: B9 M" A. R
- Message.MsgId = MSG_CHANGE_MAIN_TEXT;
9 T" ^: M* @# Q; R5 I - Message.Data.p = pStr;0 i' o2 [8 c) S
- GUI_Delay(Delay);
% f; ]0 w V& \* P! r& z7 q - WM_SendMessage(WM_HBKWIN, &Message);
3 H; S8 Z8 j6 z' R$ X$ q - WM_InvalidateWindow(WM_HBKWIN);2 {: t$ n( Z# l
- GUI_Delay(Delay/3);
1 L' z8 L% x6 B) q# i - }
- S0 M7 U8 \, s" d$ l# q, N - 9 w( I% `0 A% K, m" z' {( J. }% J# G
- /*******************************************************************
" o" T) @% |5 a; u) t; Y( j - */ s4 ], m2 G' b$ V$ N; }
- * _cbChild5 P$ ~, K4 e8 U6 [: U0 e
- */8 G) u5 R% m( V u) P% v
- static void _cbChild(WM_MESSAGE * pMsg) {(3)
6 \/ [# {& Y' O8 D8 ^2 i - WM_HWIN hWin = (FRAMEWIN_Handle)(pMsg->hWin);
, |2 h- m1 J. o: k; s: \! [: k- T, P - switch (pMsg->MsgId) {
0 r" K- c9 m, W" j5 r2 q3 a - case WM_PAINT:
. w0 \: `6 l Q - //
1 Y+ X( ^: H! H& r+ c - // Handle the paint message
6 g& D* n6 K$ V9 _" G: H2 Q - //
' x/ W( Z) q' D" l - GUI_SetBkColor(GUI_WHITE);5 [. L P6 @* E H2 }# H, C
- GUI_SetColor(GUI_BLACK);+ L2 O1 t5 G$ A% {
- GUI_SetFont(&GUI_FontComic24B_ASCII);: W9 x4 Q' }0 ~" ^
- GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);; z; c. |6 H% k/ a7 N% w" l+ _
- GUI_Clear();, m- ^+ n4 G2 a
- GUI_DispStringHCenterAt("Client window", ; B) L" R* |) K6 x9 E p8 {# |1 x
- WM_GetWindowSizeX(hWin) / 2,
$ P3 w+ R. i2 E) w1 @! S& d0 w - WM_GetWindowSizeY(hWin) / 2);
4 X% p& y. m; o/ S' m. l - break;) I' Q) d" ]: r4 O- f; m4 G f8 E) s
- default:
% a1 i* X t9 ?" i' q - WM_DefaultProc(pMsg);) i, [/ b3 i/ u) K9 p. [3 S% D5 G
- }
3 y- t. ?0 \% f' [ - }
/ R- F, N4 I* b! W - 9 V9 W* s# E8 d/ X T) m. s
- /*******************************************************************
; y, q! B, ?' z- k" p8 ?4 h* m - *
0 Q+ I' g8 P8 {7 E( Q: D2 _( j9 D - * _cbFrame
- A4 [; t5 H1 b4 h" b+ Z - */
+ W0 r7 @) T, |1 s4 B - static void _cbFrame(WM_MESSAGE * pMsg) { (4) a* J5 M/ R/ u" F' ~
- switch (pMsg->MsgId) {
" p/ t8 T! Q! u. J8 R - case WM_NOTIFY_PARENT:$ {& c( h5 Y* Z+ d: r" r+ J
- if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {4 O [7 W9 f6 l; u1 y
- int Id = WM_GetId(pMsg->hWinSrc); // Id of widget& n8 W, e0 q O/ p5 [
- if (Id == GUI_ID_CLOSE) {
8 e1 O2 i: A# u6 z - if (_LockClose) { R5 B- O7 C2 z, G( Z N
- return;
+ T5 Z( w6 g; K0 L. n) w - }
( D# [' A/ N! j& P3 e - _hFrame = 0;
! Y, o. n2 \3 M* s0 W - }' V1 d# v/ K2 E$ l8 d- O
- }
) d* z: H0 V* ^6 Y3 { - break;; s+ Z5 s/ `3 ^$ i/ I! V- s5 ~
- }/ h: k1 O/ U) {: a, W6 _( c
- if (_pcbOldFrame) {
u3 T6 s' Q1 I/ ?1 W8 r3 |* M - (*_pcbOldFrame)(pMsg);
. a5 Z" j( L1 y$ t0 n5 Y - }; T7 c& B j9 m- \
- }3 E& Z8 ]$ a/ [' w
- / g! _4 A% |# a
- /*******************************************************************1 V/ ]& Q& B4 e, n# u' i( [
- ** e$ ?$ s$ k, N* {
- * _cbBkWindow- M- P1 P, A) w7 K! R
- *
1 G/ m2 `5 O* Y% q: C* g - * Function description6 A$ }. q% i# j; q5 t- ]3 s% h4 E7 K
- * This callback is necessary to redraw the background when
9 \( A u! U- \ U6 W1 v7 ~ - * frame window is moved' ^. G7 k4 _$ A+ `' y1 G+ I
- */3 C* m! ^; Y9 E3 _8 |" f- i
- static void _cbBkWindow(WM_MESSAGE * pMsg) {(5)( |2 k' M. y! I* l
- switch (pMsg->MsgId) {" k& K3 E$ o7 i
- case MSG_CHANGE_MAIN_TEXT:
& S- T2 V7 L7 _5 L( N - strcpy(_acMainText, (char const *)pMsg->Data.p);2 ]+ {" J4 x' p$ w2 W
- WM_InvalidateWindow(pMsg->hWin);
( y7 v: E* f' H7 T - break;
$ T$ m6 Q, C! R% ~% e: S( g - case WM_PAINT:
' Z, }" u& H# Q B - GUI_SetBkColor(GUI_BLACK);
2 K/ X7 w; u5 t! N - GUI_Clear(); Y- \3 ?+ ]% [( p, F) l
- GUI_SetColor(GUI_WHITE);
( a# t) k# l' P - GUI_SetFont(&GUI_Font24_ASCII);
& T$ P" @. i) P3 f% D - GUI_DispStringHCenterAt("WIDGET_FrameWin - Sample", 160, 5);
/ t' j9 c* a; _8 o- ]3 s; k - GUI_SetFont(&GUI_Font8x16);, j% s4 F+ W8 f) k1 ]8 N
- GUI_DispStringHCenterAt(_acMainText, 160, 40);
l$ N" J3 _: r, e1 |1 Q - GUI_SetFont(&GUI_Font6x8);9 e( F* V) b2 O3 a1 `$ {. l- L0 d0 O5 o
- GUI_DispStringHCenterAt("The function FRAMEWIN_Create creates both the\n"' `& `* k. y f3 L) X( _1 B# [* R
- "frame window and the client window.", 160, 190);
3 S/ s) Z4 U5 ~ - break;& y7 G+ y; A+ P5 k" w
- default:' d- \& s7 G6 M0 y
- WM_DefaultProc(pMsg);
1 X/ O5 G8 N4 v! G5 h - }
1 s5 {4 d* @; K2 _ - }1 N' U/ w- G9 u: T$ r# U2 r( L
-
0 \3 C5 \5 R7 H - /******************************************************************* V& n( A* B, l6 ?; p
- *% O$ u7 B V- v6 p
- * _DemoFramewin5 Q. p6 l- b# B
- *; _; v9 E" z" W: }
- * Function description
8 u/ {7 o A/ A9 s; v/ R - * Creates the frame window and sets the callback for frame, child
( g C9 u9 y# S - * and background window
) ]! r% t# J2 f# W. {" x. k1 ?3 ^ - */, g f+ Q" Z9 `% \: j- F$ r2 Y
- static void _DemoFramewin(void) {(6)' M& ?4 W' D8 J' |/ K- t* }
- int i;
8 n4 n3 K2 x8 E - char acInfoText[] = "-- sec to play with window";
6 e. a" C( I! k/ r: _5 J - WM_HWIN hChild;
6 F0 X7 C' B3 `8 G+ Q: M7 C -
. J0 {, u" p X1 G; U" J8 b" N -
9 Y+ |0 R$ G: B1 E( V. a - WM_SetCallback(WM_HBKWIN, _cbBkWindow);
* y4 [" g, { t# w( E7 {; @ - //
( s; x ^1 [ ^! G6 D - // Create and configure frame window
8 M0 M9 X8 p( k: { - //- K% p0 I' H* u+ ]
- _ChangeMainText("FRAMEWIN_Create", SPEED);2 G5 o; G$ o8 A; m
- _hFrame = FRAMEWIN_Create("Frame window", 0, WM_CF_SHOW, 50, 75, 220, 100);(7)3 f7 H* X8 P+ A2 D% e
- _pcbOldFrame = WM_SetCallback(_hFrame, _cbFrame);(8)% E: @4 | F1 K- j( m( ~) N
- hChild = WM_GetClientWindow(_hFrame);(9)! a" P' e8 e; K
- WM_SetCallback(hChild, _cbChild);(10)
' F6 @( { S$ B$ T - FRAMEWIN_SetMoveable(_hFrame, 1);(11)
" c# F$ m; c6 H9 s; H* F1 G; ] - //# s% v$ e4 }( F8 w* M
- // Create buttons
, e: D- G" e0 W& L) C7 F - //7 [) n, s0 t6 `; g0 R4 G" Q y
- FRAMEWIN_AddCloseButton(_hFrame, FRAMEWIN_BUTTON_LEFT, 0);(12)
1 h# H6 Z5 N( m. l$ D2 o) X - FRAMEWIN_AddMaxButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 0);/ Q* U8 @0 Y& E0 ~1 ], D
- FRAMEWIN_AddMinButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 2);
; n& r* l) f# V6 | - //: i& _* A R# i% l
- // Modify frame window attributes' @3 A* K- M7 h* C. v q
- //
F. Q( Q# P* B8 y# u. i% ~9 O8 e - _ChangeMainText("FRAMEWIN_SetActive", SPEED);
0 B3 O, R+ c$ O! o2 [& Y y - FRAMEWIN_SetActive(_hFrame, 1);(13)
9 [ U+ q" ?7 I - _ChangeMainText("FRAMEWIN_SetFont", SPEED);
3 ~0 t& `1 ^. |+ ~9 r* c. a - FRAMEWIN_SetFont(_hFrame, &GUI_Font16B_ASCII); (14)
7 j9 i8 b0 Z5 x - FRAMEWIN_SetTitleHeight(_hFrame, 20);8 J+ P( V c5 P
- _ChangeMainText("FRAMEWIN_SetTextColor", SPEED);
$ L. Q7 `2 V# x - FRAMEWIN_SetTextColor(_hFrame, GUI_YELLOW); (15)7 u! P3 C: O" s, T
- _ChangeMainText("FRAMEWIN_SetTextAlign", SPEED);
5 h7 k' T J6 G+ ]9 ^ y- z2 l - FRAMEWIN_SetTextAlign(_hFrame, GUI_TA_HCENTER);(16)4 y w( Q, [3 _& G' C7 g7 E' C0 a6 g
- _ChangeMainText("FRAMEWIN_Minimize", SPEED);
3 y5 p3 M/ d" P/ s3 n* p% x7 s( | - FRAMEWIN_Minimize(_hFrame);(17)4 z/ V. Y2 G7 ~- L, T: B8 b4 @3 I( }
- _ChangeMainText("FRAMEWIN_Maximize", SPEED);# }. P ^3 j' `) h, @) k
- FRAMEWIN_Maximize(_hFrame); (18)
' A& J, @1 h1 n# D4 V' ?* K; k - _ChangeMainText("FRAMEWIN_Restore", SPEED);
Z) L/ ^6 K0 N - FRAMEWIN_Restore(_hFrame);(19)
+ Z _& o, O; v7 Y- G n - _ChangeMainText("FRAMEWIN_SetTitleVis", SPEED); G) J2 q* a) x2 Y8 g" h
- for (i = 0; i < 5; i++) {
1 b9 {; b/ h4 F - FRAMEWIN_SetTitleVis(_hFrame, 0); (20)3 _6 _, x- R( B1 L# C7 a. h) |4 A; J
- GUI_Delay(200);
- ^: \. u Q7 k6 L - FRAMEWIN_SetTitleVis(_hFrame, 1);: m6 o1 j, E. @: T" z3 v# w
- GUI_Delay(200);+ _, f) q( ]8 V+ Q+ I- n0 P0 l
- }
* r9 m8 X! o' s4 F) ^. E7 R% J1 h - //
5 m# x) Z& v z; J% S8 v - // Time to play with frame window/ L/ @2 {7 ]3 v, l" U
- //" B7 I( r4 G! W( }0 p
- _LockClose = 0;5 |/ h$ w5 F f
- for (i = 250; (i > 0) && _hFrame; i--) {
7 s9 ^& p+ ?8 f$ o* ^ - acInfoText[0] = '0' + ((i + 9) / 100);' w- G3 g, m2 S* f3 g0 A! S$ J0 B
- acInfoText[1] = '0' + (((i + 9) / 10) % 10);
/ M4 m3 Y. x; w) v( [ - _ChangeMainText(acInfoText, 0); m- s8 F" T7 t0 n+ W
- GUI_Delay(100);
9 I+ {# b7 E. C( V, B6 P - }& A/ L' e) C! C( f0 n3 T
- if (_hFrame) {
5 O1 P$ w9 J) m& c9 `& G+ j8 Y - _ChangeMainText("FRAMEWIN_Delete", SPEED);
( m0 s. H' w9 B o2 g' L - FRAMEWIN_Delete(_hFrame);(21)" _2 w; _9 \$ M$ ]8 T9 X" M
- } else {
3 A1 B3 [& t, z$ a( u6 B2 J: f - _ChangeMainText("", 50);* C" B/ B, B% V/ o/ r4 P2 k/ X# {
- }- g- k, t% H$ }6 }3 p
- }. k8 J6 Y" w4 T6 B3 c5 p
-
+ n9 B" q+ G8 ]4 q9 Q) \ - /*********************************************************************2 b" M2 O" ] ]
- *2 T/ u% }# O# e7 p7 R+ ^# g0 p
- * Public code
4 @8 y( t* w& ?" l9 e2 l, t - *7 _) J$ q% T* F( B
- **********************************************************************; V' h; D" E# f, k* t/ {& g
- */6 p- P% w ~3 [5 C/ t+ ]$ Q
- /*********************************************************************
3 Y ^" p3 _$ h- ], p: Z - *
7 F0 T% M6 A; a" M% B8 ^" _! X' Q - * MainTask" D# L( `7 ]' G/ a
- */
9 r# s* f6 S" x* ]8 F6 G - void MainTask(void) {
6 x; Y# T5 q3 w- y - GUI_Init();% p" J7 v% h4 K% e0 `; q
- WM_EnableMemdev(WM_HBKWIN); (22)
" l% J4 k* Q4 j2 q4 o- ~6 J8 @ - while(1) {! ?8 C" P0 R4 e: L
- _DemoFramewin();
. q' Y$ }, q( Q+ C7 X - }
3 h, D) B, e' A" b& w& s4 J+ S - }
复制代码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大家都可以试试。
( |2 G- i; [. @6 { |