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