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