特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接+ V# B1 B3 f( Q" E
第44章 FrameWin-框架窗口控件
7 |4 I' H j$ |/ T 本期教程讲解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>1 s1 L5 b$ U# T" }4 V
- #include <string.h>
F3 e! |. M [$ C$ a- y" K1 o9 U! V" R - #include "GUI.h"+ M8 W; Y# |/ S0 H% a, a6 u
- #include "FRAMEWIN.h"
2 g/ W7 L7 E- ]: C& w/ ] -
% |: n. [- K8 I }! E- q, b - /*********************************************************************8 F$ L6 a& [6 O" L; ~7 ~- U
- *; \+ M v8 ~4 o7 r
- * Defines
$ A6 X2 I% t2 a1 J$ |' b6 k - *$ E0 @0 {5 a* b, g
- **********************************************************************& e ?/ i+ \6 Y0 d
- */2 N* V5 Q1 k9 ?4 E1 Y7 ^, Z
- #define SPEED 1200; U4 a' @- K' H+ a8 D
-
. E3 o. H! @2 C - #define MSG_CHANGE_MAIN_TEXT (WM_USER + 0) (1)
- ~; p7 t9 A4 k0 l! z1 ^ -
1 ^9 U6 Z w9 h4 P" S( d - /*********************************************************************
& p+ ]0 [. d x6 l6 ^' f! T, @/ \ - *9 h+ m! ^. B+ J2 F/ Q
- * Static data3 D" |- ^. P0 m6 H2 ]
- *) d# C K( B8 U) y! r9 c6 |
- **********************************************************************. }) Y3 b }8 B, q% [' U
- */0 {8 ?6 a+ R9 |1 m0 l3 ?
- static FRAMEWIN_Handle _hFrame;/ H1 w% b/ F* n$ Z( P# ?/ Z
- static WM_CALLBACK* _pcbOldFrame;! B& |+ g2 s: S% M( L: x+ T
- static char _acMainText[100];
; y- ?) o* i4 u. c - static int _LockClose = 1;4 [1 C* D* v6 r- n7 k# n) \/ m
-
. N3 g' ?( u9 N7 Y+ w$ b - /*******************************************************************5 o' J2 Z+ W; W
- *$ i/ \" E8 g% W5 H
- * Static code
/ l9 I9 K8 ^6 F: @) j1 { - *
6 c* ]* |9 I( |. a+ t' X - ********************************************************************
( [. k! R6 |) L1 u* D! [ - */
; ?" G7 H) ^1 R - /*******************************************************************7 _5 Q# v8 i$ a0 K, Y1 g2 ]1 A
- *
& }# v& r' O* n - * _ChangeMainText
: c: v2 i9 d1 Y: b - *9 p9 V Z, b8 X `
- * Sends a message to the background window and invalidate it, so. {8 \) M, }# E: Q# S/ i1 g0 d
- * the callback of the background window display the new text.1 n' `' @+ n1 [2 u
- */
/ E1 `+ Y7 X& c: g+ H6 i - static void _ChangeMainText(char* pStr, int Delay) {(2)
# c3 O! V( ^# {' _* x; I. `' U4 ]; F7 _ - WM_MESSAGE Message; c4 n, w0 E, g/ J, ?( c4 V
- Message.MsgId = MSG_CHANGE_MAIN_TEXT;
3 g. `$ t0 c0 c0 g# g - Message.Data.p = pStr;
9 A6 p" l7 c6 i- E - GUI_Delay(Delay);
9 x b! n' V( |2 S9 b - WM_SendMessage(WM_HBKWIN, &Message);( @6 j7 _/ T; d {
- WM_InvalidateWindow(WM_HBKWIN);
3 Q; Y V) Q- f/ O) l3 ~5 B+ h9 R - GUI_Delay(Delay/3);
5 f" O v5 A. w/ t& i5 x6 D# R$ [ - }
) e, q' O) t- ^: R. C - 9 N; [9 G1 C; D% j
- /*******************************************************************
& r* H$ B4 g# p! e - *0 L6 W9 W' x- M* b
- * _cbChild
/ v6 _5 H, k6 p1 S! h5 T4 l - */
1 Q) D0 j0 u$ i+ W8 m4 l0 H' f - static void _cbChild(WM_MESSAGE * pMsg) {(3)
8 G3 J* R2 t3 F! p - WM_HWIN hWin = (FRAMEWIN_Handle)(pMsg->hWin);3 V. d& k4 d6 l/ a
- switch (pMsg->MsgId) {
; M4 Z$ _% s3 I - case WM_PAINT:
8 r( X: ~3 M0 Z0 D& |, v - //
; |+ S9 F% O0 K v8 x - // Handle the paint message4 }, @$ b V, D1 F: Z
- //
9 ?+ R! Q2 T. ]1 r/ ] - GUI_SetBkColor(GUI_WHITE);$ P' x$ y! u2 Z/ H' D- ~/ I1 {
- GUI_SetColor(GUI_BLACK);
' K! d) r% l W/ | - GUI_SetFont(&GUI_FontComic24B_ASCII);9 J/ q* |. j- W& R
- GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
- }9 b! s8 \8 R! M" m7 K% H* U2 ` - GUI_Clear();* s1 q5 h+ |) A; } c. Y( G
- GUI_DispStringHCenterAt("Client window",
& E8 Q" T1 ?7 n# n - WM_GetWindowSizeX(hWin) / 2, . a+ `- B1 a6 [% h* ?/ d$ g
- WM_GetWindowSizeY(hWin) / 2);; w. D' U P8 \. U* X
- break;, e* s x9 w* U9 m
- default:
! V6 d& _5 t* {' |5 y0 \ - WM_DefaultProc(pMsg);$ `) k8 b6 @* C
- }
, B j9 \% g/ K) u/ N9 \$ }8 n - }
4 m8 U4 n( z' d$ ]6 y9 W0 [& b$ D - # X: K$ v) q, C: b% x1 I& }
- /*******************************************************************; c9 H& L0 F5 @( V2 \* Q
- *
( o3 x$ N" s( m - * _cbFrame
2 }6 ?- W* P+ O. v7 M' t9 F - */0 u6 s( j* ?' e
- static void _cbFrame(WM_MESSAGE * pMsg) { (4) z. }9 J, Z7 R6 G* y2 q$ ?
- switch (pMsg->MsgId) {
9 o& D( l3 t! T+ S* [1 o - case WM_NOTIFY_PARENT:, r9 S9 U& m2 T3 h) b
- if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
* b$ W# U4 `& |; C0 z q - int Id = WM_GetId(pMsg->hWinSrc); // Id of widget
9 m$ u: L: P3 g k3 B. w* w - if (Id == GUI_ID_CLOSE) {% _" y$ l ^" z0 m, ?; T% A
- if (_LockClose) {/ v3 K Z2 c- j {
- return;
9 [/ S: c: r0 z0 E - }
$ c1 o V6 E& o5 T9 m0 [% e - _hFrame = 0;# j) R" a& B/ P& C8 u
- }6 t m7 R2 |9 Z- U3 ^
- }
) l+ i( a# R3 h: D9 \+ s - break;
3 f& ]) B9 y; j) N; k - }% y" K1 A! m$ \
- if (_pcbOldFrame) {
) V6 l) O# V3 r5 Y1 r- h - (*_pcbOldFrame)(pMsg);6 r- X6 }# f! L8 p7 _' ?* ^
- }4 ?2 w; Y: Z0 r) y
- }$ ]3 S( o: @$ ?/ b2 ]/ X
- 3 |5 b' r @8 K3 H" Z
- /*******************************************************************
$ e2 B4 R$ l i. J8 K: H; D - *( G% Z1 O/ j9 W1 N3 Q7 W7 e% t
- * _cbBkWindow% c5 f" z. {: {, {* ~
- *8 w+ L0 h: t: Q& e1 ]+ h
- * Function description/ N4 I9 o* {! e0 Z5 c" t6 @
- * This callback is necessary to redraw the background when
7 b7 c0 D1 w/ C. p a4 d) V - * frame window is moved/ I# E( V/ W+ z+ E' a' M6 S2 x: t! k c
- */
% q0 ~* b+ o/ B8 F) I0 I - static void _cbBkWindow(WM_MESSAGE * pMsg) {(5)
7 A( e6 C8 a1 E! m, _/ F/ @- i4 E - switch (pMsg->MsgId) {; @" ~! ~+ F ]6 l* {
- case MSG_CHANGE_MAIN_TEXT:
) q/ P; j k8 _- Z* n1 k" W - strcpy(_acMainText, (char const *)pMsg->Data.p);% Z" ?' f$ p4 Z0 D1 [5 p( U
- WM_InvalidateWindow(pMsg->hWin);
. Q* w$ A/ J, c, F( ` V - break;! b6 Q7 |* `! m+ ]2 K3 c
- case WM_PAINT:
# R, w3 ?& w( e# j - GUI_SetBkColor(GUI_BLACK);
* v' {. X; J4 b) A3 [$ h5 t1 k# T - GUI_Clear();$ t6 u! ~: }0 O$ M/ l; `' _" W
- GUI_SetColor(GUI_WHITE);
: |7 G1 Z4 o( Q9 ]) q - GUI_SetFont(&GUI_Font24_ASCII);
: U) t2 p/ Y& n: V - GUI_DispStringHCenterAt("WIDGET_FrameWin - Sample", 160, 5);1 n5 @" p$ Z( X
- GUI_SetFont(&GUI_Font8x16);
( e9 y2 R8 ? L& l - GUI_DispStringHCenterAt(_acMainText, 160, 40);2 ?$ C R! V' l0 Z1 f1 `
- GUI_SetFont(&GUI_Font6x8);7 t" z5 W2 g& \
- GUI_DispStringHCenterAt("The function FRAMEWIN_Create creates both the\n"
2 {% M8 f1 ]9 Y2 M2 ?# s - "frame window and the client window.", 160, 190);3 t- d* I) B/ u. ]
- break;
$ x# H5 Z3 b6 C! Z: r - default:, J* F8 j( N! G9 a( C2 B# G( V
- WM_DefaultProc(pMsg);
9 @5 W3 j" N8 Q% Z) P H# o - }) A m6 F6 F( }3 @
- }
. J1 {& p# Z- b0 Z7 d4 t6 G4 Q - / c( W# i4 ?% A( \1 w. d2 C0 K8 y
- /*******************************************************************
: W* {' n2 b7 O9 l - *
/ J1 Y# d! N6 \& h: N - * _DemoFramewin
) m3 V3 F" l9 v7 s' o - ** [" [' X! z) c7 G" b% ?
- * Function description0 u* @6 C$ t6 Y) J0 R: L( s
- * Creates the frame window and sets the callback for frame, child
: T6 `$ a' _) P, y" t+ u8 n- P - * and background window
4 ]6 U W2 g3 }9 u - */4 h* z( r- |, ^9 f( m6 k. f
- static void _DemoFramewin(void) {(6)) S9 @" F X1 z5 V+ N" A" d( r
- int i; D" o4 Y2 s5 x( Y- ]
- char acInfoText[] = "-- sec to play with window";
7 z4 X* N& t' o' \% c- h3 l - WM_HWIN hChild;
* w$ e6 x1 [' v - $ F+ ]! z4 j7 V3 R1 Z' i2 @
-
- @0 `; c. ^( } - WM_SetCallback(WM_HBKWIN, _cbBkWindow);6 M# \- l+ {, E
- //
9 w5 ~; y) ?/ ~ - // Create and configure frame window
9 n# r' G" e* n7 S# D E - //7 g- O o" @! Y; v
- _ChangeMainText("FRAMEWIN_Create", SPEED);% [& Q8 X$ ^8 i& K- k, y& o! D
- _hFrame = FRAMEWIN_Create("Frame window", 0, WM_CF_SHOW, 50, 75, 220, 100);(7)3 X3 M: ^# `" g# a; ?- C
- _pcbOldFrame = WM_SetCallback(_hFrame, _cbFrame);(8)% ?( _% R, K8 b. T
- hChild = WM_GetClientWindow(_hFrame);(9)
3 E. `. z# q0 a: r& @$ X6 e - WM_SetCallback(hChild, _cbChild);(10)
- m1 G5 E% t2 ?" F- h+ z2 b% A - FRAMEWIN_SetMoveable(_hFrame, 1);(11)& w/ Z* v( A: Y' F, O$ r- @
- //. z9 ?5 U; U; K6 K4 Q" R& @7 G
- // Create buttons
T* \. m% k3 K9 ~" K0 o - //8 G3 d. J! j& B- K8 \
- FRAMEWIN_AddCloseButton(_hFrame, FRAMEWIN_BUTTON_LEFT, 0);(12)
9 o$ N# h1 D M& E1 k0 `) ?( v) r - FRAMEWIN_AddMaxButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 0);
2 j* I: i! g2 w/ ?2 q Y2 z - FRAMEWIN_AddMinButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 2);- {: I) [( L* D) h' b
- //
' p8 a" G% s* t2 H; {' @$ |6 v - // Modify frame window attributes
0 O. b( {2 m7 I3 I+ } - //
/ T @3 A, G3 _1 ]8 D% f - _ChangeMainText("FRAMEWIN_SetActive", SPEED);2 E6 M; E) M* N0 P4 c @ _
- FRAMEWIN_SetActive(_hFrame, 1);(13) n N( ^4 j* ]& m
- _ChangeMainText("FRAMEWIN_SetFont", SPEED);
7 f0 c/ _, h8 i1 D - FRAMEWIN_SetFont(_hFrame, &GUI_Font16B_ASCII); (14)
0 A+ V% J$ y7 L' n# k5 v1 x - FRAMEWIN_SetTitleHeight(_hFrame, 20);! V. h/ d' O* I( X
- _ChangeMainText("FRAMEWIN_SetTextColor", SPEED);6 `, V! m2 V3 B+ @) ~3 B$ ?
- FRAMEWIN_SetTextColor(_hFrame, GUI_YELLOW); (15)
$ l* r. d; s0 _3 G5 ?0 R - _ChangeMainText("FRAMEWIN_SetTextAlign", SPEED);
' z. b: n/ }3 y# Z" C - FRAMEWIN_SetTextAlign(_hFrame, GUI_TA_HCENTER);(16)# z* s$ p Z$ l* a& i: m( m
- _ChangeMainText("FRAMEWIN_Minimize", SPEED);
9 R" O. j1 r. R7 z" j8 M5 {$ x# @ - FRAMEWIN_Minimize(_hFrame);(17)2 w, j, `, w# n9 V: W1 X
- _ChangeMainText("FRAMEWIN_Maximize", SPEED);
# e+ ~8 S! V5 W+ k - FRAMEWIN_Maximize(_hFrame); (18)
4 Y# w* \$ m- ? k- n5 G - _ChangeMainText("FRAMEWIN_Restore", SPEED);
! k% c5 `( g& W! ? - FRAMEWIN_Restore(_hFrame);(19)
& Y4 A8 V' N& |- x" O" \: p- ^ - _ChangeMainText("FRAMEWIN_SetTitleVis", SPEED);1 T, g8 G6 W9 S* A9 `2 O
- for (i = 0; i < 5; i++) {1 d: E, q* G6 X. i! R
- FRAMEWIN_SetTitleVis(_hFrame, 0); (20)
) R$ M& a; z5 u- l# \$ z( l( U - GUI_Delay(200);9 Z4 ^1 e! k- l5 T/ a
- FRAMEWIN_SetTitleVis(_hFrame, 1);2 ?/ n7 u! ~. d, N' R8 }3 ?. S
- GUI_Delay(200);
2 {; k, |" A. a& L4 J0 v1 L* { - }( Q) Z% |2 X u. _8 L
- //! U. k6 G4 ?0 @0 d; S1 e; C2 _
- // Time to play with frame window
: v' R2 d+ S0 S6 ~/ R$ i' { - //
$ v5 J# w5 r7 d# R# h1 C - _LockClose = 0;5 R8 ~; \2 m2 z Z
- for (i = 250; (i > 0) && _hFrame; i--) {+ c' z( h' X8 T$ g( M* n# g
- acInfoText[0] = '0' + ((i + 9) / 100);- l. ?- E& {$ j( R, H4 S0 I
- acInfoText[1] = '0' + (((i + 9) / 10) % 10);
; G* x6 x1 U+ h- }! i - _ChangeMainText(acInfoText, 0);; d; j! A7 f- q% O
- GUI_Delay(100);- u" y5 A \2 u+ H# k" F
- }
6 C" m/ H0 R& z2 K. E - if (_hFrame) {
. q( Q S7 Z# E6 }$ G) ]& r. Y - _ChangeMainText("FRAMEWIN_Delete", SPEED); g4 j' b9 q% r' j
- FRAMEWIN_Delete(_hFrame);(21)
" M! X. N9 S* B' f - } else {
& s. G5 O g7 }) \, F3 j - _ChangeMainText("", 50);0 x0 r) g- A! i
- }
, R9 j' S$ V5 ^1 H! e5 Y - }; k- d' a) W$ m$ u) X2 n% E
- ! R1 O7 q$ p! h3 y; ^
- /*********************************************************************( L3 B1 v9 B8 l9 } T
- *3 @' ?1 y U0 H0 M
- * Public code. d3 m9 [$ d- @5 l y
- *3 A! o4 r; ^8 f4 h3 h5 X
- **********************************************************************" h, G9 F7 \) t
- */
* f- i# s' [3 d e; ] - /*********************************************************************
* k! w1 m% H# [5 w - *& F6 M7 ~: V; |; q, x" `# z
- * MainTask
" T5 [2 z5 q$ W - *// k, q0 h) I& E! J. H- c
- void MainTask(void) {
K2 v. t8 V9 {, I - GUI_Init();" D* y5 l+ w) j6 [8 w$ {! b
- WM_EnableMemdev(WM_HBKWIN); (22)- Z$ n9 k5 [% W% G! ?* z$ X
- while(1) {
. [- F3 @" p1 o! S - _DemoFramewin();, k# J8 e, m: ^9 Y. k4 n
- }
2 _1 n P& p: y- r - }
复制代码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 L J7 ?6 ?6 l" {+ W$ ]
|