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