请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
做过UG二次开发的都知道,在UG里做二次开发的主要界面就是对话框了,UG自己定义了一套二次开发的界面接口,即所谓的UIStyler,对于我们用惯了MFC及Windows的消息机制来说,它那点简单的事件映射,仅有的几个控件(好像连常用的树控件都没有)让我们没有发挥的余地。于是使用MFC对话框代替UG的对话框是每个从MFC进入UG二次开发的人的首先想法。关于怎么在UG中使用MFC对话框已经有文章讲过了,我这里就不再讲了。但MFC对话框的一个很大的缺点就是与UG对框的风格不统一。UG的对话框都具有统一的风格,首先,按钮都具有自己的风格,比如它的四个角是圆角,鼠标移到上面会显示一个Focus的框。然后它的所有对话框都是一级一级弹出来的,比如点击OK按钮,可能会弹出下一个对话框,而上一级对话框会隐藏掉,按Back按钮会重新返回到上一个对话框。再有,一旦有另外一个对话框弹出,当前的对话框都会隐藏或销毁。 下面就给出我的仿UG对话框风格的对话框类CHsPMEDialog,它除了实现了上面的三点UG风格外,由于UG似乎对键盘消息做了截获,如果是普通的MFC对话框,在UG内使用时一些特殊的功能键就无效了,比如TAB键、回车键、ESC都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。 //-----------------------------------------------------------------------------: u4 K( ]. |* n) f! |
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
4 T, j* h0 d1 q5 P+ y" y// 该类来自网络,稍作修改,版权归原作者所有8 u0 i: }: [: E7 t9 m8 E) |( F: E
//-----------------------------------------------------------------------------
e& B) B: X1 X B2 g& `2 aclass CHsPMEButton : public CButton
' ?9 j8 r( s. B/ J* Z, C+ O6 j{( m# K$ s( S0 l* V8 |( Z1 ?+ \
// Construction9 t* u7 ]7 Z+ ^' {5 _" y
public:
0 o3 U# B! j) F' @+ B$ U CHsPMEButton();- b! x5 ?7 C/ o* j
8 d* {" X1 F l8 x. g- L+ |) t% @ // Attributes( l1 [' s1 N) Z& L' ?+ C
public:
' y/ m5 a( Z0 e: Y3 m' R
# I* S& i: n% ]2 o! r+ M; ?9 ? // Operations4 j p8 l) M9 t
public:. Y! O) f/ \/ O# K: M
inline void SetNormalTopColor(COLORREF color)
; b# _( [/ g3 r, T Y# L {5 i& I; ?8 S( p$ Q
m_NormalColorTop = color;
; O3 Z5 ]! M+ \7 b3 L }0 d0 }7 C" O1 ]$ a
inline void SetNormalBottomColor(COLORREF color)
+ h; i3 i: R0 Y: ~% g* ^% P- m( W {: ?3 \- Q/ `% v
m_NormalColorBottom = color;
^. ~7 A$ j l, `) l& r }
. |5 S `0 [0 q! O4 D inline void SetActiveTexTColor(COLORREF color)6 d( I m5 s; m& Z% O( N5 v7 r
{) [; e8 m% q; S( F( i
m_ActiveTextColor = color;
& k/ E2 G/ v- o' q( \7 @ }
8 ^3 l2 l& s- _" W inline void SetNormalTextColor(COLORREF color)
( i+ s4 g1 P2 ~! r {* Z1 V1 h4 }, c- k- P
m_NormalTextColor = color;$ W2 N/ q" ]- m
}" H9 i8 K& y+ @6 Y7 s9 U
inline void SetSelectTextColor(COLORREF color)
0 v" p( v: o3 I9 x% d {; ~+ g7 Q, ^7 Q F( ?
m_SelectTextColor = color;
) u9 T# _6 f. }; F5 @! w- L) w }
1 D% Y$ t0 ?/ L) Z inline void SetFrameColor(COLORREF color)
3 g/ L! g1 O+ {4 t2 u {
& p+ u2 g$ g4 T3 S5 t% ? }) |) T m_FrameColor = color;% e- T7 S4 P; W) _1 s) Y
}& t, |! I' c& ~9 w% n" r
inline void SetActiveColor(COLORREF color)
& E" r4 U- |+ ~ {
& [- O2 f8 u4 V8 D4 w q$ Z m_ActiveColor = color;2 E1 Z; q5 T- P- V: o. f
}/ F* `6 T. |$ a. W6 V3 F* K
// Overrides
6 o* O, J# b7 U1 l) K# p# c // ClassWizard generated virtual function overrides( Q, N/ H5 l6 H7 Z' o- a
//{{AFX_VIRTUAL(CHsPMEButton)
6 ^. f: E( M, P5 |: O |, [protected:, A% z9 z; E% p7 y
virtual void PreSubclassWindow();
+ _$ I, B: E& m9 A5 p. z' Q //}}AFX_VIRTUAL
" K3 q2 v+ h! e
4 ~& R: z+ H/ G8 b) x' ~ // Implementation' `7 l5 y* b: H+ r0 c% e2 J0 u q1 I" m
public:4 X; a2 @6 p7 [" E( ^
virtual ~CHsPMEButton();
# [5 T& J8 G! r8 L) d
5 B; l) \1 Y; e" o // Generated message map functions" j5 O- s3 p) }0 `4 F" K
protected:4 r3 T7 R/ x0 L5 M# e! N" ]
//{{AFX_MSG(CHsPMEButton)
, i# F( g }% _0 } afx_msg void OnMouseMove(UINT nFlags, CPoint point);
- I2 [7 ]1 N9 z) C //}}AFX_MSG( x% c' m& k1 G# y6 k; y- Z
- ~$ o6 s/ ]: W! n# I! |4 j void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
8 U; c6 ^4 r4 b. y9 R* i2 g& \ void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
D# w* u0 w3 ^1 I; E9 s4 p( Q void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );* n( y! c6 ~2 _3 i+ s
LONG OnMouseLeave(WPARAM, LPARAM);, Y0 _, d& S/ G% T
BOOL m_bIsMouseMove; m, I; H9 N, v4 @: s
7 B: y3 b6 K1 K# x6 Q$ { COLORREF m_FrameColor;% h3 x6 f/ x, T% v1 Z1 j- |
COLORREF m_ActiveColor;5 r; v* T$ V5 B: m ^3 p/ F
6 q2 n; c, M4 v
COLORREF m_ActiveTextColor; l+ @$ G% c0 U& s; F
COLORREF m_NormalTextColor;" e- V& a- j0 {! K4 @6 k! U" |
COLORREF m_SelectTextColor;
# Y4 b' X6 R# M" e
0 d0 _4 {" X0 q* Z. j1 [0 i COLORREF m_FrameHeight;) G# R1 l6 Q; l/ D8 L2 S5 N
COLORREF m_FrameShadow;% m- _' B7 e" W G8 J* d
3 W2 H. d5 N: o: C- G7 Z COLORREF m_NormalColorTop;
/ A8 p9 r6 N" w$ a COLORREF m_NormalColorBottom;
! b% r1 w5 w- `! W. B 6 C3 ]3 T' C6 J- a! _7 X
DECLARE_MESSAGE_MAP() f( T2 C6 r" X/ U1 d1 J% E3 R
}; /////////////////////////////////////////////////////////////////////////////
2 m0 R4 _ o" s// CHsPMEButton CHsPMEButton::CHsPMEButton()1 ] y& W' G& o0 D$ E0 W0 k) u
{
( ]8 t, e, {& v4 I I3 K1 W m_bIsMouseMove = 0; m_NormalTextColor = RGB(0, 0, 0);
8 d% p3 }4 e. u m_SelectTextColor = RGB(0, 0, 0);
; n* q4 N4 U# |9 { m_ActiveTextColor = RGB(0, 0, 0); //m_ActiveColor = RGB(250, 180, 80);$ v1 [2 U+ L6 }, v7 A, D. v) Z
m_ActiveColor = RGB(255, 120, 80); m_NormalColorTop = RGB(255, 255, 255); // 从UG对话框中取出的颜色- j5 A* E2 S9 M; t
m_NormalColorBottom = RGB(213, 208, 196); m_FrameColor = RGB(0, 64, 128);
' {* j# e4 v' v& v m_FrameHeight = RGB(230, 230, 230);3 M! v2 _! v" H/ u. t
m_FrameShadow = RGB(128, 128, 128);
$ o: E- R! @% z} CHsPMEButton::~CHsPMEButton(); O9 \( r9 b( L
{% e) \, d8 S$ I& i; `3 C
} % [0 `; u9 [- J
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)5 g5 t- L+ x( x- w8 l
//{{AFX_MSG_MAP(CHsPMEButton)) f0 F+ K2 m' y6 i Z
ON_WM_MOUSEMOVE()6 i' l' C$ j% Z& U1 N E# W
//}}AFX_MSG_MAP
+ C: E1 z6 ^ u6 v+ x3 P ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
; N2 K. V2 b, f. v. tEND_MESSAGE_MAP() /////////////////////////////////////////////////////////////////////////////
0 l- x( m3 n2 S0 K// CHsPMEButton message handlers void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
5 y$ M& Z$ w& w1 s, U0 {% @{, B0 e1 V$ n4 O$ v6 ^
//*
3 a4 Q/ `1 K. n5 X CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
4 R' e7 N; O: \) j- Q: K DWORD nState = lpDrawItemStruct->itemState;
$ s7 {6 }3 N0 d9 Q" u, G DWORD nAction = lpDrawItemStruct->itemAction; # L* B$ E7 k0 _8 C3 W
CRect rc = lpDrawItemStruct->rcItem;
2 ^' t% X: |1 |, o$ H o UINT uStyle = DFCS_BUTTONPUSH; pDC->SetBkMode(TRANSPARENT);! Y4 v% q! F/ V/ a$ [
CString strText;( H( j; d$ w% n8 {& k
GetWindowText(strText); if( nState & ODS_SELECTED )
^/ q, k. o" L) i {
4 k1 e( ^+ ^7 \2 P) m, d m_bIsMouseMove = 0; DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
7 L' Y6 P9 c$ Y& p5 w" H DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); 4 N. d9 \# l; Z y3 j
//pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0)); pDC->SetTextColor(m_SelectTextColor);$ E& _& a" l6 H! }: k0 L% i
}
) M2 I- U- q0 G( _) S l$ O5 O else //Normal' @9 w, _) a" x4 { x% v. Y
{8 c- [% \/ v/ S5 A8 _8 W, B$ \
DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
4 e, B/ T/ p3 b3 ]% ^/ x. o/ C+ ^ DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC); pDC->SetTextColor(m_NormalTextColor);
5 I h5 E& q; ] h } if( m_bIsMouseMove )
6 q3 z, s$ I C {8 V' c. t, l/ v, H3 J
CRect rc2(rc);- q# P u5 Z" n8 Z
rc2.DeflateRect(2, 2, 2, 2); DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),( r& k2 X: `; Q, _* w! c
m_ActiveColor, rc, rc, pDC);
+ a; C" t6 f* ]0 r7 O# n) w6 D DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC); CBrush NullBrush;4 u2 M6 e# T& ?) Q3 ?( k% f
NullBrush.CreateStockObject(NULL_BRUSH);
, t# d0 A, K$ L* E) t8 x4 {1 c% u CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
9 g1 ]# Z. W4 {0 t; D* [+ r / g$ ^1 ]8 A/ u- @7 h
CPen Pen;
- M: f+ L* [$ Q2 G$ }4 g* H Pen.CreatePen(PS_SOLID, 1, m_FrameColor);: K( K8 L' J: C9 I8 h8 s6 B8 Z
CPen* pOldPen = pDC->SelectObject(&Pen);$ J" O L( z& p7 T a
rc.InflateRect(1,1,1,1);0 I3 T! I! W7 E
pDC->RoundRect(rc, CPoint(3, 3));: E" B+ o" n/ F! `
//rc.DeflateRect(1, 1, 1, 1);
+ Y9 R/ w' s& G6 k& d' ~2 O //pDC->Draw3dRect(rc, HeightLight, ShadowLight);8 t' h$ b& r! v/ O- X6 a
4 {4 b9 n1 r: P! t" [7 l
pDC->SelectObject(pOldPen);
, J: L, |/ M$ i- M" P( v: m' b6 c5 }# D pDC->SelectObject(pOldBrush); pDC->SetTextColor(m_ActiveTextColor);
9 }+ [# e& z/ H. P( l; } }
: V0 E P B7 \0 B
& Y6 {. E; o5 K, v3 A pDC->DrawText(strText, strText.GetLength(), " O) e7 i! Y+ n: e' C4 z2 |0 D( h
&lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);3 R, f& \" K3 u9 p; j8 q
//*///2 Y! w( B8 G2 w7 `/ @
} void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
9 F$ y' C0 k- S! ^/ Z! ]+ i6 j6 `{0 k2 g: p( M+ ]4 {( T/ W3 E0 L( Q6 A
// TODO: Add your message handler code here and/or call default+ D3 Q2 C) L+ E# x; Q2 F
if( m_bIsMouseMove == 0 )0 v* Z' A* `2 Z) J; A2 \. |
{( c" E: \3 e7 @4 z& t* g
m_bIsMouseMove = 1;
- F6 [3 e, m: I1 F$ m Invalidate();
- o8 F5 f$ v& G7 j
0 w+ v2 f1 w+ `& S TRACKMOUSEEVENT trackmouseevent;
6 r$ {4 l2 G& D; H trackmouseevent.cbSize = sizeof(trackmouseevent);/ l5 ~9 c( I! W' a* p0 L& }
trackmouseevent.dwFlags = TME_LEAVE;
6 H# V' z( }; z1 \ trackmouseevent.hwndTrack = GetSafeHwnd();* `7 k/ ^# c0 x& ?' T8 {/ h
trackmouseevent.dwHoverTime = HOVER_DEFAULT;2 f z, q: }0 J) P
_TrackMouseEvent(&trackmouseevent);4 k- u% I8 [$ H* _3 t1 O" C8 z
}! }: i+ H4 Q. z9 g5 K4 v
3 g# ?1 M# o2 K& z% p( b2 l: V CButton::OnMouseMove(nFlags, point);
4 M, u) B: F) O4 G& U} LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM) C$ i, T L2 n8 w p+ v \4 ?' [
{
: q. H8 E0 s/ ~ m_bIsMouseMove = 0;7 g1 A8 b; T0 m: U! v6 {
Invalidate(); return 0;
5 \/ v' `7 z" m} void CHsPMEButton::PreSubclassWindow()
' O" a$ o K- z9 d5 v{3 c% E1 i0 p( a
// TODO: Add your specialized code here and/or call the base class
+ l. _- x/ p+ i' w% w$ G UINT nBS = GetButtonStyle(); // Add BS_OWNERDRAW style% ? P4 j4 {# c! }/ g) g1 f
SetButtonStyle(nBS | BS_OWNERDRAW); CButton::PreSubclassWindow();) W7 y+ l) f; V1 O8 ^1 k2 m: |
} void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
1 L# X; Z, j$ O9 _% r+ c4 Q* ^$ x8 L2 |{
! w$ u' L8 F( p5 V CPen Pen;
0 P- o! q( H7 i2 a; f( u2 e# o' J CPen* pOldPen = pDC->SelectObject(&Pen);; B- |& A) H- u( \# i7 ?/ w
3 h) h. m6 M: F/ |5 z0 a: N' h* i int R, G, B;/ T2 i2 U1 s, J9 o5 [$ e( C/ ~# U/ M
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();& h3 P ]* w3 U# ], j7 k! C2 H/ ~
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();2 Y* m# ?6 }, J
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();7 S1 p! Z+ z+ h( v7 t1 ]6 x8 q
6 ?) R' X( B1 l# Q( J/ [
//R = R>0 ? R : -R;* D6 m+ q: Z! g* r3 B: p
//G = G>0 ? G : -G;
- r3 |4 k3 s% `1 x9 C' Z5 m //B = B>0 ? B : -B; int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);- _( k( y- O: h/ F
COLORREF ColMax = Top > Bottom ? Top : Bottom;5 P1 y" y* O1 C, X. p" ] t
COLORREF ColMin = Top > Bottom ? Bottom: Top; for(int i=0; i<rc.Height(); i++)7 u$ R- x' y/ B ]% H
{
% H& d4 f2 u* p9 c2 C; b* J. b( y ColR -= R;9 d: k: _- k f0 f: g- e/ g
ColG -= G;
1 Q; N; w5 s3 d$ _ ColB -= B; /*
( W4 [$ s1 }- v5 c4 a if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||+ Y5 W- D) O7 K' G' r
ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
. \, K; _1 } G7 M ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )- F% f+ _3 [. Q, x' O4 H) X
{! U0 i4 V+ {* h X7 ?0 u( j
R = G = B = 0;& h8 ^% n6 ~& p8 }1 w
}///*/
5 B/ C& i& I' p3 y Pen.DeleteObject();0 e4 p) W, |& Q- \/ K4 L- [9 O
Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));( v4 L6 M+ D* V5 {
3 X+ R# r$ X' N6 g! ?% | pDC->SelectObject(&Pen);
1 D+ ]9 y, V8 N4 z6 a 1 q3 B* y1 K$ V3 E) ~' q \# b$ S
pDC->MoveTo(rc.left, rc.top+i);
2 A/ W- w# W/ M pDC->LineTo(rc.right, rc.top+i);. F" R9 F0 C9 v" H D% ?
}
pDC->SelectObject(pOldPen);
; |" M; S! k# c; q- E} void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
5 a" T* _, F5 l& z{; W/ ~; O# r( r9 ^; k
CBrush NullBrush;* ~9 [; W- p: V; s8 M/ J
NullBrush.CreateStockObject(NULL_BRUSH);3 b; b0 @* b! u4 d! z9 @
CBrush* pOldBrush = pDC->SelectObject(&NullBrush); CPen Pen;6 L; y! Z& [2 [6 H( w
Pen.CreatePen(PS_SOLID, 1, FrameColor);
! Z# ]% M+ g. s/ f CPen* pOldPen = pDC->SelectObject(&Pen);
5 R% S$ ^' F" J0 p
3 E5 N' [2 ]$ E# W pDC->RoundRect(rc, CPoint(3, 3));
% [4 O+ @: o6 f# z4 B% x rc.DeflateRect(1, 1, 1, 1); 1 ~$ V% W& p/ R3 O9 [. s
pDC->Draw3dRect(rc, HeightLight, ShadowLight); pDC->SelectObject(pOldPen);. `" O+ H$ P' T. A* t/ l0 G
pDC->SelectObject(pOldBrush);
+ H: U3 ^( J2 |( ?, E3 Z' m4 i4 t}
3 N! b2 |1 Y5 ]! T, Z8 j; J. v' H/////////////////////////////////////////////////////////////////////////////
0 ?& I- Q( w% |" h5 X// CHsPMEDialog dialog
9 w+ w4 B8 \1 D' ?7 _7 [//-----------------------------------------------------------------------------7 B5 F+ d$ `; R! J- T, z
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:3 H0 g5 t! V1 {/ P! K) v* Z L
// 1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
: L5 z, j5 j, p// (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口* k. f' h( I* n/ H! N' Z; `
// 指针将其显示出来,然后隐藏或销毁自身
6 `- i) D. `4 }- c// 2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
$ l0 E. ^& r+ d6 O; R5 b// 采用的方法为使用上面的CHsPMEButton作为按钮的基类
- ~7 Q( R1 y) n6 I6 q) I1 `// 3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
: }* |4 [4 f. ~$ B4 Q// 如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
- P" c' I& ?0 E2 P1 {$ U// 采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
" i5 ~' j3 b4 O: L: z0 u, a, ^( e- C// 4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框 m/ j% r6 y" ~4 |' E& R' A
// 就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。, ~& n' S ~7 }" T/ e* x2 x' f7 e
//-----------------------------------------------------------------------------
9 P9 [6 t! T+ Q G) {// 注意:
% N! Z. G+ e. w, p4 N6 X& z// 1、在构造对话框时必须给出其父窗口指针
$ u/ z9 _0 {+ r) O" d- s0 \, k! t// 2、在初始化基类时必须指定对话框资源模板ID& z# B1 t7 V2 J7 }. N
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
3 O5 Q! Z- M" r7 {/ m// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
' N2 { ]; o$ x, T8 x//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog- t& s; h3 ]( B" i& u) D5 }4 M4 I$ ]
{
! T) C+ s- A9 R" s' Y3 u DECLARE_DYNAMIC(CHsPMEDialog) // 为了实现IsKindOf功能
, ]" {! ]' ]' @ w" e! X/ e4 ~6 [// Construction
/ `% L. g, B0 j8 Kpublic:
4 H+ J F$ `' {; O9 X$ P CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL); // standard constructor
' J4 r% M1 T' n* r8 N$ z ~CHsPMEDialog();
: y: {1 W! ?# {# v BOOL Create(CWnd *pParent = NULL);- I9 y& F/ U" y" @4 t3 }
2 E2 g2 A% ~9 R3 A |/ H; E
// Dialog Data
U5 b9 s0 F9 Q4 c' t" c( S2 x //{{AFX_DATA(CHsPMEDialog)
4 ~; s4 }$ h. d" Z5 r' ] //enum { IDD = _UNKNOWN_RESOURCE_ID_ };
2 \* L# F8 Z' C9 g/ r! Z // NOTE: the ClassWizard will add data members here
$ @* N4 \3 N M" T6 o% c/ ^ T+ P //}}AFX_DATA 0 } O; j {% [ O3 F
// Overrides9 I; Z. F+ z. M) @1 O
// ClassWizard generated virtual function overrides
8 }1 Q' A1 ^# G) i) F+ ]/ O //{{AFX_VIRTUAL(CHsPMEDialog)
# q/ V0 L" c7 m3 W2 X protected:- Q, w) @; V5 x/ _8 A. U$ {
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support1 \2 d; d- B- o) ? ~
virtual void OnOK();. K* w! \$ |: ]9 |
virtual void OnCancel();
' d) p9 y" u3 q virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
* e/ ]7 u1 Z1 I9 \7 `9 v9 ? virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
! ?' v2 O0 U) t$ t1 i //}}AFX_VIRTUAL // Implementation
) |/ B" _. w' T6 ^! O6 b; Aprotected: // Generated message map functions' M: I, P7 x `% q# \- ]* {6 ^" v
//{{AFX_MSG(CHsPMEDialog)3 \9 ~* n1 _ u4 }! t
afx_msg void OnBack();
' O; @/ L/ N2 x9 D3 J virtual BOOL OnInitDialog();0 s2 x+ D q& j. v
afx_msg void OnDestroy();- U* r5 `2 B; e% M" D
//}}AFX_MSG2 L4 l+ P* s, d* [; f1 l7 V
DECLARE_MESSAGE_MAP() protected:0 c% C$ B4 A5 ?# ^$ d: d
// attributes
4 D, q9 u: X* L- e CWnd *m_pParent; // 父窗口指针& c) ? M+ J) Z# ]6 H
HICON m_hIcon; // 图标
, ~# l6 }. i N& [# ~" `8 _; r UINT m_nTemplateID; // 对话框资源模板ID CHsPMEButton m_btOK;
0 ?, H" D a1 _) w" s- T8 m0 o F CHsPMEButton m_btCancel;+ E& H9 U0 E3 J7 X0 P& `& a
CHsPMEButton m_btBack; static HHOOK m_hkKeyboard; // 键盘钩子句柄
& M8 I% j; w! r& n HHOOK m_hkCBT; // CBT钩子句柄
0 H. X* ]8 B3 i! O2 p' \; X
2 x! p+ A$ S4 N: O/ r m //-------------------------------------------------------------------------8 g: x5 @! V a, h$ }
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
' t. r4 J1 F" g) [( I // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
9 U! q5 t+ a/ J* T // 链表的头及下一个结点的指针: N9 P8 W$ s( b& J/ K6 O1 e1 K8 R
static CHsPMEDialog* m_spHead;
- E) B' v- q8 v; H CHsPMEDialog *m_pNext; // operations
3 n0 {, M* Y0 e! ]% j! d- B1 \" ? // 键盘钩子消息的处理函数
}$ k, q( z& L; x. V static LRESULT CALLBACK KeyboardProc(9 {, \9 z1 h5 w* I( V! p+ I, B# {
int code, // hook code
7 f6 p* _% N, f, H: u WPARAM wParam, // virtual-key code
2 C7 V l4 M/ `2 G4 ?" n7 W LPARAM lParam // keystroke-message information5 X0 T) b# I1 j; m2 q
);
7 F( B% K2 I6 u6 c7 r // CBT钩子消息处理函数
9 H) C+ a/ }% C! W6 Q static LRESULT CALLBACK CBTProc(
! Q% [. C( L0 r( R; F- D. F int nCode, // hook code
" [: d; j6 p& K: q! K% p) @ WPARAM wParam, // depends on hook code6 N3 k8 y3 g! e( A7 v- w
LPARAM lParam // depends on hook code& y: |) a2 O6 [: e1 r
);
& R0 ]- [, V! f' C // 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口6 C2 k" s6 C. h- ^% y5 g/ a- u
static BOOL IsWndKindOfThis(HWND hWnd);
( }& b. w9 r p0 c' } // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
, Z$ Y" G, M' {2 Z# v static HMODULE ModuleFromAddress(PVOID pv);! h8 S5 W6 X I
public:
. E% Y& {% `& L0 H. r // attributes // operations p6 H7 I! u# W' {+ T
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框
. K. m% y7 I1 L) B, y BOOL CreateChildDialog(CHsPMEDialog *pChild);
6 X9 H5 i: s& X( s}; 9 h- T' Z: s, |. I6 j; w* e1 }
CHsPMEDialog* g_pHsPMEDlg = NULL;
; m9 `) I: n6 ? h5 U# o- x5 s; c( c. LCHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
U% l' H$ x% [& N% P' Y* E9 y/ C8 vHHOOK CHsPMEDialog::m_hkKeyboard = NULL; IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog) CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)& x% u- b. A' T e$ `4 \
: CDialog(nIDTemplate, pParent)1 D7 h8 ~. ?: R; e8 O# ~; F
{
2 ~0 F# W& r" y$ I* k! V //{{AFX_DATA_INIT(CHsPMEDialog)
: B1 a; U: w: t% c7 J8 } // NOTE: the ClassWizard will add member initialization here
0 w Q1 o9 I8 F$ D4 ^. b //}}AFX_DATA_INIT/ v% q9 z- u; }& |
m_pParent = pParent; g2 n3 \1 f) ]7 G2 z
m_nTemplateID = nIDTemplate;
+ \2 V T2 a& X$ [# [ m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标 // 建立起链表
0 D+ t( P) q/ ?( t m_pNext = m_spHead;) z! m+ o9 E- g
m_spHead = this;( J4 G# f' I) @! N" U
m_hkCBT = NULL;! d ^1 m6 ^3 @# u, l1 D( i2 m
} CHsPMEDialog::~CHsPMEDialog()" S8 G5 o* W# b# } b7 s2 `3 I
{; w T" B; P5 r& Y* [- ]( i/ _
// 从链表中删除本结点
3 H! N6 \! w8 r( n; f% i CHsPMEDialog *pTemp = m_spHead;6 Y4 A4 H% H. j. ^6 {
if(pTemp == this)/ D9 J* H" J, T! T/ s2 ~
{
. U$ s8 v9 Q. {4 b$ e1 z m_spHead = pTemp->m_pNext;
% ]. K9 n' S( \ }
) S, A4 I% w2 Q. Z# I4 v* z else. Q3 v' q, O+ R- E; i# h
{5 B% P$ k% f7 o
for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
, ?: ~ ?6 v3 u8 l {
4 X2 y8 u, a' R if(pTemp->m_pNext == this)/ F6 l7 `4 b% l- W
{( X! ~; U( Y; m
pTemp->m_pNext = pTemp->m_pNext->m_pNext;2 O2 I5 J$ @$ @, ~) C
break;
: o# Q; d9 C- u$ V( t+ [. q }2 G5 z- C+ L+ F2 n+ A! h
}
( i8 s5 l4 C( p t" T6 H } I% y% ~8 C; [) Q9 S/ U
} void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
" N1 W: p* c' G# I3 {{
7 [" t% t/ m. i) o& ]; i0 d- I CDialog::DoDataExchange(pDX);
- `; E$ {+ {) u8 J. E* E- S' W- w //{{AFX_DATA_MAP(CHsPMEDialog)
- ~& ^/ ?* ], M1 T) b0 [1 f DDX_Control(pDX, IDOK, m_btOK);
$ O9 ~' o8 @2 c1 c- ~ DDX_Control(pDX, IDCANCEL, m_btCancel);: j7 \) g& @2 t, k- ]2 X) [
DDX_Control(pDX, IDC_BACK, m_btBack);% U7 F6 h, K- G. m: u0 x, t: h
//}}AFX_DATA_MAP
" j9 H4 [2 f( ^! D9 f} & z, Y! s. d0 |3 T& {/ y* _
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
$ x9 C! r; L( o //{{AFX_MSG_MAP(CHsPMEDialog)# t) t) K) v! ~- I
ON_BN_CLICKED(IDC_BACK, OnBack); @/ v; ]5 [: l& }3 f; b
ON_WM_DESTROY()
. `* l y8 S0 H7 `/ }+ I# w( u3 h //}}AFX_MSG_MAP
1 e% W" s* `/ {* y; @- v9 z6 x0 @END_MESSAGE_MAP() /////////////////////////////////////////////////////////////////////////////& }" e' i4 ]: ]8 a( ^
// CHsPMEDialog message handlers BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)+ H% p6 K! V. m E
{* N% p6 C( E% o
m_pParent = pParent;+ T) g* i5 m9 I" M2 \* I, e
return CDialog::Create(m_nTemplateID, pParent);
! f( J. j1 m" ~1 F# m! g# d} 3 U' V# B, u/ ]2 S7 S% M
BOOL CHsPMEDialog::OnInitDialog()
) N- c( N. r: @. K) v- q$ `% ?{
# r# L0 B, \+ A+ ?: { CDialog::OnInitDialog(); // 设置标题栏图标' q7 {- x; O4 w" G7 ?4 V
SetIcon(m_hIcon, TRUE);
1 F& v5 ~8 Q0 O. \ SetIcon(m_hIcon, FALSE);
5 X2 c x- b* w' w( U* Z
3 Y& B1 A) ]0 @$ G7 G3 s0 ]% w5 ^ // UG的对话框的几个标准按钮没有TAPSTOP
& z+ B0 S9 u% y& y# ?8 w CWnd *pWnd = NULL;
4 C9 J F8 e2 F$ V3 G pWnd = GetDlgItem(IDOK);
3 n# q$ x$ v% |2 C if(pWnd)7 L- B+ V* n( R9 b; m1 z# `) R
{5 X- c& C0 c5 T
pWnd->ModifyStyle(WS_TABSTOP, 0);5 y: k- L2 z( A; E6 C
}" Z p5 ^" A8 `! [2 _2 D2 U' u
pWnd = GetDlgItem(IDC_BACK);( J$ k' Z9 a9 u( y
if(pWnd)
' @/ t2 T1 _) b {
- u/ u3 b/ U- S* G$ ]% k. s. ? pWnd->ModifyStyle(WS_TABSTOP, 0);
; A/ g/ K) o5 B }
4 z0 {' r3 L4 k8 y pWnd = GetDlgItem(IDCANCEL);( q* h; _ ? y% u& N' M
if(pWnd); ^2 o0 e9 z( m9 g: }4 J* p
{
% _) ~ I$ k/ L2 a; x pWnd->ModifyStyle(WS_TABSTOP, 0);5 _; E9 y8 f( G/ K* g7 s! \
}: _3 D% o% V- m+ B" l5 k) t
, E# w7 b. I: u5 \* M t+ A
g_pHsPMEDlg = this; // 方便在静态函数成员中调用 // 设置键盘钩子; k! {+ t H, ]
if(m_hkKeyboard == NULL)
) c+ ?" x+ G3 E8 L& J7 p {5 a5 O1 \. E% ?9 m4 H
m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
/ k3 o# m s/ R6 v8 R7 r% {0 a }
# e; f% C1 _$ P0 k if(m_hkKeyboard == NULL)) w: r2 N, C+ D9 \2 i$ M
{
8 s) r, M, N, c! _ TRACE("Set Keyboard Hook failed: %d/n", GetLastError());$ O* |5 Q. V6 C7 Q6 \9 w
} if(m_hkCBT == NULL)* k! m* N$ a) s) v! Y+ L/ R
{( W! j$ S; E# A. h* Y
m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
# R1 r5 H! u+ {. T1 z4 z }
! J" P' P; i9 n& g6 p5 Y if(m_hkCBT == NULL)
0 e/ q5 W9 q2 `, B7 M {" i" f( k. p) H, c- l) j: C0 ]
TRACE("Set CBT Hook Failed: %u/n", GetLastError());3 @. I0 L8 n/ p
}
5 \+ V" z Y+ U1 a! ~/ h 2 `* \/ X o! a$ ~4 L
return TRUE; // return TRUE unless you set the focus to a control
5 y4 [4 m+ X& }$ J, ?4 A7 y // EXCEPTION: OCX Property Pages should return FALSE# O# F4 j; T8 {* [; f
} void CHsPMEDialog::OnOK()$ c7 K# I0 n& U
{0 E) V3 M8 y' ` d
CDialog::OnOK();+ G9 I* h) b, N7 }0 o" X
if(m_pParent): b% L% A( l; m9 K7 d2 L5 Q
{
0 b# g) Q. `9 [ //m_pParent->DestroyWindow();
% S/ A- m- M0 Y3 R //((CDialog*)m_pParent)->EndDialog(IDOK);
3 A/ G; Z) m5 v, p ((CHsPMEDialog*)m_pParent)->OnOK();
& X# v' {; f- i3 Y }. f# u0 L' H ^- F! u
} void CHsPMEDialog::OnCancel()
; T; e l7 L) y2 f$ {% ~1 f{
( u s G* l- |* P! J4 K CDialog::OnCancel();6 R# L) C6 O; W' ?# X; _' T
if(m_pParent)
/ G B, V! W: K- x {: r x) i% K8 X6 L1 W$ z9 p
//m_pParent->DestroyWindow();0 q* F7 U' W( j! n" _( S
//((CDialog*)m_pParent)->EndDialog(IDCANCEL);
# t3 {- N" Y. _6 b. r* q' s ((CHsPMEDialog*)m_pParent)->OnCancel();
+ X7 U. [ H: ?1 V$ c' }2 l+ U }/ I) v/ ]( Z* O( O
} void CHsPMEDialog::OnBack()
# O- b& [9 L+ k9 `% n{: S% o( k' l; P( E4 _: B
if(m_pParent)+ y' U; m9 a- V* g4 q
{* n. |; a/ ~0 e
m_pParent->ShowWindow(SW_SHOW);; f4 e5 x/ W- _' O
}
0 e* B' C/ ]! j) E CDialog::OnCancel();
- t3 T6 L: f- T} 2 h( g+ d% A7 i( x
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)2 H6 v V; T8 [
{
; `$ P; @, Y$ C* \& ]1 `, ?, N BOOL bRet = FALSE;
2 V5 L, A- m0 |! ?0 ]6 M% w if(pChild->GetSafeHwnd() == NULL)9 m( O: ~% t$ r6 f+ m
{3 p/ Z3 N) N o/ |2 w
bRet = pChild->Create(this);
3 Y5 h P( J8 n: n# |! t }
" J5 f- i5 g$ u bRet &= ShowWindow(SW_HIDE);
7 Y& I6 Z. g% U4 c( P& a bRet &= pChild->ShowWindow(SW_SHOW);6 X4 q# n2 f# q
return bRet;( j1 i g, `# c5 J0 p
} LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
; C2 C, T. O, Y: l# c2 j/ M{: p4 |8 g/ l3 J
if(code == HC_ACTION && !(lParam & 0x80000000)) // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
% ?, y6 E2 }: E3 c% s5 q8 d {' }' t4 ~1 ~$ p N, G! T! p, S
//TRACE("Key down/n");
# t9 B ]$ P9 c0 B# ] CWnd *pTopWnd = CWnd::GetActiveWindow(); F" C. q% V4 I( {
if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))' c* c3 ^- a/ L# S# \ H- J
{
/ H% y7 W6 T5 e, A // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息0 W7 W' B, q, ?! }
if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)* G7 z6 ^, x" ], J
{5 }( j- i' N% G4 X* u
// 只截获tab、esc及回车键
3 l; H" g @) S //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
% ^. p0 m& _- n //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
$ `4 @; Z, P/ c& d: p }
8 Y1 D8 I* C! w, F' z switch(wParam) {
! |) F: \( y- S, w8 D" P! V0 P' L case VK_TAB:& r9 _/ B7 U" y4 a: I
{
6 \$ X* j5 O$ l9 S# [ CWnd *pWnd = pTopWnd->GetFocus();, T" r. o& A2 m7 w
CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
$ x9 Y1 W- A2 |+ h" [# Y T if(pNext)
4 T3 Q; T }# R/ ? {2 b+ j' u( Q' l! p8 w/ o
int nCtrlID = pNext->GetDlgCtrlID();
1 j. L% ], w6 f# J) W* T- a //TRACE("CtrlID = %d/n", nCtrlID);
1 @2 p: k0 O. E1 p; ~$ d pWnd = pNext;8 Z/ i7 T* A( b/ N0 K6 |4 e9 c
while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)- C4 P( [; p5 L9 \& t
{
! \% J, m! L& P% K/ m5 e // 根据UG对话框的属性,这三个按钮是没有焦点的
% A( h. x- f- N* ` ~ pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
7 ]3 H8 e, ], W$ w! Y( } if(!pNext || pNext == pWnd); ~# r. \$ w. c: s o( t' g4 X( H
{
+ @; |3 D6 V, l3 r6 O- z% i2 E$ M4 ? // 对话框上只有上述三个按钮
8 U: ?, a- R" g. i I* l' A3 {! M return CallNextHookEx(NULL, code, wParam, lParam);
' E; k3 F- _/ n: g/ t8 ?# ? }
; W! F9 I$ f5 U" J nCtrlID = pNext->GetDlgCtrlID();
5 h) e3 N/ v; A5 s: z5 u2 K j! z" V ^0 R& Q //TRACE("CtrlID = %d/n", nCtrlID);
# b6 O& q, A1 g z; F }
* A; }, q8 g, r* H pNext->SetFocus();
8 t. I! h n' z1 d3 W }
# b( ?- A' N2 @8 l a) l //return TRUE;& h' o* c& ? L2 u/ |; N* Z ^
}* A$ \# U7 u# \: w
break;, O, S6 X& t3 @
case VK_ESCAPE:6 I2 E, J% y4 I! G7 J, S* d3 R
((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
- n$ h' Y" y$ O/ {6 B //return TRUE;
& N! {, m1 m- `& o% W break;
# H& n. v. o0 u+ @5 I case VK_RETURN:- J8 A' X9 q; U5 H+ p$ X, s
// UG实际上并不处理回车键 D8 M$ T, @3 ~: ~9 i
break;
* c4 A% o/ c2 @' W: J: n: K$ n6 D default:
/ ~3 h6 h4 @* m* W8 D% \ break;1 _8 _+ x* X! U x
}
. k! X& J7 Z& o; z1 ~8 N }
4 |+ a5 ~5 X* W. G. y }
* o4 e9 O0 T+ ~9 B4 G( ] return CallNextHookEx(NULL, code, wParam, lParam);
8 e' ?) v$ b8 p$ }} void CHsPMEDialog::OnDestroy() 3 C6 y7 q) e' M+ D. V; a% S; p
{3 w6 J, i4 w/ D+ S0 q* T1 k
CDialog::OnDestroy(); g_pHsPMEDlg = NULL; // 销毁键盘钩子% d* I1 A& w% o% u3 P
if(m_hkKeyboard)' ?9 d! C8 H$ J% l3 {+ A* ?
{
5 w0 j; r; a# _; Y: _: S* ] UnhookWindowsHookEx(m_hkKeyboard); " S* Z: d( q; g/ T% f0 ^9 [
m_hkKeyboard = NULL;( l/ `8 V. v( A7 _
} if(m_hkCBT)% X+ N& _8 M: n. E8 L+ E: U
{) r- y- F3 g, n' c* C, V2 S$ Q
UnhookWindowsHookEx(m_hkCBT);
5 x9 a% d2 e8 \' h m_hkCBT = NULL;& D S7 R) ^0 j. `1 L- h4 P
}5 e6 B, B' y/ C1 x$ {* Q' }
} BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)7 V* ]6 r0 }+ i- _
{
. j# e. {' ?4 K$ y& F CHsPMEDialog *pTemp = m_spHead;9 R& e) G; o/ T* [4 `- s3 L: c0 ]; `
BOOL bFound = FALSE;
0 J4 t+ b5 t: K# ~# ? for(; pTemp != NULL; pTemp = pTemp->m_pNext)7 I; e3 b9 T! v5 u, l) G+ L( H: x9 V8 T
{( I3 N. ^: ]3 j. Q+ ?8 b C
if(pTemp->m_hWnd == hWnd)/ a5 i# T$ B* I$ v$ y. I/ G7 H( l
{# v3 z" D* {, T1 b0 R& X
bFound = TRUE;
# Q7 l( S( |% q3 g% \( j# k7 m break;
2 Q1 e# Y9 j9 r6 Y* Z" Z m2 G( \ }6 A. c: l( B$ o6 C) Y& m& U
}8 [: s! q: m: p
return bFound;; t# N+ `1 a8 T" r2 C/ K$ c
} // Returns the HMODULE that contains the specified memory address8 D* \. T; _) t9 R
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv) * g& ?7 h4 p% I( W# S8 [4 J. q. C7 a
{2 x$ W; w- Y8 a6 B! k4 ^ p% |
+ `* d+ l/ u; Y9 S4 D
MEMORY_BASIC_INFORMATION mbi;: T, S9 t/ ~9 l1 p; g/ Y
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) 2 d3 V- J* {! R) m
? (HMODULE) mbi.AllocationBase : NULL);
+ W: K# L1 q' [4 D. i0 y} LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
/ i- ]9 l# k: V9 ]{. b( W/ A% w: k4 y( b2 j2 F. V. Z
if(nCode == HCBT_CREATEWND)& D7 s& T( J/ S: o4 @/ F: |
{1 X1 d% Z; ]1 \' n
//TRACE("A Window is being created/n");
' u/ b, H5 P% {- h# g: F, J' f LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;! ?1 D1 n3 ^/ E& |
//TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);4 g+ x! c( w- g2 D# G, ?
if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
9 I$ `" `9 u- T8 Q. F {; u) d$ s% s w/ }. R
// 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应 a% b8 ^2 b, ^ E1 e1 Y7 b) R
// 取得窗口处理过程内存地址/ U0 \9 ^1 i+ ]4 X. E# P& ~: B
DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);& [9 r/ E- h& d- h, T% S4 h( }
if(dwUserData). \' |! x( r0 S+ g7 B8 C% O
{
1 p) c5 p) q) E+ D9 m HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
( |3 W, p) S7 a+ Q1 K% o char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
, a+ ^# O4 r5 [, b; I4 c: z GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
% r$ `2 |$ ]& Y" I; r, _ m GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
/ H2 X8 W1 g, @2 D2 P3 | D/ ~ TRACE("CreateWindow Frome Module: %s/n", szModulePath);5 b, D# X2 {4 \% l* j' w/ C
TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);7 Q: c0 h5 B. v; f6 @: R9 V* }' B
if(stricmp(szUGPath, szModulePath) == 0)
" @1 K: }1 ?( y* w {) ], o! P2 R) A1 q5 l7 ?
// 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
: N7 _9 }; \ m; y, q1 E) K if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
) J$ a$ O7 A* M) i5 V( j {
% l, Z) B, H& a7 t // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)7 w3 O& F w7 j3 E
if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && 1 k. p- c$ j9 I+ Z* K% Z' t+ d! N
lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)* R: _, F1 K* f4 T7 J
{
$ ~+ C+ R5 _5 W. e9 h, @ // 窗口非本窗口或其子窗口8 Q4 u4 e. X- B7 z2 _. X2 C2 B! C
g_pHsPMEDlg->OnCancel();8 W0 I( [4 |: F* ]" M
}$ O8 W8 h) ?- [# F1 }
}9 n) S' M4 `/ D; J! s; Y4 W
}, H; N( S( Q" K
}
6 M6 x# p5 \6 T }4 l, x- @* L G4 z
}9 k. m* e: t1 [, t* a
return CallNextHookEx(NULL, nCode, wParam, lParam);+ U8 E* _3 g# ~8 B% |! i
} LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) ! ]" Z6 X H% b& @# H7 @* b
{: ~5 k7 S. `# [% v: b3 ]$ e8 X1 D
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
% c& w- q- a h7 K. w1 |: C# z7 i
, X8 s- I( n/ S return CDialog::WindowProc(message, wParam, lParam);
( I/ v. V) w* y. \8 }! J} LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 5 a. F! X/ v4 q9 S1 k
{
+ V& V- o3 ~' F8 R2 f. q" L / z2 I' d: N+ _+ L
return CDialog::DefWindowProc(message, wParam, lParam);
- f0 e0 m" k0 V# Q} ( p( o& b) X+ V+ o4 s
|