" X. ^) `6 g( S void CSampleView : : OnLButtonDown (UINT nFlags , Cpoint point7 ]9 d' a8 }) F+ a3 C7 }
) % Y3 d9 x& C& v9 [8 K6 e {- q& z0 k( c) z& z8 R
CView : : OnLButtonDow (nFlags , pont ) $ h. v9 }+ {& v8 j; [+ x0 D: d- u- Q0 Q4 t; p- ^( h) j
//Fool frame window into thinking somene clicked . W& t, `4 _- t on , {! N2 |4 f) k its caption bar .* `, F; [' u9 E; l
GetParentFrame ( ) —> PostMessage (; g" l% a5 i' u) X# A* @( \% P
WM_NCLBUTTONDOWN , 8 ?- q2 I( W- j/ Y HTCAPTION , MAKELPARAM (poitn .x , point .y) ) % Q1 L& E7 q9 a! Z' f+ J) L7 `9 Y3 d
}3 A/ N$ N" ]9 e: Q: B' M. Q
, y# M; t. u! Z( A' S; P% N' h
* t1 B9 K( [6 Q! p; ~# v 该技术也适用于对话框和基于对的应用程序,只是不必调用5 k2 W( a$ Q) Z) i; Q& f* _6 U: S2 ? j% L
- a' i8 x' }' L! k+ ]
- R# x0 t& O% i" C
# }" V& z4 e$ E3 Y$ w5 ^2 o( Z1 O0 h7 O7 Y% ?- @. l$ g
CWnd: :GetParentFrame 。1 K. o# h+ I3 b- U
void CSampleDialog : : OnLbuttonDown (UINT nFlags, Cpoint point )7 H" U8 g0 m# ~" C: U. U
{ + k3 H+ G2 L$ l7 Z- g9 z+ X Cdialog : : OnLButtonDow (nFlags, goint ) + f& l4 h8 C( X# M //Fool dialog into thinking simeone clicked on its( Z" i- R" [6 f) c
caption bar .$ y+ t- m7 I0 @, X0 u1 M0 }
PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARM (point.x0 S- H, J$ ?$ n1 L9 F
, point. y: X( r4 V" }. k+ y5 U% A& `& K
) ) 4 q0 i) T2 @& H- I! K1 h } ; \, w `9 D6 w: K& W* b & Y2 U: N0 D6 E0 B ^ (18) 如何改变视窗的背景颜色6 W, w* y+ x& f% X
Windows向窗口发送一个WM_ERASEBKGND消息通知该窗口擦除背景,可以使用ClassWizard重载该消息的缺省处理程序来擦除背景(实际是画),并返回TRUE以防止Windows擦除窗口。3 X0 x( {# ?8 W
: F+ p2 ]4 G" _- R* t0 Y; M, j& Q
5 H! y+ S9 L' r; L$ G 4 o& Z: G+ h1 |2 {9 v& B& o; K# w q! {% _ / X' k) O% |' n8 | //Paint area that needs to be erased. 4 y1 a" x' Z% M* ~5 `2 F BOOL CSampleView : : OnEraseBkgnd (CDC* pDC), Z+ o, a' r6 o
{) }. Y) z4 @5 y3 C
// Create a pruple brush. 5 i; ~8 |3 u3 p5 \( O4 V* _ W CBrush Brush (RGB (128 , 0 , 128) )% i( \* f/ Q6 E. t# n
' U5 f1 s- \; k // Select the brush into the device context . 5 K1 [0 s' w3 `+ g8 v% H CBrush* pOldBrush = pDC—>SelcetObject (&brush)6 a' G9 k* N, \# j7 K
: n5 \* Q8 m* k/ i t
// Get the area that needs to be erased .- U! ]+ X# K+ g5 r6 A
CRect reClip 8 p' c9 B8 U: T. F1 V$ ] pDC—>GetCilpBox (&rcClip)1 ]4 H) b; N# C' T6 C
//Paint the area. , [4 W. m" E* e3 I8 u4 q pDC—> PatBlt (rcClip.left , rcClip.top , rcClip.Width ( ) , rcClip.Height( ) , PATCOPY ); r) q; O7 p1 x/ b4 W4 D- Z
2 S3 m" G) c, F: {. @ //Unselect brush out of device context . 2 z" |3 s U, d6 T1 w pDC—>SelectObject (pOldBrush ) 9 L# Y4 ]6 u8 q$ `5 s1 K2 ?% g& M+ [: j+ [+ X
// Return nonzero to half fruther processing . @8 I9 K3 c2 i6 p) [) U return TRUE* u: o- s3 }# L* @0 w R% B* h- _$ H
} 4 I# U' `: w9 B$ W" i& k+ _- S% V! [- ~
19) 如何改变窗口标题! T9 m0 f& j. ^9 J* @/ d
调用CWnd : : SetWindowText可以改变任何窗口(包括控件)的标题。6 u9 {0 s) Q5 o# U! [
" y) l8 v U- @8 @
! d2 E" ~, f9 @6 Z4 N( {0 c) _ @+ P6 `/ z/ X* C
, U- X9 u& E# k7 z& L0 p6 n
//Set title for application's main frame window . 5 v% w$ A% K j/ s" l7 f0 n0 D0 a AfxGetMainWnd ( ) —> SetWindowText (_T("Application title") )8 P6 V9 [+ d Q2 b
( t0 E. F7 ?2 t) F, [8 u- p8 r
//Set title for View's MDI child frame window .- ] ^, X# A% e) ]3 \
GetParentFrame ( ) —> SetWindowText ("_T ("MDI Child Frame new title") ( V# q% Y& {2 m+ e$ O* Z )) f5 M; k' H- H6 ]# z Y3 `/ c
( P& Y- ]( c! l- W- |
//Set title for dialog's push button control.; A6 [& {$ E% X" b1 X- ~
GetDigitem (IDC_BUTTON) —> SetWindowText (_T ("Button new title ") )+ B' D& \ J2 v q4 m4 J
1 ~' s/ A* ?2 k/ P
+ }( R+ X# _" Y7 w1 P5 X, Z) a
如果需要经常修改窗口的标题(注:控件也是窗口),应该考虑使用半文档化的函数AfxSetWindowText。该函数在AFXPRIV.H中说明,在WINUTIL.CPP中实现,在联机帮助中找不到它,它在AFXPRIV.H中半文档化, 在以后发行的MFC中将文档化。) Y! d9 G$ m) H. v( U6 Z0 B
AfxSetWindowText的实现如下:7 o* H# b$ k5 U% \- m2 I( V
3 U' \+ L3 \6 t A 3 o. b% B7 B o ! f1 j& N+ y: |+ ^6 j 6 X0 F, l: y5 Y2 {0 x- U9 {! d voik AFXAPI AfxSetWindowText (HWND hWndCtrl , LPCTSTR IpszNew ) , c9 q" o0 ~# y. f- w4 U {$ ^! T W+ z0 h4 P# a2 ]
itn nNewLen= Istrlen (Ipaznew) 6 ^3 e8 H" t& f+ ^ TCHAR szOld [256] ' A: G4 N0 m2 |+ g //fast check to see if text really changes (reduces+ f$ T& f& ?6 ~0 Y+ w
flash in the $ A `6 Z- R2 \: q# B controls ) + l6 f" `0 W6 Q- ^+ d+ u* R" w% X if (nNewLen >_contof (szOld)1 t3 W5 j/ [& t5 k Q7 ~" j
|| : : GetWindowText (hWndCrtl, szOld , _countof (szOld) !=nNewLen8 Z3 @, ?/ M& W& F8 ^ n# P! J
|| Istrcmp (szOld , IpszNew)! = 04 K: M& W4 d9 H) b; ?& w
{ 7 v: H C' K6 W6 b* i$ w E A //change it: j5 J* e- a) \% U/ c% K1 X1 k/ D
: : SetWindowText(hWndCtrl , IpszNew ) 2 T/ ~& Z9 i! ] X" i$ I3 P } ' h% @2 P2 @* G" D1 D } / @/ {' x+ Z7 T# l: i' I ; M9 U+ D/ o' G! L5 E* \ (20) 如何防止主框窗口在其说明中显示活动的文档名2 A0 r" \+ O- y
创建主框窗口和MDI子窗口进通常具有FWS_ADDTOTITLE风格位,如果不希望在说明中自动添加文档名, 必须禁止该风格位, 可以使用ClassWizard重置 % U! _5 o) s7 f3 O( A. i' Q9 ?1 { CWnd: : PreCreateWindow并关闭FWS_ADDTOTITLE风格。/ q* x4 y! ^7 d: T4 b) S
: o8 e* A, t4 _0 |
[2 r$ M) v% i0 j
5 w$ ~- O0 I% p6 K; N
( q, m' d F! C; \1 m0 z6 X+ ~ BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs) Q k) } W9 t6 K2 h { * `6 L+ e7 ^ \5 ^: {2 d g+ ^ //Turn off FWS_ADDTOTITLE in main frame .% J1 G, `- Q D {
cs.styel & = ~FWS_ADDTOTITLE $ r4 }. R8 b1 |3 K2 D' u
return CMDIFrameWnd : : PreCreateWindow (cs )4 i' L) n+ K5 Q" x6 z% o9 ~
}( @7 X: d6 I, `6 R; l' i" W
6 q) [, b6 d( N2 }3 d
, g3 u( R5 D' p8 _2 o' |+ x
关闭MDI子窗口的FWS _ADDTOTITLE风格将创建一个具有空标题的窗口,可以调用CWnd: : SetWindowText来设置标题。记住自己设置标题时要遵循接口风格指南。7 E; I" p& \% m9 b' C2 \
j& Q+ J: j' S& r& v
(21) 如何获取有关窗口正在处理的当前消息的信息2 G I E* M* O4 {' ~( t0 P; x
调用CWnd: : GetCurrentMessage可以获取一个MSG指针。例如,可以使用ClassWizard将几个菜单项处理程序映射到一个函数中,然后调用GetCurrentMessage来确定所选中的菜单项。6 ?0 l- j8 l/ Q6 I. d, C
; F& l+ a$ l7 W: a: x' u0 @- @6 @. X- O9 F' ^
. d, `* G9 I6 S, o9 l. |
/ D0 |4 p. Z8 S& `/ `: S4 G
viod CMainFrame : : OnCommmonMenuHandler ( ) ' q6 ]% g6 Y8 B { 8 E) ~3 D1 ^# `9 R8 d' v //Display selected menu item in debug window .3 `! r' |' \5 V
TRACE ("Menu item %u was selected . /n" , % t6 q/ x2 I1 B- l1 { ( U% x/ D1 f+ V- { (22) 如何在代码中获取工具条和状态条的指针 % ?: U- g2 }/ j% M L h 缺省时, 工作框创建状态条和工具条时将它们作为主框窗口的子窗口,状态条有一个AFX_IDW_STATUS_BAR标识符,工具条有一个AFX_IDW_TOOLBAR标识符,下例说明了如何通过一起调用CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口的指针: : r8 R3 C1 c$ ?0 |0 m0 c8 Q) J+ G# D* K
" `0 T1 U3 ^* A1 o m& w
% I- r8 ?* W' j i6 G5 C5 d' ]" f8 b$ c
//Get pointer to status bar .' B, G; d" p0 t' i0 u: d
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( ) + j. ^3 q6 o/ _7 J1 P# p& U —> GetDescendantWindow(AFX_IDW_STUTUS_BAR)+ p& v1 P" Y- f
& @9 z- R) \+ R0 y; K P$ X //Get pointer to toolbar . 7 j G5 p, }1 a- n CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )+ j- P4 ~1 j, \, B! d% U7 o1 F
—> GetDescendantWindow(AFX_IDW_TOOLBAR)- k* Z" l v4 V) H& p, t
% e0 P/ G0 R! K0 n; z0 K$ I3 |
(23) 如何使能和禁止工具条的工具提示 ; E% U# _. c ]( P 如果设置了CBRS_TOOLTIPS风格位,工具条将显示工具提示,要使能或者禁止工具提示,需要设置或者清除该风格位。下例通过调用CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立一个完成此功能的成员函数:! Y# [1 p7 h+ O4 F5 T# }1 i- H
6 @) s. E; R0 b" S- @, C q void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )( w; W9 h5 N; @1 W5 Z, J6 N, x
{ 9 u. L& {3 o& {- i# c7 P( p ASSERT_VALID (m_wndToolBar). b5 m* ]# p; x+ |
9 c( j1 X L( ^+ w& h/ r9 G
DWORD dwStyle = m _wndToolBar.GetBarStyle ( )/ D* q8 ~4 I8 ~' _. O
`: p. _) {/ n9 d
if (bDisplayTips) dwStyle |=CBRS_TOOLTIPS * m( G8 X( s& x6 x# o! M 0 L \) W$ t4 R, r% l0 ` else 6 Z( Q2 _8 Z# G) V% o dwStyle & = ~CBRS_TOOLTIPS 5 j* w3 o) b5 p3 \ v 3 d3 B% ?# G* K8 r m_wndToolBar.SetBarStyle (dwStyle ) ' n% X# [( H2 O }1 L* h$ [' N; d& g- p1 }+ r& Y0 {
3 d3 K8 C/ Z! O) p. J. ^" X! P$ l1 {(24) 如何创建一个不规则形状的窗口 P6 q8 I4 l7 E! C5 m7 L
可以使用新的SDK函数SetWindowRgn。该函数将绘画和鼠标消息限定在窗口的一个指定的区域,实际上使窗口成为指定的不规则形状。 使用AppWizard创建一个基于对的应用程序并使用资源编辑器从主对话资源中删除所在的缺省控件、标题以及边界。' i( N, l U9 ^' q9 P
给对话类增加一个CRgn数据成员,以后要使用该数据成员建立窗口区域。 - x9 E6 Y7 K$ g" i% G7 o7 i- w' j. p. _! O$ ~
+ h2 U$ T9 t" y& E4 Q* q; d& R
; Y0 K. Y) U7 [9 W( |3 A, Z1 U! }# N8 h8 u4 ^% S8 W4 y# d+ I
Class CRoundDlg : public CDialog: { W/ i+ u$ g5 x! c" [: t1 c
{9 x& r" \* m1 H; L4 K
…: W1 [6 Y( v$ A) b3 q0 F. u! ?
private : e0 }' Y& s2 E9 q9 y [+ P& {* s
Crgn m_rgn : // window region , P9 D0 F6 C0 }" W s$ p …1 [' e( f! J4 g" P+ W0 O
}% ]' Q5 \# t' u* {0 L
修改OnInitDialog函数建立一个椭圆区域并调用SetWindowRgn将该区域分配给窗口: 7 u. f: H; j6 G- q BOOL CRoundDlg : : OnInitDialog ( )) }3 |/ O4 Z; t1 Q
{2 J4 y$ O9 U+ G
CDialog : : OnInitDialog ( ) * F# p) M, s7 s , l; N; C7 ^* v! \- Y3 C7 ` //Get size of dialog . j9 g# c0 `$ a+ c" h
CRect rcDialog" Q8 d& Y! f8 a# p7 G3 |. g$ j
GetClientRect (rcDialog )7 f! }$ h+ n1 T9 P
8 m- h% z3 O% H7 J- p8 ^
// Create region and assign to window .8 }! U: \* g0 J
m_rgn . CreateEllipticRgn (0 , 0 , rcDialog.Width( ) , rcDialog.Height ( ) )! Q6 L$ I6 j8 Q! v2 X" P
SetWindowRgn (GetSafeHwnd ( ) , (HRGN) m_ rgn ,TRUE ): V2 b I6 D# I. w# \5 z
( \6 q& ?; [* O; ~. x
return TRUE # B" l* K: m3 S# O, \% M g: S }; u7 M( [6 y6 w: K( N
! V) C* H2 S" c9 m; @6 T
通过建立区域和调用SetWindowRgn,已经建立一个不规则形状的窗口,下面的例子程序是修改OnPaint函数使窗口形状看起来象一个球形体。, l) @5 K# z M
5 ]' r5 _# S8 K1 O$ S' f" Z
: {0 V3 E! Z" _- X2 h2 p1 a$ j
$ N4 }7 l/ J+ g @5 G9 T. w
; X4 L! k; M2 ~, T
voik CRoundDlg : : OnPaint ( ) 9 X; {$ a6 t5 m% W { $ A! I9 y) A0 T; N3 S1 u( G CPaintDC de (this) // device context for painting1 H" v1 E' _8 `6 {% U
.( e2 T3 V% J. n8 f5 m1 K# e! @
//draw ellipse with out any border , P3 o& U% c! V# M dc. SelecStockObject (NULL_PEN) 2 `5 y9 Y1 s8 R //get the RGB colour components of the sphere color6 n: P/ \1 R/ Y
COLORREF color= RGB( 0 , 0 , 255) 1 l8 }6 u, N8 W$ x& u BYTE byRed =GetRValue (color) - v: L& J( p) r( J% x1 [6 x BYTE byGreen = GetGValue (color)( g# P% v5 G- e( F. r b1 Z
BYTE byBlue = GetBValue (color) $ r$ \- X6 |% l/ {9 Q% B* k* g u! @5 e
// get the size of the view window , P- G5 |4 }( n, e6 s% @$ k Crect rect! S6 v7 {" l1 y! ?& t( W1 n5 C+ S
GetClientRect (rect)4 k" w* _# ^9 K4 ? I6 i
4 Y: `+ A6 `) |# v7 d
// get minimun number of units . m. z; E ]+ r% R int nUnits =min (rect.right , rect.bottom ) & D' r; U t' D - {0 ]( H: z8 T7 c6 Z6 ] //calculate he horiaontal and vertical step size ! C" x% G, y- E) F! J! O float fltStepHorz = (float) rect.right /nUnits6 Y& T0 i0 z: y1 _$ v9 H* B
float fltStepVert = (float) rect.bottom /nUnits! j1 \& L& x- M2 O
4 e- |8 T8 n2 ?# U0 p" G2 s& F+ g* G; t
int nEllipse = nUnits/3 // calculate how many to0 h B7 Z; G( d( i% n. B
draw5 s1 E7 H% F5 A/ S
int nIndex 3 o. Y) U6 F& w // current ellipse that is being draw9 w9 }1 ~9 z- J( }2 ]( j
{6 z/ M0 T" F5 u
CBrush brush 9 P3 e" W6 _ L // bursh used for ellipse fill color# R2 F% Z1 u# H9 A: g" r
CBrush *pBrushOld // previous ; ?" |* }% ~+ L& ~; Y Q brush that was selected into dc 8 D5 l8 b; J1 I$ _( V. ` //draw ellipse , gradually moving towards upper-right , s. _7 m$ o6 f: ` corner ' V; l8 k$ z& l, [ for (nIndex = 0 nIndes < + nEllipse nIndes++) . F% J8 _+ W' j7 h4 z: j { 3 a2 e3 v& {. F8 b" m) D- } //creat solid brush; M: ]( w) ` m0 g/ P: s" w
brush . CreatSolidBrush (RGB ( ( (nIndex*byRed ) /nEllipse ). R2 M1 S* z6 f! I8 }
( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue); i8 R5 c5 m" L# q
/nEllipse ) ) )) E; Z, m+ |: ^+ V4 y
% e8 w1 Q! A, C //select brush into dc3 e: k* K1 S, T
pBrushOld= dc .SelectObject (&brhsh) # p; s8 e" b2 W# X7 E% _ + r% m7 O: l6 q //draw ellipse * A9 a. k6 }# R. K dc .Ellipse ( (int) fltStepHorz * 2, (int) fltStepVert * nIndex , 3 ~; U- H5 u. w0 y4 N: E rect. right -( (int) fltStepHorz * nIndex )+ 1, 2 Q+ F9 V- z7 P) O/ C$ y rect . bottom -( (int) fltStepVert * (nIndex *2) ) +1)) d( C9 u$ r/ G
1 g6 Q X' h5 S
//delete the brush * f4 J `. F; z/ G/ J, Q' | brush.DelecteObject ( ) # o( ]9 x9 h& [" U. S1 X: v }1 a$ [' }, R% Y+ ?$ g
}8 e+ l) ^: d: F* F# q' M' e# N
6 l# l/ r$ ~1 s4 v
最后,处理WM_NCHITTEST消息,使当击打窗口的任何位置时能移动窗口。 # {# Z- l5 d6 }9 Y- p1 a8 ` s x0 L, W3 a. D# u7 F& Q7 V# I) J
: D. I* m/ W, D* m: g$ V5 G1 g- Y* S
: Z( [ f9 s+ c/ j6 g5 K& f UINT CRoundDlg : : OnNchitTest (Cpoint point ) + W% }, b. G* q/ K) a" H- _ { 2 N! Q. |( K, K' U8 X/ I6 u8 M //Let user move window by clickign anywhere on thewindow . ( `1 H; h& O3 F' D UINT nHitTest = CDialog : : OnNcHitTest (point)6 P4 `1 g, R% ~; k% y, O
rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest 4 F# F8 Y! Y7 c: @+ f! U9 P, i+ l 5 K. B2 P) @" ~ } Y$ U1 C2 @- v, H& r
9 K) H+ q; a5 b4 X$ h1 r' T8 Q" D
(25) 如何获取应用程序的 实例句柄? 0 w3 c# r% Q, b3 Z 应用程序的实例句柄保存在CWinApp m_hInstance 中,可以这么调用AfxGetInstancdHandle获得句柄.: B" T& C) f* g7 u6 i
% E( i# {+ n# f4 N
9 y" S5 e9 Q8 @+ Y1 e' c8 }. K. j5 M7 m
, o) o. N, b3 e" }- u* p
Example: HANDLE hInstance=AfxGetInstanceHandle()4 _ w% g p$ y, R- _" L, `9 s* s
+ ?9 y- ]0 Y, p9 t# V) @$ y: M9 r5 q' N
(26) 如何编程结束应用程序?0 R5 a9 M9 n/ d, B7 q o
这是个很简单又是编程中经常要遇到的问题.. o" |) N# u8 [' V) O
向窗口发送 WM_CLOSE消息,调用 CWnd::OnClose成员函数.允许对用户提示是否保存修改过的数据.; o% S# y" N, @% ~) ?
3 x' \% ]& ^, d, f
[被屏蔽广告] " l8 N+ K+ u/ ^8 E r& ~0 [4 F O# D v) p" L) D
系列文章:VC实用小知识总结(一)/ \; H$ O8 f3 x1 a( d) k9 B% w( @
0 q0 o+ e6 H' y8 M0 `/ `1 l) ? " k) I$ w1 u. F! T* v# G9 G r0 H k9 g! K) \
0 {6 K, z0 q) d% \: Y. i/ `
Example: AfxGetMainWindow()->SendMessage(WM_CLOSE) # q8 c b3 t% @8 O+ O9 {; F 0 z$ c! G" l% l7 K8 n 还可以创建一个自定义的函数 Terminate Window7 {; j8 o: `% ?9 ]+ T
0 n6 c+ z/ {2 {5 V# u& J- B 3 @& U! ~* W& U. h2 u3 p 8 Z- L( S5 a6 r, t# j; A9 Y- M2 [6 G7 J. J! ^
void Terminate Window(LPCSTR pCaption)4 J: _1 h' X1 f9 E& E2 K7 w9 j
{ : ?2 p/ d9 o5 U CWnd *pWnd=Cwnd::FindWindow(NULL,pCaption) 5 \7 C: M, V1 b# y: @$ U( H, Y8 k; T( S) {. i8 a
if (pWnd)5 B2 g0 G! A3 Q+ u
s6 f7 B1 C. }6 D" o pWnd ->SendMessage(WM_CLOSE) + t0 s" l/ e: x3 r } ( o; Q5 c: t/ K' `# b) Z Q . ^% D* Z6 x0 F' K$ _# n, _, i; p- h 说明: FindWindow函数不是提倡的做法,因为它无法处理标题栏自动改变,比如我们要检测 Notepad是不是已运行而事先不知道Notepad的标题栏,这时FindWindow就无能为力了,可以通过枚举 windows任务列表的办法来实现。在机械出版社"Windows 95 API开发人员指南"一书有比较详细的介绍,这里就不再多说乐。; U" l' t2 G5 c' \3 R& Y! t4 t
- W5 ~, x! l2 R Z; \ \/ Y7 m1 X 关闭MDI子窗口的FWS _ADDTOTITLE风格将创建一个具有空标题的窗口,可以调用CWnd: : SetWindowText来设置标题。记住自己设置标题时要遵循接口风格指南0 ~4 @: H! x m# q# H4 p; w2 G5 `
; \& t3 ?% p X(29) 如何在代码中获取工具条和状态条的指针( p9 |) p" g& x) }; c! e @, R4 k
缺省时, 工作框创建状态条和工具条时将它们作为主框窗口的子窗口,状态条有一个AFX_IDW_STATUS_BAR标识符,工具条有一个AFX_IDW_TOOLBAR标识符,下例说明了如何通过一起调用CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口的指针: ; ?* }' w' R' r5 {+ r! D- h7 p+ p+ Z
- X* i. y2 a, b' G" J
" b" l- R5 ]! B! h; R; E 3 {1 j4 z7 g* t4 b7 Y' z' x //Get pointer to status bar . . P' [; F& a7 h CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )0 t4 ^8 S$ H3 X& @, r! q
—> GetDescendantWindow(AFX_IDW_STUTUS_BAR)# a& n+ E9 a1 Z, K8 F
5 F- {9 }" R! ~ y
//Get pointer to toolbar ./ N7 o, \* p1 |+ O k2 c: I7 }
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )$ }1 t2 E" |% B' C2 ~: X
—> GetDescendantWindow(AFX_IDW_TOOLBAR)8 _2 ?0 G0 B; ^, S8 U0 h W( c- u
0 L+ ?. Z: ~7 S( E7 `
(30) 怎样加载其他的应用程序? / t: h k5 s4 ~2 T, d; S 三个SDK函数 winexec, shellexecute,createprocess可以使用。 & Z5 E2 h3 X- n) ` WinExec最简单,两个参数,前一个指定路径,后一个指定显示方式.后一个参数值得说一下,比如泥用 SW_SHOWMAXMIZED方式去加载一个无最大化按钮的程序,就是Neterm,calc等等,就不会出现正常的窗体,但是已经被加到任务列表里了。 9 Q" V7 \7 f( J! u0 _9 O4 A" [6 \8 e" K1 v8 w+ ]
ShellExecute较 WinExex灵活一点,可以指定工作目录,下面的Example就是直接打开 c:/temp/1.txt,而不用加载与 txt文件关联的应用程序,很多安装程序完成后都会打开一个窗口,来显示Readme or Faq,我猜就是这么作的啦. 6 z9 a) ^# j$ d$ I ( n0 r. T+ C0 \ " ~; R& P1 ~: \) f - Z3 c. e0 A. e$ N) m 3 P) u' |" C9 E0 M& o ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c://temp"),SW_SHOWMAXMIZED) . [7 z1 k. E: q* {9 @ ) L6 i* T- H& K r8 ^2 I CreateProcess最复杂,一共有十个参数,不过大部分都可以用NULL代替,它可以指定进程的安全属性,继承信息,类的优先级等等.来看个很简单的Example: 1 k) E# x1 J4 d0 \ 1 C2 K0 @7 X" z8 q+ j, s' f. u, f+ V- T1 U
( Q1 j5 j, X. O: k* H) _
/ C1 [: p# N1 n) ]3 u
STARTUPINFO stinfo ( `$ v. i/ a( s; Q1 w //启动窗口的信息 % C7 x7 S3 B% D# | PROCESSINFO procinfo //进程的信息 4 y/ }# p2 u' M% }- s' p8 K, ~$ i- P; ?3 L; W
CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE, / p. X' ~ |5 w/ M$ {2 \% g, K$ Y' m7 I NORMAL_PRIORITY_+ \" S6 _6 ?4 Q. i2 z3 K
( H3 C) i% E; x: l p! s
CLASS,NULL,NULL, &stinfo,&procinfo)) u" D# ?' [' ^& F0 O
" H( w& y/ R" b, `% O( b
(31) 如何在代码中获取工具条和状态条的指针( P# d% \, u5 G$ d1 {
缺省时, 工作框创建状态条和工具条时将它们作为主框窗口的子窗口,状态条有一个AFX_IDW_STATUS_BAR标识符,工具条有一个AFX_IDW_TOOLBAR标识符,下例说明了如何通过一起调用CWnd: : GetDescendantWindow和AfxGetMainWnd来获取这些子窗口的指针: . W+ n+ |0 {3 o6 L: | & x5 Q6 U& ^7 N3 L- M5 ], |6 r5 n( I3 F8 }& V/ N1 F. p# N* d
: q- \# K3 @& v! k* Q( D# @
# W8 c5 F: S# j6 L! d7 {& _ //Get pointer to status bar ./ n- _9 |8 T2 Y. p% n& D
CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( ) * O& ~% L. @1 |+ V1 J8 Q —> GetDescendantWindow(AFX_IDW_STUTUS_BAR)3 a, m, R2 n1 t% j3 \0 J
' ?, i$ R- ~0 V) ]) F- e; n& T; ^
(32) 如何使能和禁止工具条的工具提示 , l6 l( K% m' Y/ f( T 如果设置了CBRS_TOOLTIPS风格位,工具条将显示工具提示,要使能或者禁止工具提示,需要设置或者清除该风格位。下例通过调用CControlBar : : GetBarStyle和CControlBar : : SetBarStyle建立一个完成此功能的成员函数: 6 N/ [7 r5 i6 x$ |& c1 b . c; I* V" w& @" Z; u1 J 5 s8 b1 ^7 C" c2 m) ?0 \) v9 Q- l p. Q/ @( v
; X7 u$ g9 [' W2 e9 x4 r+ F void CMainFrame : : EnableToolTips ( BOOL bDisplayTips )5 E" @: J! ~) E( M5 T8 t3 j
{: ?9 E; i, x+ L6 g) }0 [& A( }
ASSERT_VALID (m_wndToolBar) 5 z( A: ?6 ^- E; \2 v0 W) U$ @+ X8 B2 p3 d- ^) v% I) S8 X
DWORD dwStyle = m _wndToolBar.GetBarStyle ( ) {6 ^6 h1 Z9 ~" n4 T+ J" s$ k$ w0 ^+ Z2 o; F$ \
if (bDisplayTips) dwStyle |=CBRS_TOOLTIPS2 \9 u4 {4 R' X% [0 z7 ~- w
: b7 O6 m0 t5 `1 e( c8 L
else 4 p( b, J) b, H4 B dwStyle & = ~CBRS_TOOLTIPS 9 z# `# | ?0 c, C) v9 d5 {) v( ^( N g# n
m_wndToolBar.SetBarStyle (dwStyle ); I6 z7 e, u7 j/ e l6 n
}6 b e0 Q, _& H9 N& j+ W3 u3 X( Z
' p; s8 [2 t1 } //Get pointer to toolbar .0 ]& ~* y1 g7 U4 {
CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )- m1 ^0 ~4 ~# O. J8 x; C1 n
—> GetDescendantWindow(AFX_IDW_TOOLBAR) % k! @/ b) M* S$ x% q6 p! T. E, f1 s/ @
(33) 如何设置工具条标题 5 S: c% z; ^: H7 e3 ]) C 工具条是一个窗口,所以可以在调用CWnd : : SetWindowText来设置标题,例子如下:6 t0 ]4 y1 ~, I4 T/ J+ X8 k5 ?
& }% `, ?" h% J& Z1 n
, E8 u( D* r( |. R% N! T
8 q, \7 m& M. H$ S4 A0 h R) o: r& s, y8 T& s
int CMainFrame : : OnCreate (LPCREATESTRUCT lpCreateStruct ) r& n% ~1 j6 E+ o. R { $ D7 g1 h' t' j8 I f @; K …# S. t5 p+ }* O6 h0 Y
// Set the caption of the toolbar . 3 `6 B B" |9 P( z! ^0 f m_wndToolBar.SetWindowText (_T "Standdard") 0 P" N* x- }) M8 \' {4 E3 B/ N. G* U) U4 B! [1 U7 q b* t
(34) 如何使窗口始终在最前方? : J4 r0 x4 v4 T% U J; F- o/ j3 L( j9 Y, T- m
5 p( e' l+ u$ A1 L z6 C q! H9 U2 |( a 1 q- y. _" D- Q. X& c; C8 O BringWindowToTop(Handle); B) Q8 i: O: t1 l6 Q
: I4 h( y( H* T, }7 R 2 W# y) p1 S# R% W1 r0 n SetWindowPos函数,指定窗口的 最顶风格,用WS_EX_TOPMOST扩展窗口的风格 ' f/ H: \9 g/ c0 y4 E3 I, H1 t& s/ S% }1 r' q8 L) q8 H7 Y
2 V+ D" g6 @/ m4 L6 D( O i
) O- F" Y3 r: F2 }* \; S. S
% ~8 F4 C6 F& [9 H Example: 7 c' c1 P2 }7 T void ToggleTopMost( # \1 E: X6 O" q2 V CWnd *pWnd) # d$ m+ j+ w. k9 c$ Q- n' c% d {# e7 o+ ~. \! m' m6 U' m: H# l
ASSERT_VALID(pWnd) 9 [8 f( H' F9 z7 U ) H/ e/ w/ N" D: Y0 \4 [7 c' S pWnd ->SetWindowPos(pWnd-> GetStyle( ) &WS_EX_TOPMOST)? " i j4 g, W# m7 n! Z0 ^; e' Z - \$ U/ s4 ]* z8 w &wndNoTopMOST: &wndTopMost,0,0,0,0,SSP_NOSIZE|WSP_NOMOVE) |" N+ V( y' x% d* S$ i# M, l
}8 j* j9 i3 L Z4 G# E& p
3 u* n# E7 v' O; W! o
(35) 如何在对话框中显示一个位图 9 M1 t+ g; f. I; t" S6 |2 u 这要归功于Win 32先进的静态控件和Microsoft的资源编辑器,在对话框中显示位图是很容易的, 只需将图形控件拖到对话中并选择适当属性即可,用户也可以显示图标、位图以及增强型元文件。 6 L& ?6 `. b+ X* j/ q( b0 ^3 e$ X+ C' _$ I9 v. N2 P- j+ J
(36) 如何改变对话或窗体视窗的背景颜色 + M, I/ }) ~6 E8 K1 w( [ 调用CWinApp : : SetDialogBkColor可以改变所有应用程序的背景颜色。第一个参数指定了背景颜色,第二个参数指定了文本颜色。下例将应用程序对话设置为蓝色背景和黄色文本。 1 e' t3 ~# L' M( l( Y' V4 i2 {; C
$ K. h$ u ~$ a4 z8 Q
( N2 y4 J# r7 ?/ v( s# b1 H# ]0 m! S7 b6 N
BOOL CSampleApp : : InitInstance ( ) 3 z) [7 }. U+ }5 n6 T2 Q- u {7 J6 u. C9 e/ ^$ P8 k, T( p
… & k3 ?6 M8 ? C " P( {2 n" G2 ^- G# U //use blue dialog with yellow text . ( R. F- e# l- h- ?7 |9 ` e- Z SetDialogBkColor (RGB (0, 0, 255 ), RGB ( 255 ,255 , 0 ) ) ! }& V/ V8 {+ q9 F! q' E; y ; A8 i+ X# z. a! c … 4 S4 f/ W3 ?: Q, `4 `$ y) i } ! M9 y8 q6 D" [/ g5 E* _& q' u" W3 a7 O/ Q+ |
需要重画对话(或对话的子控件)时,Windows向对话发送消息WM_CTLCOLOR,通常用户可以让Windows选择绘画背景的刷子,也可重置该消息指定刷子。下例说明了创建一个红色背景对话的步骤。1 o/ N8 W1 l2 {5 B) f& W
5 C9 _% _0 O. ^/ q5 l: q 首先,给对话基类增加一人成员变量3 U. A' n2 z6 G5 P+ ^0 I
" E( @% v3 |0 ?9 Y, F
C* d' @& V$ [$ G$ g$ i" l/ F( J; `3 e; V
; ?+ M- |4 B5 e4 p1 ^
CBursh :class CMyFormView : public CFormView0 Q. A, D3 v s7 C1 v& q; T
{. F; K+ T; n* ~% o
… ( w0 q( N7 q6 D * U. I" r4 X) v; @ private : , B# C+ b R4 y8 N! ` CBrush m_ brush // background brush$ k% [1 ]6 }. f* b- v& B3 I- O
k& A9 {* X9 _$ C' e9 a
… ) b6 t6 i# y2 @) B }8 R; r6 U+ \2 d/ I* [' m
" Z$ x" _8 }% L+ b9 S 其次, 在类的构造函数中将刷子初始化为所需要的背景颜色。 ! M8 t; F& [% z7 G' N 4 o/ c) Y) t. y6 e' u : r7 y+ s& {# b; k y U! Z1 x3 t' z, ? _; @* `
$ p. V8 q* s! W1 f# i, s
CMyFormView : : CMyFormView ( ) , N) Z* i+ ~0 ?( F, D9 h/ b {& y2 l8 X s& k O; a; s4 M
// Initialize background brush .' D4 n( R; r; c. Z
m_brush .CreateSolidBrush (RGB ( 0, 0, 255) ) 8 U* _4 U3 Z2 B6 T } - s" Z+ F& W9 U1 s) i* u) w( O2 D # _0 y, q- d) b" y$ ]; M% G( |- I 最后,使用ClassWizard处理WM_CTLCOLOR消息并返回一个用来绘画对话背景的刷子句柄。注意:由于当重画对话控件时也要调用该函数,所以要检测nCtlColor参量。& k& \ Q/ u$ G/ q
9 e& c: U& m. ^! D; j8 i9 S
' \1 O! T/ V, m4 l9 P# H
" n+ n# g* U8 t$ D
' y) K& |1 e( _) R+ @ HBRUSH CMyFormView : : OnCtlColor (CDC* pDC , CWnd*pWnd , UINT nCtlColor ( M& @" X: }8 O' t ) ) j: A/ y2 W% O7 {: v5 P6 r# A. v$ `6 v9 w4 E+ F% {: Z
{ 3 u% K$ P. D2 J# ?" K$ H$ a, S6 ? // Determine if drawing a dialog box . If we are, return +handle to8 b7 ` }8 z0 w) G o* D
//our own background brush . Otherwise let windows handle it . w. { Y( o" ^( F( O if (nCtlColor = = CTLCOLOR _ DLG ) # k/ i3 X K4 h! _/ w, \ return (HBRUSH) m_brush.GetSafeHandle ( ) * T9 R; P0 }2 k/ i- P4 P return CFormView : : OnCtlColor (pDC, pWnd , nCtlColor/ p5 K# y7 T! Q, k b+ t( Y6 }
) E: ? c8 A) t
} 6 w9 R: }4 O$ l+ v3 r' l6 N1 p' X5 J1 O
(37) 如何获取一个对话控件的指针( }- ]9 B) @$ @$ V: ~! k9 f
有两种方法。其一,调用CWnd: : GetDlgItem,获取一个CWnd*指针调用成员函数。下例调用GetDlgItem,将返回值传给一个CSpinButtonCtrl*以便调用CSpinButtonCtrl : : SetPos 函数: 3 s) }: I0 w( j: l/ n% x; C7 v R; @9 P1 y7 g* h; U+ Y2 q4 q! S4 Z" h! m4 D0 D
( V9 F4 y" O+ D7 j% U6 A0 ^% F* W6 ?8 S) p
BOOL CSampleDialog : : OnInitDialog ( ) % C- L2 |* _" Z5 ` {* I6 [7 E) Q/ A+ o* S
CDialog : : OnInitDialog ( )5 Y/ a0 e0 `$ H; J( k0 X. O
$ `6 o \% T7 j
//Get pointer to spin button .$ r+ }; |6 y; x2 K8 }: @
CSpinButtonCtrl * pSpin - ( CSpinButtonCtrl *) GetDlgItem(IDC_SPIN). Y; M: Z( t4 `5 \, \4 W/ E5 A
ASSERT _ VALID (pSpin) 5 c4 p# J& Q" _* u, T2 U //Set spin button's default position .7 ?) x( A, m, Q; n) u6 [
pSpin —> SetPos (10). g% d& k! ^7 Q, s% K4 J1 C8 M
0 t/ R2 i5 x" K6 ?2 T
return TRUE0 R+ d% h! f9 v9 ^. R) L
}3 M$ O# F9 i" T/ M2 H- d6 L