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