( D1 J1 S+ v. g; \! \2 b. B #define WM_MY_MESSAGE(WM_USER+100), 0 K( T9 b: O; N: G _; m- j# i# Z. \" c F- ~0 x
8 R9 q, G+ O! G& {" p4 D
MS 推荐的至少是 WM_USER+100( s: _) i, c. U( T! ^/ a
9 J' |4 ^/ N6 \6 e% o* q- s @
(2)写消息处理函数,用$ w) N) {0 G- b" I5 c/ p) h! E
; [" [3 Z; M$ `: e$ o, B/ @ C
; r5 K8 y# Q( g9 P! Z% I X/ g
$ {& e/ n6 g" q) R
# L3 S& Y/ N2 s7 J WPARAM,LPARAM返回LRESULT. 7 T7 Y. p3 f. A3 A) l3 v0 S$ ?+ j LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)+ \# l4 h3 v- E: l8 ]! ^- ]
6 z) U0 r, z/ A7 k4 V6 `
{ " j9 K) Q! H- L7 P temp目录: Use "GetTempPath" " E; y! I. E* t* C% J+ z6 H //加入你的处理函数 irectory"9 {/ t1 e8 O. p8 @0 X. j+ V
}# H n/ w+ r8 H
$ H" K6 O' K6 Y0 L' P0 { (6) 如何改变窗口的图标?# c6 o1 `. Y6 u7 H5 ~7 U V) a% M
向窗口发送 WM_SECTION消息。 8 t6 y, r W: s8 s# L9 P+ @& ^" x9 l* x5 P' _7 t
, [! y% y9 k% s, t m; V& s& O, D' |# f$ a+ b
, ~1 T% W( k9 Z0 o; z& t. {+ E8 i+ Z
Example: / b# a: e7 x4 O# k HICON hIcon=AfxGetApp() ->LoadIcon(IDI_ICON) 7 f6 ?2 n4 X- Q4 j3 L& q+ a ASSERT(hIcon) # p2 ~ L5 G7 O$ ~# z4 M AfxGetMainWnd() ->SendMessage(WM_SECTION,TRUE,(LPARAM)hIcon) * r0 v& C! W! K: z5 ^+ k R0 h 3 {) x. v' h- e9 W (7) 如何改变窗口的缺省风格?! n4 ^* l' [& x. c% w7 H
重载 CWnd:: PreCreateWindow 并修改CREATESTRUCT结构来指定窗口风格和其他创建信息.0 I+ w% ^$ B. A2 P
7 ?1 I8 R: Y( l1 W
* R0 s- [4 `5 Y/ I
/ H* c1 S5 r1 J8 B, ]7 d& E( F
/ D8 j9 L4 @8 F6 H4 O Example: Delete "Max" Button and Set Original3 q% O* v: H# M
Window's Position and Size1 O ]/ j8 E1 Z W8 a7 }
( e+ ^# b( x, o- ^/ c BOOL CMainFrame:: PreCreateWindow + U z. O s6 N( _' `$ G (CREATESTRUCT &cs) * e4 c1 I: {% E0 c8 T5 y# A {+ D. D3 r+ E* }6 h/ w; t
cs.style &=~WS_MAXINIZEMOX 0 F; P [6 ^' `" M' ^! r* L |2 {1 M0 t- [, B: q1 | u
cs.x=cs.y=06 O1 N R# Q3 |: F+ W; J
cs.cx=GetSystemMetrics(SM_CXSCREEN/2)8 V. N0 }# i9 H- U8 T
cs.cy=GetSystemMetrics(SM_CYSCREEN/2) . ^, l; s, [( |7 l & ]5 C9 @# ?4 k* E1 B6 Y return CMDIFramewnd :reCreateWindow(cs) - E7 P& X0 v. k$ L1 t6 D } 9 j4 A) A m2 s9 M! s) P5 w2 x7 | 1 d s. S, |8 A(8) 如何将窗口居中显示? + q* ~7 z. z6 b2 `! V g9 M! \* U G! \2 V) S. N. f; P% ^! {4 B2 z# j
2 h1 `2 }* ]% N' `. E# u2 D) q# u/ q. S
Call Function CWnd:: 9 }2 D6 c6 |( Z& Q7 C Center Windows ' ?# Z* m+ ]; C g: q3 u( C* k1 U& r9 }0 _$ G% N
Example(1):8 V; |0 p: [8 P
Center Window( ) //Relative to it's parent ( z- B" C9 A/ t+ X+ o // Relative2 `0 `* l& g: @6 y" E5 w" ?" i! i
to Screen+ R8 ~) A0 I3 D* i7 A" T
Example(2): * m i/ Y6 a2 O- x Center Window(CWnd:: GetDesktopWindow( )) 6 C# l2 A( a) N% V1 u) z //Relative to 9 o- }7 d7 r1 ~6 E Application's MainWindow9 @6 C* S3 T$ C: Y; i% K
AfxGetMainWnd( ) -> + y3 \- e3 J; G M* _' \ Center Window( ); V- j9 ?9 ]) V8 c+ \ X6 k9 M8 h
7 Z/ n( Z; D+ n' n$ C
(9) 如何让窗口和 MDI窗口一启动就最大化和最小化?0 p8 K5 T4 P/ l8 w& r
先说窗口。7 X0 x# D8 K; a5 J5 ~# d
在 InitStance 函数中设定 m_nCmdShow的取值. % G4 }, v( l+ H7 P' y , i) \ E, W$ h9 d9 p( P5 j 5 E0 e. t0 f( y A) c4 { : w* J& W& K2 U ]* \; v: J+ _9 q$ Q/ q ~( @
m_nCmdShow=SW_SHOWMAXMIZED //最大化 , q" W+ \+ v/ N m_nCmdShow=SW_SHOWMINMIZED //最小化 C2 N* l2 f* e0 L! {( J3 l1 o m_nCmdShow=SW_SHOWNORMAL //正常方式" t8 I/ w+ h1 m/ B( u2 U
; }# t; h+ ]6 M% K) l6 q MDI窗口: 3 W4 j6 _; S- [/ j8 M 如果是创建新的应用程序,可以用MFC AppWizard 的Advanced 按钮并在MDI子窗口风格组中检测最大化或最小化还可以重载 MDI Window 的PreCreateWindow函数,设置WS_MAXMIZE or WS_MINMIZE F/ O! b% p4 K& N# c3 M 2 w1 B4 z9 g. r8 S0 m H! P/ Q 如果从 CMDIChildWnd派生,调用 OnInitialUpdate函数中的 CWnd::Show Window来指定 MDI Child Window的风格。- ^& U- \2 u+ S
+ f l: W$ X5 y" p' A) j/ ?; @, u
(10) 如何限制窗口的大小? : a4 ] S/ g2 {* K9 @* m% S- J: \ 也就是 FixedDialog形式。 Windows发送 WM_GETMAXMININFO消息来跟踪, 响应它,在 OnGetMAXMININFO 中写代码: ) t; }, {) I8 h8 V' \. t; |6 n- B! h
(11) 如何使窗口不可见? ( o4 Y( J- K2 E% {( |2 k 很简单,用SW_HIDE 隐藏窗口,可以结合 FindWindow,ShowWindow控制.7 W8 w$ B- M V! W4 n
% Q' H6 u2 a( X+ Y. \0 W0 s6 X (12) 如何创建一个字回绕的CEditView 6 {5 R7 J2 v+ \% x& C; D3 d/ K9 l 重载CWnd : : PreCreateWindow和修改CREATESTRUCT结构,关闭CEditView对象的ES_AUTOHSCROLL和WS_HSCROLL风格位, 由于CEditView : : PreCreateWindow显示设置cs. style,调用基类函数后要修改cs . style。5 Y# u1 b2 V J3 F+ \! x
) x+ V: S% b# |: j& Z; U
! J0 [! z5 c7 E' {, s# @/ {8 ` , V9 q5 k! d$ q% J- I; P- ]) r$ ], X3 i3 `! F* K' f3 S
BOOL CSampleEDitView : : PreCreateWindow (CREATESTRUCT&cs)) [! `( K" ~* R7 |2 o
{: f |% o' D; x2 t
//First call basse class function . 7 e! c- ]* {3 ?! K! B& ?& D$ w b8 D BOOL bResutl =CEditView : : PreCreateWindow (cs)( u# ~4 W3 T3 m2 a
' a$ @$ M4 f. t& r // Now specify the new window style .: ^8 b- ~9 \8 F" ~/ G( N
cs.style &= ~ (ES_AUTOHSCROLL |WS_HSCROLL) & `5 f! w* _2 g3 u) Q6 j4 h return bResult. h4 f1 T$ F$ e9 J+ ?, @
} & a9 t# j9 e) K. R" K$ J- ~3 M3 m/ k+ E7 }
(13) 如何使程序保持极小状态? ! P8 [. M4 Z1 E. b 这么办: 在恢复程序窗体大小时,Windows会发送WM_QUERY-OPEN消息,用 ClassWizard设置成员函数. m& o. |$ U) s8 Y: l1 a! v
2 I/ q/ X4 v8 [+ w5 }4 x: A 1 ~: ^2 }' C/ X! c: v' \* x8 |5 {- O4 J, M5 f
4 B# R' v: n& c3 C7 B# A4 c- e' B8 v
OnQueryOpen() ,add following code:* ^, O4 |9 r# t0 e6 e+ w
6 j3 l: N7 t& j n% D' t- U' Q+ j Bool CMainFrame:: OnQueryOpen( ) c' e8 T8 z6 {% R* b# M( X( f: d0 z {: p: n1 \+ [, x9 [9 G
Return false2 ]+ E8 U5 x4 Y
}! ^- F2 `' L2 s' n, h* E1 ?
, U0 t4 c1 H4 a* m/ [8 m1 P
(14) 移动窗口 . t* k/ l& k5 _' [' Z 调用CWnd : : SetWindowPos并指定SWP_NOSIZE标志。目的位置与父窗口有关(顶层窗口与屏幕有关)。调用CWnd : : MoveWindow时必须要指定窗口的大小。 ) F* l- x4 i0 K% r, r. S5 S ; Z9 M; t6 d0 {# n* R, \5 Z! ]7 h 7 i v0 K- f- s% H3 r) o. y / K$ t r6 T, t- c , e' ~8 z% b, i8 z9 K+ s. |% P //Move window to positoin 100 , 100 of its parent window . 2 _0 v8 q, }1 a SetWindowPos (NULL, 100 , 100 , 0 , 0 , SWP_NOSIZE |SWP_NOAORDER)6 i6 \' ~" n F2 u
# I5 K) T/ j ]
(15) 通用控件的显示窗口 D- Q! n" }2 t4 n J a5 [- n MFC提供了几个CView派生的视窗类, 封装了通用控件的功能,但仍然使用工作框文档显示窗口体系结构:CEditView封装了编辑控件,CTreeView保持了树列表控件,CListView封装了列表显示窗口控件,CRichEditView可以处理多种编辑控件。 + {' R% X' w+ H' Q" n9 T- n$ M, V* @% y( s
(16) 重置窗口的大小 9 j( l" H% x: X1 A 调用CWnd: : SetWindowPos并指定SWP_NOMOVE标志, 也可调用CWnd : : MoveWindow 但必须指定窗口的位置。 i% q1 V& Y F- n+ y' y ( M5 ?9 t: s$ Z7 ~0 L 2 y) [, j5 |% }: w D+ X! y7 m0 |( e2 z. |: ^
: K5 P# _, B k- L
// Get the size of the window . 3 n3 \( q$ I) J1 y- `* K" s Crect reWindow # p" \! c3 @) B# H GetWindowRect (reWindow ) 9 i! K! X7 f) V( k$ C/ [9 N3 Z' W, \$ B0 } |$ F
//Make the window twice as wide and twice as tall . 7 J( |! a1 c& r& X SetWindowPos (NULL , 0 , 0 , reWindow . Width ( ) *2, , N3 U7 L! z% l9 C- t! U! m2 E6 z, y
reWindow . Height () * 2, 1 n" [, ?9 H$ ^8 N SWP_NOMOVE |SWP_NOZORDER ) ; ?. V$ h& \* o# w% r4 H 3 z, c4 v; u/ K3 c( V (17) 如何单击除了窗口标题栏以外的区域使窗口移动3 `, A' t4 g/ M
当窗口需要确定鼠标位置时Windows向窗口发送WM_NCHITTEST信息,可以处理该信息使Windows认为鼠标在窗口标题上。对于对话框和基于对话的应用程序,可以使用ClassWizard处理该信息并调用基类函数, 如果函数返回HTCLIENT 则表明鼠标在客房区域,返回HTCAPTION表明鼠标在Windows的标题栏中。: {" K0 h' u( D8 N {
* t" n) G3 P/ V(24) 如何创建一个不规则形状的窗口 - x( z. V- A4 [0 H 可以使用新的SDK函数SetWindowRgn。该函数将绘画和鼠标消息限定在窗口的一个指定的区域,实际上使窗口成为指定的不规则形状。 使用AppWizard创建一个基于对的应用程序并使用资源编辑器从主对话资源中删除所在的缺省控件、标题以及边界。 # Q& @: ?$ u0 J! H Z 给对话类增加一个CRgn数据成员,以后要使用该数据成员建立窗口区域。/ u" K. y; s- [1 z6 ^; N
) b7 M5 }9 W$ J B4 g7 @, J9 @& B$ C) ]
$ s0 r$ U% l! ` * l( i9 K% q' h# M Class CRoundDlg : public CDialog $ K6 q9 R/ y% k1 c ^ { " v& S! k$ y R9 W" i( i& O2 t8 x N2 e# e* d … % c# j0 f. m& ?) V, Y# H private : 1 H) S! a; O2 ~; Y7 R1 |* y( G Crgn m_rgn : // window region& Q2 W3 Y6 M/ M( ^* k
… 5 }& Q9 T% [; h: J* ~! K } 1 E m7 R" V( E! w6 ]! Z 修改OnInitDialog函数建立一个椭圆区域并调用SetWindowRgn将该区域分配给窗口: 3 @. [# F3 f2 t4 s2 M# K: n$ N BOOL CRoundDlg : : OnInitDialog ( ) " p1 S5 q/ x4 ]& K7 v ^ { / B" {" c( \0 }2 F+ p/ r8 f W CDialog : : OnInitDialog ( )" G$ x1 Y5 S1 C) t# c
, R, k2 f& u6 l( x: {3 Y
//Get size of dialog .( i2 o9 E! y Z+ Q$ X# G
CRect rcDialog 6 ?$ r2 X, K* y6 o, `0 l! T GetClientRect (rcDialog )! a4 a) T2 p* e8 f0 R' L! [# ?+ j0 n
r6 I, o3 D# j) L
// Create region and assign to window .- F v2 P' j; {4 ]- L9 r7 y3 U
m_rgn . CreateEllipticRgn (0 , 0 , rcDialog.Width( ) , rcDialog.Height ( ) )4 [( P/ [9 I+ I1 e( d) O
SetWindowRgn (GetSafeHwnd ( ) , (HRGN) m_ rgn ,TRUE ) : R( ^0 R9 H/ A) P. v# D( Y; w9 c" q0 K2 ]
return TRUE / b& E( @! b) \' _ } ) E4 x& p0 s/ X! n' v. [2 S* g* i9 Q7 _' @' I
通过建立区域和调用SetWindowRgn,已经建立一个不规则形状的窗口,下面的例子程序是修改OnPaint函数使窗口形状看起来象一个球形体。 , i, ~) @# D8 G0 } 8 W; x# u; D+ ] ^8 e( W, q ( Y1 `& q" N1 j- O$ k8 ]6 Z, \; |5 J- Q x) P4 ]6 r" |3 t% e8 S# Z
3 v7 H7 s- X% t. F3 g' L
voik CRoundDlg : : OnPaint ( )7 w N+ n+ `) s/ S4 ^8 W* m1 d
{ / N4 k6 ^; c% t+ Z CPaintDC de (this) // device context for painting( o5 x0 N# J4 U6 s
. 2 Y) ?9 q% b0 E. \) V1 m //draw ellipse with out any border $ L* N" c+ N6 N l/ V! z3 b% F. C dc. SelecStockObject (NULL_PEN) 2 T. \# m D9 L, P7 r //get the RGB colour components of the sphere color 4 _+ b4 R( g6 a* V5 J7 L COLORREF color= RGB( 0 , 0 , 255)% s) C0 |1 H: c% B3 y8 P; b. P0 D
BYTE byRed =GetRValue (color)8 w' g. x7 k' A+ p6 d0 ~
BYTE byGreen = GetGValue (color) 2 P( X$ J( P \. p# u/ c& C# { BYTE byBlue = GetBValue (color) V9 B Q) ^" A
' K [' J9 R, b# d$ J; ]7 W& ?$ t // get the size of the view window & {. P; e" O5 ~; C @6 ^1 y7 X Crect rect) m7 ?8 ?7 |8 E9 ^5 x
GetClientRect (rect) ' O( g9 T* Y2 ~) c2 b % ~! J6 f* [* E& {8 W. c) w+ l // get minimun number of units + b8 w* d; K9 x {+ s int nUnits =min (rect.right , rect.bottom )4 N9 L* t- R; [- r( x( ^% u
* N+ k, d B8 k: l" Q+ s //calculate he horiaontal and vertical step size * G3 g7 h- K, n9 d! _* E float fltStepHorz = (float) rect.right /nUnits" q) H( N; O4 |* L p1 z' |
float fltStepVert = (float) rect.bottom /nUnits2 v8 X3 }; J1 Q/ g6 h
, Z2 j, K$ A6 M& s" [
0 l- P) Y) F6 Y5 w6 K int nEllipse = nUnits/3 // calculate how many to . s- R% X2 i2 Z6 S5 g& U draw- [9 I0 X/ ^% @
int nIndex- x* A2 F3 C* U. p; o, q
// current ellipse that is being draw ! p) u7 h- O6 H( d9 z8 d2 d # S% i' Y4 z/ a( T CBrush brush4 N! f/ Q2 n/ ~
// bursh used for ellipse fill color ! V& n) L) `3 ^ CBrush *pBrushOld // previous + d( M( D( _; Y9 Y) u; Y brush that was selected into dc 3 k; h- n0 W4 N# M4 A //draw ellipse , gradually moving towards upper-right 6 W S0 o+ c3 p& z corner + N) ]) M+ w2 u/ b for (nIndex = 0 nIndes < + nEllipse nIndes++)0 E9 I [6 K3 }- v
{ 9 L4 d e3 X7 k2 ?* N* T //creat solid brush- {/ a6 ]7 b7 {$ z
brush . CreatSolidBrush (RGB ( ( (nIndex*byRed ) /nEllipse ). . B1 g0 X9 S; p: z ( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue) 7 _ i; w, y* P /nEllipse ) ) ); T! e% l1 Y; e/ @; f0 ^
% F- Q1 o3 i( Y8 V
//select brush into dc! ]2 n* E: c$ V! T
pBrushOld= dc .SelectObject (&brhsh) ; l/ D; @. ]4 v0 N; Z 3 Q% F/ p8 \6 p1 c* z4 L //draw ellipse, P9 L( i3 ?1 ?$ t, q: D
dc .Ellipse ( (int) fltStepHorz * 2, (int) fltStepVert * nIndex , ' k @0 `8 w0 H3 h rect. right -( (int) fltStepHorz * nIndex )+ 1, 6 w1 z& k7 Z* S% \. m' m7 k$ o rect . bottom -( (int) fltStepVert * (nIndex *2) ) +1)' E+ O: p* @, X2 R7 w* ]
6 I6 l. w, S. w# _( n3 R; U9 p //delete the brush% @, \/ t& P' C2 Y8 ?* ]
brush.DelecteObject ( )1 u4 r+ H5 S' }0 R
}" W w& [: V% u" i6 |9 V4 l1 @7 l
}9 m5 ^0 {$ I! w* z0 J
" P3 C5 v* o1 X% U$ B* M( Q
最后,处理WM_NCHITTEST消息,使当击打窗口的任何位置时能移动窗口。+ {- @9 U: r0 |3 [# D7 b
! `+ ^, Z) N1 G1 o" g# A
( Y7 s- U7 y, U" s" ^9 e/ _7 g! Q9 Q& t, \0 m
# {: W2 W A, f4 C7 U' o8 d UINT CRoundDlg : : OnNchitTest (Cpoint point ) ( k3 J" C" M. g& L. ~1 ? {( [; I! b. P0 ^ ~' m; s0 P" [
//Let user move window by clickign anywhere on thewindow . ! ^4 B( [. {# S: X+ g9 e UINT nHitTest = CDialog : : OnNcHitTest (point)& O! S! _/ R+ c( `' v, |" ]- `- O- q
rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest * h" E8 L; G; R 4 i4 l* M& p" P5 ] } 9 G0 U) b, ^4 c+ I ' a: I9 e$ A( D9 ?- |6 D' o3 h" } (25) 如何获取应用程序的 实例句柄? $ C0 }/ R9 i+ v ~ 应用程序的实例句柄保存在CWinApp m_hInstance 中,可以这么调用AfxGetInstancdHandle获得句柄. # e9 {- W/ s/ ?7 V* ?7 L8 ^6 T- L : L9 H( D. o2 f2 r/ X+ o ) ^' ^2 g+ ^) q: |) F+ g8 X! S
6 a2 v3 a- E y0 q4 z: P! u
Example: HANDLE hInstance=AfxGetInstanceHandle() # z0 \+ h; a/ }: Y' v( W" ?9 j 5 _! s: u, e" J4 r$ I+ P' [5 K4 e(26) 如何编程结束应用程序? 8 p. p; ]2 o7 {; i 这是个很简单又是编程中经常要遇到的问题.; ?- K5 v* m0 G
向窗口发送 WM_CLOSE消息,调用 CWnd::OnClose成员函数.允许对用户提示是否保存修改过的数据. , r+ s1 q5 ?: `! e9 M3 a) y0 j2 ]% O. [6 @- u: l F* b
[被屏蔽广告] 4 ]$ I. _4 \* O4 d. t/ `3 g 7 W: \1 k& U% a7 }; m 系列文章:VC实用小知识总结(一) , X+ I4 W( Z9 S, l" N % ?: [. d. T8 }* \& B6 I+ Y$ u" V& E; C, Z J8 r6 w' G
& f' D, ]8 l8 a7 X# Z& Y
9 o( A; H* Y k$ k
Example: AfxGetMainWindow()->SendMessage(WM_CLOSE), [5 B1 a N* ^! y
* \# I( l1 G% V- W- o0 K/ {
还可以创建一个自定义的函数 Terminate Window 6 j) u4 m6 ~$ X1 b3 i# z- d+ ?1 g! s& p; O8 ~! ]1 Z
6 F7 @9 C2 g7 U0 n% i9 X: F" o# m7 J - |$ h) E+ z; A% S1 a 8 c; a- J `4 ] void Terminate Window(LPCSTR pCaption) . k2 r5 c' ^1 J* F$ X" r/ J3 _7 v { 7 j8 o1 G7 [( Q# v* k7 m CWnd *pWnd=Cwnd::FindWindow(NULL,pCaption)- u. m _3 O0 y& K
! U2 b6 x$ ]) ]# n) Y. H0 t+ m
if (pWnd) % w* ?/ D" @0 Y ' n* r8 ?. h p1 ? pWnd ->SendMessage(WM_CLOSE)% Y& N8 \ g1 M( i7 a* O/ }0 h
}9 }, W0 w9 O; p
% a% j- T+ Z! Z1 `% A( Y* @: c 说明: FindWindow函数不是提倡的做法,因为它无法处理标题栏自动改变,比如我们要检测 Notepad是不是已运行而事先不知道Notepad的标题栏,这时FindWindow就无能为力了,可以通过枚举 windows任务列表的办法来实现。在机械出版社"Windows 95 API开发人员指南"一书有比较详细的介绍,这里就不再多说乐。# d# Q* a& O* r( J* `3 Z. C
. S4 }3 x# P& L0 r, C# e/ U (27) 如何创建和使用无模式对话框 + t F# p5 \- y' B MFC将模式和无模式对话封装在同一个类中,但是使用无模式对话需要几个对话需要几个额处的步骤。首先,使用资源编辑器建立对话资源并使用ClassWizard创建一个CDialog的派生类。模式和无模式对话的中止是不一样的:模式对话通过调用CDialog : : EndDialog 来中止,无模式对话则是调用CWnd: : DestroyWindow来中止的,函数CDialog : : OnOK和CDialog : : OnCancel调用EndDialog ,所以需要调用DestroyWindow并重置无模式对话的函数。 ; `& [4 }% v. w% N9 ^3 g, h$ k2 o$ V- P* T# U
$ I. E' A4 h; m5 @! i; i* s) m' f
- }1 @- z" J, a6 @0 E. N1 }+ u2 G void CSampleDialog : : OnOK ( )$ s) E+ L2 e A0 h5 m' B5 \' w: r
{. G0 [! W3 {% X9 Y- O
// Retrieve and validate dialog data .7 Y+ [4 _. ^6 w$ K" w+ j
if (! UpdateData (TRUE) )* @* |+ M$ Y ^) c
{ % S( F5 e# _ j! Y% R& t1 Y // the UpdateData rountine : @/ x. v8 I. T5 d1 c' Y will set focus to correct item TRACEO (" UpdateData failed during dialog termination ./n") * s' ?9 s9 }! v, C% U0 t return 5 n( M0 Y8 p k* x2 j1 a } : P& A6 ^( }" U# t0 v; q6 L ' A3 J* p& Q& Z! V2 W0 u9 L& Q //Call DestroyWindow instead of EndDialog . 9 p# W' a4 [1 E DestroyWindow ( )* e" @3 w& T; s! f% N8 @- ?
} * g, u" c- q1 J) n( D& ? % K6 B- p( n# S- ]2 ` void CSampleDialog : : OnCancel ( ) 6 L# E) e1 l. e7 C6 a8 \ { ! v; p; l: [7 ^7 n4 r //Call DestroyWindow instead of EndDialog . 2 j4 R: w5 ]1 V) f( N DestroyWindow ( ) * j+ q2 E0 F" v5 v, K }8 W8 t" |/ H7 T& T7 `' H
. X2 R; x5 |( l' ?9 q3 D
其次,需要正确删除表示对话的C++对象。对于模式对来说,这很容易,需要创建函数返回后即可删除C++对象;无模式对话不是同步的,创建函数调用后立即返回,因而用户不知道何时删除C++对象。撤销窗口时工作框调用CWnd : : PostNcDestroy,可以重置该函数并执行清除操作,诸如删除this指针。 * P9 o1 O, \3 P |! g8 x+ w$ L. V a3 o. F1 I2 J& ~
3 N' A V: G- t. a4 _1 z
: |' b7 a; U# f' w$ Q3 a. n. Z T! p
void CSampleDialog : : PostNcDestroy ( )0 n2 i; B$ U/ p" n% H7 {
{ 2 t& G% a8 ?( E, {6 ~4 y) E) c // Declete the C++ object that represents this dialog. % j- C$ ^- U, r! F! ]/ D- V delete this 0 [7 a2 ]" l" i8 x7 {6 ?1 l# X& z7 i! [: V1 w
最后,要创建无模式对话。可以调用CDialog : : DoModal创建一个模式对放,要创建一个无模式对话则要调用CDialog: : Create。下面的例子说明 了应用程序是如何创建无模式对话的: 象;无模式对话不是同步的,创建函数调用后立即返回,1 S' X! L8 D! a7 P2 h6 X( r9 ^7 `0 [2 O
6 K; v" q0 b6 X5 K( V
* k" z4 H7 U4 r( k) g! \
. @, F2 [: _8 ^7 i# j
( R$ Z0 f) X* _. Y8 O1 a% ~
void CMainFrame : : OnSampleDialog ( ) 8 `; x& I4 G. B) @: x { 7 G: ^+ H! N1 \+ X //Allocate a modeless dialog object .+ j; g( ^3 Z4 P) [0 }# B: ^
CSampleDilog * pDialog =new CSampleDialog, Y1 L' b( n+ u5 w, z& o p* Q
ASSERT_VALID (pDialog) Destroy ( )4 i2 ?1 \) }2 c) L, r5 O
6 I+ A6 a& {& y" u. f //Create the modeless dialog . represents this dialog.( M7 J$ A7 O. F! K
BOOL bResult = pDialog —> Creste (IDD_IDALOG)& x, _/ u) T0 G. [0 v; V9 A( u
ASSERT (bResult ) / ~' @6 C* _8 J& `6 D- P8 p }: N' q/ L% o; \ A
. k7 E& A3 g* p ]; F
(28) 如何防止主框窗口在其说明中显示活动的文档名 t- [. E7 \3 v* c0 X; L B 创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位,如果不希望在说明中自动添加文档名, 必须禁止该风格位, 可以使用ClassWizard重置 & h P' S! V/ R) q: A# F5 T6 P 8 ~ _, N" O! _7 J4 C, t( S9 u) a5 X7 j) K0 e
; A3 s/ y: ^' L5 @5 F" D4 X0 A/ e0 [- T9 z# {% W3 W
CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格。 3 W1 q4 a: `1 w0 s* U2 o BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs) ; k6 M, B) F1 [9 b8 ] { ' a- |7 F6 o) ]( j //Turn off FWS_ADDTOTITLE in main frame .; x% P" T% f' S$ O
cs.styel & = ~FWS_ADDTOTITLE $ W( n4 u& N! c$ Z return CMDIFrameWnd : : PreCreateWindow (cs )6 p" ]; { L6 j8 L
} ) w; w0 w) m; o5 q4 I6 m. Y# S/ u2 i+ |) H5 d4 S