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