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