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