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