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