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