PLM之家PLMHome-国产软件践行者

[资料] 用MFC对话框模拟UG对话框

[复制链接]

2017-8-31 13:24:24 3215 0

admin 发表于 2017-8-31 13:24:24 |阅读模式

admin 楼主

2017-8-31 13:24:24

请使用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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
5 H  G) O8 K! f% C$ h' }0 R// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
, Q2 o/ i) S' {! s9 i- h' z* p//    该类来自网络,稍作修改,版权归原作者所有* ]6 C* t; J2 S& _
//-----------------------------------------------------------------------------$ X7 v8 k9 F7 f+ l/ w0 l8 F
class CHsPMEButton : public CButton9 c. v. p1 x' `; S( _5 E9 O. p
{
3 q( f+ {" |6 t  L# @, J$ \ // Construction+ V, _1 b3 b) d
public:. H" W# W: |0 @, b4 P
CHsPMEButton();
: W! Z- L% w5 S; z( t
7 a$ ^0 t$ P2 C3 J7 ] // Attributes
/ R- a# ?  {: d7 n6 gpublic:
" ?/ {6 z. I1 I2 m) y
  c/ G3 Z2 [! P' ^6 J) H! E+ U // Operations
& ?/ Y- l9 P" `public:) v% Q0 @% Z" S2 h2 w6 v- v
inline void SetNormalTopColor(COLORREF color)
' Y" c" |+ \/ A9 u {* A3 `' t) {2 l! U( ?' E* n& W
  m_NormalColorTop = color;% y9 ~* N$ t$ d# w2 E7 b
}
( Z  K% I! U  R; }. w% L inline void SetNormalBottomColor(COLORREF color)' e% X" G2 ]8 Y& Y9 H0 D
{
# ~. p8 j$ K* Y" }  m_NormalColorBottom = color;
" J& K- A& z5 [# K- j( \ }. v' t. N" j0 K7 R
inline void SetActiveTexTColor(COLORREF color)
/ \5 E) O, T  O% C {
6 O. M5 ]2 O4 P9 c- i8 t% X  m_ActiveTextColor = color;1 R: z+ e8 n6 I9 Q6 }+ b6 D
}2 p8 U8 p" C8 z' y$ _4 b
inline void SetNormalTextColor(COLORREF color)
* \9 m  I5 j3 ^5 c6 r( e {+ I; Z! m3 `1 [' l
  m_NormalTextColor = color;6 E& h; ~( Q4 n+ Q! `' g
}$ [4 C3 q! j3 n+ X% k( S+ k0 d# Y
inline void SetSelectTextColor(COLORREF color)
4 W6 ^' E; |( j+ Q* `. O {
" ?6 e& ~6 Q( C! ?; U  m_SelectTextColor = color;1 k( ?, {& p7 }' s9 l
}
" b2 y- ^% h. q' q7 \4 H4 G inline void SetFrameColor(COLORREF color)
* Y2 X( [$ p# v4 j& c+ I8 }) m/ C {( q( p+ B" h& p5 |0 E4 ?9 C4 @
  m_FrameColor = color;9 r" I) z/ G$ f
}
# ^1 M) \  D: P inline void SetActiveColor(COLORREF color)
$ w$ W) J$ |8 Q {+ M& a1 e  N( V5 g3 u; W4 A
  m_ActiveColor = color;$ `( i$ j: L# U! c% i/ a
}9 R+ {5 p- C3 K  V
// Overrides+ s% S3 R/ P  a, N0 S
// ClassWizard generated virtual function overrides8 Z- O0 y0 @# T8 s
//{{AFX_VIRTUAL(CHsPMEButton)9 E" o) P+ b7 |; Z% C
protected:
' L) c& n# j. }5 m virtual void PreSubclassWindow();
1 ~8 C" Y; |0 k7 J' G9 [ //}}AFX_VIRTUAL6 [6 F( q; S( P8 ~
- J  Q$ {4 I; [, B( h
// Implementation5 I) f4 _( b* v
public:5 B/ ~. Y/ ~; x. i0 W- |& S
virtual ~CHsPMEButton();4 T/ l2 {/ C% x) G
3 D7 q9 D/ F! W2 N  O. O/ Y" l
// Generated message map functions
, Z) O! e+ u* N7 Z% K6 y$ Xprotected:, n2 s4 s8 ^$ w4 m$ u1 g
//{{AFX_MSG(CHsPMEButton)& c0 R0 l" J  R" w, c1 ^
afx_msg void OnMouseMove(UINT nFlags, CPoint point);# [) _" R: i: X0 H
//}}AFX_MSG
# Q2 q3 I: ^1 ]
" o/ I( F! U) ]3 l2 t& g void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
" ^/ V* |2 J, A7 w void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);! e- _& z# z5 R* z, {
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
2 G0 W; H* |  X4 ?" U% q% \+ g LONG OnMouseLeave(WPARAM, LPARAM);
2 U9 h! b. y, o9 W' Z BOOL m_bIsMouseMove;
% h2 F, E, z" T- Z& v7 M9 n
& S  H: x7 I# v' k9 j' ~ COLORREF m_FrameColor;% h% b1 b- P6 A$ J5 T
COLORREF m_ActiveColor;
9 h; q0 U* Q' j+ m5 c 3 P- W0 r- k+ ~
COLORREF m_ActiveTextColor;# i2 ~( g& }3 k8 F  [8 ^
COLORREF m_NormalTextColor;2 K5 z4 _6 r) N
COLORREF m_SelectTextColor;& I4 [8 b1 t/ `- k8 `1 L
, P$ B2 t6 o5 |7 F
COLORREF m_FrameHeight;
4 u' `: S1 ]& S/ z) d( s, ^ COLORREF m_FrameShadow;8 q1 i1 G& Q' S; N6 \
$ O. U5 b' c3 w; x2 U
COLORREF m_NormalColorTop;
) q2 ^; N# S" R) v0 z, x; K COLORREF m_NormalColorBottom;- E8 \8 k4 {  }9 |3 K( Z, ?

+ Y1 A5 c" R6 K4 t DECLARE_MESSAGE_MAP()0 X* W: v- a) D" S" |( Q6 ^; Y8 v
};
/////////////////////////////////////////////////////////////////////////////5 \# R, r; G4 K
// CHsPMEButton
CHsPMEButton::CHsPMEButton()$ Z" X7 O( d( S7 L. g, N* D
{$ B, D, O. j5 P+ z/ D7 V8 s
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
: W1 \( C; k9 H. ~4 m m_SelectTextColor = RGB(0, 0, 0);/ D5 U) t! o5 m7 w% g) Y
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);8 A9 N9 C; a: I$ P% G( q
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
# i; X6 [5 G$ V7 P; n m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);& s  q% [+ ~: T9 o! B
m_FrameHeight  = RGB(230, 230, 230);( M% M" r, a7 j( d# g  j
m_FrameShadow  = RGB(128, 128, 128);
! O  W8 Z7 U' x* [}
CHsPMEButton::~CHsPMEButton()
2 k8 \8 \9 f% a* ?9 t{6 x4 M* J* }/ H. M/ c$ J
}

. B& R  h% g7 Q" _BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)3 f. }5 ^0 L; g$ R7 N+ o( Z" O- C
//{{AFX_MSG_MAP(CHsPMEButton)
7 a! x9 Z6 x5 b ON_WM_MOUSEMOVE()+ |8 s  m1 c; W% e6 r
//}}AFX_MSG_MAP4 }$ ?3 d( e' W0 F
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
4 U' f! F5 n6 U9 d# r; i/ KEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////" _6 C& J: Y# w* s& m) i
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )7 ^; q' _: L$ w
{9 ~& j- |7 ?* A
//** T! _7 O6 v& S! q( B
CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
( M& t+ T. F7 @, ? DWORD nState  = lpDrawItemStruct->itemState;( p7 e/ M3 k8 z* [( r2 ~+ U
DWORD nAction = lpDrawItemStruct->itemAction; + d) M+ ?# M# Z& c# I' y  F
CRect rc   = lpDrawItemStruct->rcItem;# R; v# d& m3 E/ j0 R
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);5 [& G4 _3 ^& X3 m  T# t6 x$ i2 R
CString strText;% a  S8 b1 n" H* d! O
GetWindowText(strText);
if( nState & ODS_SELECTED )
& i- _) a& ]  W {: l$ w4 \# {6 n; P$ q
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);; h- C9 R+ F, [2 N! G& h* j
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); 3 U8 e% ?, d8 C5 C2 M/ l* H% [
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
' A7 J' f1 {. d }
. f( u, }8 D% i1 T2 e else //Normal
! p! L$ w/ H/ O4 S* V {
2 j4 k. P; l; D4 {2 q. x  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
( }" f- T; j6 Q; Q# h! ~  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
/ s$ j" P0 v2 a1 V }
if( m_bIsMouseMove )' u7 P4 G# @2 s  B5 x5 {4 Z
{
( R1 N# S3 M! y6 R2 g2 J$ h  CRect rc2(rc);
, b  X7 d2 V/ x. D; i  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
7 B9 C: B/ A. n& `; f) A   m_ActiveColor, rc, rc, pDC);/ q- V7 h; Y8 Q8 P+ e- A  }" x
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;' M/ P! |+ N3 _( _: D+ P! V) ~
  NullBrush.CreateStockObject(NULL_BRUSH);( h4 \" y' p# ?, j3 W5 ^: t
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);/ ^5 x+ K3 n6 V, |7 H- I( q
  
/ k0 H, r/ s3 J* M* i. ~' g6 m2 n  CPen Pen;
' U1 x  Y" p! B$ e0 {" x  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);1 S; Y' h: L3 p- D
  CPen* pOldPen = pDC->SelectObject(&Pen);
7 i- N0 k, Z3 l. U3 _  rc.InflateRect(1,1,1,1);
' I" P1 [  M$ q0 M5 d  ^  pDC->RoundRect(rc, CPoint(3, 3));
" x! s2 x8 `' ^  //rc.DeflateRect(1, 1, 1, 1);
9 @% v# A% r, x  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
9 x5 s2 o  G7 \; l+ F  
! b+ U% K9 S% G/ ], i  pDC->SelectObject(pOldPen);
' C1 a% J/ O# e2 R3 G; e" d  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);4 |& ~3 _' o8 \% ^+ l% r
}
. W# r0 m2 p) y4 ~' f * o, w& c2 L) \: x
pDC->DrawText(strText, strText.GetLength(), 0 P9 q. c4 I/ j$ b; [) C" ?8 N
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);. G: R: C* k( Q
//*///$ h1 T, l6 I. K. N2 @
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) 3 a7 P0 f$ [' |1 P4 {
{
+ S4 P/ w( }6 _$ ^9 f // TODO: Add your message handler code here and/or call default' T9 |+ m* a  U& h
if( m_bIsMouseMove == 0 )
! i- c' W, J, X- H* x. g {& O" O* j5 m7 k! E  n& p+ V
  m_bIsMouseMove = 1;
) U5 M) f2 z' I  h/ F6 K" _  Invalidate();
8 {6 t$ j0 B2 I. Z  
3 O+ ]/ L: V1 O9 A8 f) N5 A  TRACKMOUSEEVENT trackmouseevent;
6 k  W" x) Z% e" b+ Z  trackmouseevent.cbSize = sizeof(trackmouseevent);, C3 v0 _7 Z7 h" ]
  trackmouseevent.dwFlags = TME_LEAVE;# T+ ]; ]- Z' Y2 M* N
  trackmouseevent.hwndTrack = GetSafeHwnd();
/ x, P0 ~5 \: Y7 ]# Z$ ?* u) k  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
) s! _# i/ U# b( E1 z4 _, I& I  _TrackMouseEvent(&trackmouseevent);4 S& k2 D" A6 _. X$ G; O
}6 d+ r% y! N" t" v' |  d( |% d' C

4 |" }+ z2 M+ n# c7 P CButton::OnMouseMove(nFlags, point);
7 P7 g3 l& ~+ u2 V4 c}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)5 e' `! |9 I& m
{
: \+ h5 [2 ]3 x, I' g m_bIsMouseMove = 0;
3 B. u& W' G6 o4 F3 _ Invalidate();
return 0;
6 H1 H* B3 ?. H# v}
void CHsPMEButton::PreSubclassWindow() ( p* g. ?: M) Y! u" p% A8 J  `
{
: r9 V* I: w# z- I0 U/ O; V // TODO: Add your specialized code here and/or call the base class
/ y- M( a7 w4 V4 W' {( Q# W0 Q UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
, q. _- G+ I0 B' ], y, Q SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();& X! [2 P' x0 ?" J
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
9 R5 x9 N9 Q  z& e. |$ I{& M( X4 A3 {8 d3 Y6 G/ i
CPen Pen;2 u: T8 S7 W: D$ {9 Q
CPen* pOldPen = pDC->SelectObject(&Pen);1 l5 q5 p: v! E+ P+ w% A' G& a

3 p  q+ A& H- [% d int R, G, B;
- Z' S/ t: @+ A7 o! X5 W R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();; k3 [+ X$ E/ \, O, N8 i
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
4 k( F$ b& s( }1 A# H B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();! t1 V1 H0 o1 C' n6 Z& c! O# N

) i2 U+ n' G! I8 ^+ [ //R = R>0 ? R : -R;% d' ]- m" \/ P- _
//G = G>0 ? G : -G;6 l3 w2 E4 N7 {5 i/ L# @8 C
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);8 k5 N& Y6 Q1 C' T
COLORREF ColMax = Top > Bottom ? Top : Bottom;
3 b* J+ c) S3 {# q" P& e) k  Z# B COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
- A" Y, y" V3 G! [, B: X' L {9 f8 z7 a6 `/ B+ Z7 N& N
  ColR -= R;
0 V/ g' q: g( `( |& t% n5 B' N  ColG -= G;  R, Q  [* i3 k
  ColB -= B;
  /*3 H9 Q8 ~- ?" c$ J
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
+ a& g' F1 H$ |) ?. B6 P   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
4 B1 Q( b( r  \( h9 i$ Z   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )' B# d0 _: h' P: O9 s$ B* B% _1 \
  {
8 \# J9 a% T  c& m   R = G = B = 0;
/ T. _2 ]- n; q8 o  }///*/

1 S" E' G: G' B  Pen.DeleteObject();5 u6 h0 B" ^6 _+ i$ Z
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));2 k7 J, ^) |+ Q! h. k6 @+ `. k  w
    7 x5 G' f$ c9 x# H. _
  pDC->SelectObject(&Pen);
0 o; P/ y# z5 M; L6 ?* _0 }$ h  
! O2 }: H% b: n+ i' G  pDC->MoveTo(rc.left, rc.top+i);! W  K1 _! n" X6 e& O0 d
  pDC->LineTo(rc.right, rc.top+i);
9 m2 B3 [) ]2 y' A* \$ A }
pDC->SelectObject(pOldPen);
# S& H' r( x8 o& F/ y# h3 T}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
( L: D0 g# N( `/ q7 |5 ^{3 ?1 j* V( D2 V8 q
CBrush NullBrush;1 [+ ]. w% \4 [- c" h$ L
NullBrush.CreateStockObject(NULL_BRUSH);4 i& u# H2 m2 \) O1 y% Q$ f
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
" H1 `+ @6 a8 C( m; a* {5 A2 Y Pen.CreatePen(PS_SOLID, 1, FrameColor);
0 v4 J( d9 F0 O( C CPen* pOldPen = pDC->SelectObject(&Pen);. u0 e: T; k% i9 q( X9 J
2 E' ^0 Y1 [0 k* D7 T/ y; x
pDC->RoundRect(rc, CPoint(3, 3));1 V$ k5 y0 O; U" c0 p, b' u  e, H
rc.DeflateRect(1, 1, 1, 1);
6 N  ?5 E* _1 R  o. X pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);7 ~2 T3 y" H! u6 T" }
pDC->SelectObject(pOldBrush);$ T2 _/ F9 n- ]! }
}

( y/ H. a: x8 s3 o6 v( _! M/////////////////////////////////////////////////////////////////////////////, F7 }9 R" k9 W$ A
// CHsPMEDialog dialog$ g6 v$ ]. c0 _4 w: z7 i! }
//-----------------------------------------------------------------------------
' y" S3 {' D6 o/ \' W. a) |// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:+ G  M( R, [( L! t7 \; ~; A4 U& R
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级9 ~! ]- F- R& a2 b% T+ ?) ]
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口) y; K$ e0 j0 [4 m8 ?& D8 I
//   指针将其显示出来,然后隐藏或销毁自身
/ S8 ?! {$ Q- I& o! L% |# l//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
4 ?8 t- j8 g& F//    采用的方法为使用上面的CHsPMEButton作为按钮的基类9 g, c' O) E. J' b# S$ _
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,6 Z2 K2 n4 B4 Y5 I( e; E
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。: F. o& P3 Z8 a+ J1 }5 R5 P( K
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
4 N$ @+ k2 z/ L* X3 s//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框/ y! A5 t! `+ [1 c0 ]7 V, }& Y/ ?
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。
2 b* J4 j$ P  R) x//-----------------------------------------------------------------------------7 J7 K  r+ d2 i2 m$ I) O4 }
// 注意:! ?. ~% O8 U, m
// 1、在构造对话框时必须给出其父窗口指针, r7 ^: L7 @$ n7 N
// 2、在初始化基类时必须指定对话框资源模板ID
! U! p, [6 H% d3 w) \4 }- X// 3、对话框资源中必须提供ID为IDC_BACK的按钮* ^1 j6 `" T- z( c  M, _( }3 B" |
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel! v/ t, [  W" i2 V$ w: n+ Q7 y" _
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog$ s0 O+ Y* }3 [
{* R( V; F5 d( \' f9 ?0 S" R/ m% i# e
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能8 `: G6 @3 P% }+ Y, X- ?
// Construction5 b/ L4 l# S9 `
public:
6 ]6 H. x9 a- `3 Q CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
1 R) K* i8 f; h) F+ G) U; W ~CHsPMEDialog();
  E9 n- Z8 h1 k7 z8 _$ u4 j0 v( C BOOL Create(CWnd *pParent = NULL);
3 c1 c( v& F" J: r& _8 N, L3 l7 |
! H  t4 J+ O2 l+ D. K' ~// Dialog Data
& [- u( k; m  x: B$ z //{{AFX_DATA(CHsPMEDialog)3 e# X9 r/ t$ t
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };" Y. U, i, S# G! J* A
  // NOTE: the ClassWizard will add data members here9 p6 c" W# G* }- L
//}}AFX_DATA
9 P7 b0 V6 ?5 j7 y# a
// Overrides
# A( A3 K( o* o+ X: j: E$ o5 R // ClassWizard generated virtual function overrides
8 @2 z; Q5 \( i0 c9 k5 U //{{AFX_VIRTUAL(CHsPMEDialog)
4 B8 \) U3 a( a$ Y% V0 l- e0 M protected:
1 Z/ @% x# S* P2 o! K virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support4 f) j% G# {( L8 h* @
virtual void OnOK();  n% f5 Y  E1 l6 p: e( ?$ U
virtual void OnCancel();' |2 w/ G- f$ A9 u1 q
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
- ]" s; Y  h0 [) f' P# w/ m" j" o virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);  s! ]6 m2 q% [6 M
//}}AFX_VIRTUAL
// Implementation
+ Z# o" A, `# d, C2 X5 n& _5 i( D5 vprotected:
// Generated message map functions2 K- h, J) \& k# O+ g
//{{AFX_MSG(CHsPMEDialog)4 }3 }! s; e1 p' c" ~. l7 S
afx_msg void OnBack();. K% ~3 v7 J+ [" x0 b5 F
virtual BOOL OnInitDialog();
' b6 Q* Q- s0 |5 f' w! w/ e afx_msg void OnDestroy();
" g( l, P; g8 m: [$ c //}}AFX_MSG
( ?7 ^  G4 h" d6 p DECLARE_MESSAGE_MAP()
protected:
1 J% x1 @; U! k: n // attributes
8 ?6 j. J. ^9 q! G CWnd   *m_pParent;     // 父窗口指针$ P% v$ W! a8 j$ |
HICON   m_hIcon;     // 图标
5 ]" B* P3 \, `1 ?& ~( b9 } UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;5 [) a4 D, \" m  T  Z1 ?6 S; b1 R
CHsPMEButton m_btCancel;
; r- v$ X- C+ Z' a& q CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
  U0 K( E0 ~) X, [. Z HHOOK   m_hkCBT;     // CBT钩子句柄
1 U" Z" H) i+ M# W# |% O0 S+ a2 U . h9 N2 k3 s3 @& {+ M5 ^- [1 a
//-------------------------------------------------------------------------0 f- y8 @1 w- C# p) I9 z% E+ S4 {4 e. R
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
+ E- C9 ]1 p. l/ x* ` // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
! {8 j( ~+ z7 [; X1 C // 链表的头及下一个结点的指针
" o; K  j" D4 ]# x4 r static CHsPMEDialog* m_spHead;$ I% O# i5 W8 i9 w
CHsPMEDialog *m_pNext;
// operations  ?1 d: [" v0 h
// 键盘钩子消息的处理函数
+ e2 k! N9 U! B" B! f! T static LRESULT CALLBACK KeyboardProc(
$ O# E8 |" q3 g  r/ R: o( X- U  int code,       // hook code
) H5 i& ^4 q# {  B+ s5 U$ ~  WPARAM wParam,  // virtual-key code
+ ^. u0 B* W& E  LPARAM lParam   // keystroke-message information* o+ d# ?) L/ I/ @* h/ `9 e
  );
/ w: p8 n% O9 t9 \* g; [& P, M // CBT钩子消息处理函数
' q" k- }  A* l# L' B& k9 C static LRESULT CALLBACK CBTProc(
. N9 w% p  X6 Q9 D+ Q' Z" M' e$ f) M3 A  int nCode,      // hook code3 k0 n5 |: W/ A) _( R! ]2 @$ D- i: ?
  WPARAM wParam,  // depends on hook code5 e4 w) ]& t" \  W& N" e
  LPARAM lParam   // depends on hook code
2 r% Z- l1 U7 U# \. G/ T  );6 t+ L( z7 @5 Q  Q6 N9 s) H
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口8 F8 H  G$ u' Z. e# J
static BOOL  IsWndKindOfThis(HWND hWnd);' U5 h# |9 Z& E' y" c
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
2 I; E1 x: K  T& q( u static HMODULE ModuleFromAddress(PVOID pv);, |1 M7 i" J/ ?" \& }0 w
public:
% D8 ~, |8 Y7 o7 V' @ // attributes
// operations& f& C" I: g. |  R5 N
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框
3 B* t, x) A& O9 e# ` BOOL CreateChildDialog(CHsPMEDialog *pChild);0 d' c- F: I( |: j" Z
};
: G1 D6 X8 i* d7 {- p6 ]! l+ M
CHsPMEDialog* g_pHsPMEDlg = NULL;; h# f1 G& Y1 J7 d
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
( J/ @! Q& V% m: G+ I0 aHHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)8 O2 Q! Z: B. k+ m+ ^1 i5 C: [
: CDialog(nIDTemplate, pParent)
. D, I) ^& X# r% x4 r{& p0 j8 i9 b0 H" d9 s( {
//{{AFX_DATA_INIT(CHsPMEDialog)1 C, S8 ^( j9 f. k; t/ \
  // NOTE: the ClassWizard will add member initialization here
4 }' z% x# F! U1 y //}}AFX_DATA_INIT
7 ~: Y; ^; U8 j4 ?/ J" {6 I m_pParent = pParent;
7 K8 ]) l  o( z m_nTemplateID = nIDTemplate;3 P( A( L$ I: u  C! J' S2 U/ l5 ]5 t
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表- ?  O7 O4 t1 I4 u
m_pNext = m_spHead;
* l0 G4 [+ [; M! C" t* ^ m_spHead = this;# r+ ]0 D6 J6 g! B. S4 T/ j
m_hkCBT = NULL;+ d. x( J3 ]8 ^+ m" \5 {' o; J$ D
}
CHsPMEDialog::~CHsPMEDialog()
5 y# P: c" k  T" T7 ^{
7 ^6 ?+ {$ k2 _; \8 g7 t* h7 N/ V6 I$ f) f // 从链表中删除本结点
* V. o% }! w& {% c CHsPMEDialog *pTemp = m_spHead;# B( Z5 v) _* D6 P% |. K; w
if(pTemp == this)9 J/ f2 I  r9 l8 N
{
" f! ^0 K- Z) T) t* M+ C( L  m_spHead = pTemp->m_pNext;) H$ }$ w& h1 k/ A) \6 f7 u
}
* v( T8 h( }$ J0 W! h9 h/ ]1 K else2 r% U  c" z! A
{, H$ d0 E: f+ k3 V
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)1 ]9 L4 C6 P( _& F
  {
$ ^, `7 Y# j* u5 K+ G5 d* s9 y   if(pTemp->m_pNext == this); K2 ?5 P, I( n( @6 M( e1 s
   {$ C$ g* T3 a7 f& \) E+ \
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;, J4 ^4 t5 i5 |' \  S9 O
    break;
4 o+ N) i# G* g   }6 F! b1 ?  r3 G) z
  }$ m  f! }4 h1 i3 B) u
}
+ J  t( O7 p2 ~7 z* T# l}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
7 m5 R/ F, M, N* g( [3 d{8 h# P" P" W) Q8 f* I
CDialog::DoDataExchange(pDX);
2 e* K* a! a. f1 Y% U/ J //{{AFX_DATA_MAP(CHsPMEDialog)
7 q2 |/ i& a* I; k  ]$ V DDX_Control(pDX, IDOK, m_btOK);
# r. w" j) q6 x  S: [- i1 ?% T DDX_Control(pDX, IDCANCEL, m_btCancel);: h( ^( b9 l! Y4 x2 w
DDX_Control(pDX, IDC_BACK, m_btBack);/ }( ?# O' |! Y5 {
//}}AFX_DATA_MAP
% L5 ?+ K- r9 H}

' `" c! U& s# d, @8 c" S) ?- iBEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)" }7 \/ F- M+ C' s+ r  L
//{{AFX_MSG_MAP(CHsPMEDialog)# m$ {: m/ K- Y% f; l: ?
ON_BN_CLICKED(IDC_BACK, OnBack)
. L+ P% c0 k, C% v, n! A8 E  l" ` ON_WM_DESTROY()
4 G# s1 a3 }8 N. I7 s) N- ~ //}}AFX_MSG_MAP
4 [- t, ^! D1 R; S2 \, _END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
+ Z% F8 Y$ v* M) q1 f0 Z// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
' x4 N- e( Q4 G$ r; U: a6 X$ l" y{
$ n4 n. {, G9 o! p8 U m_pParent = pParent;; Z  F9 [6 q& b, ?' |6 W# K  y
return CDialog::Create(m_nTemplateID, pParent);
# ^3 J+ `7 r2 w6 @. ?7 s}

2 A/ c2 W2 ~, FBOOL CHsPMEDialog::OnInitDialog() 6 P7 t  O5 z2 ~' }* L
{
, U( Q: E. d5 X3 \ CDialog::OnInitDialog();
// 设置标题栏图标
: S% y2 k; Y) {' I8 x& u SetIcon(m_hIcon, TRUE);
( }( v6 d5 g8 [: I2 K4 a# P SetIcon(m_hIcon, FALSE);! S$ d& @# {1 x: h8 j/ M

3 K$ P+ y0 g: ` // UG的对话框的几个标准按钮没有TAPSTOP
- J- I0 D6 q, E- P  M, [ CWnd *pWnd = NULL;
4 I% t" ^, o7 s pWnd = GetDlgItem(IDOK);) V6 ]" s; f7 x- h
if(pWnd)# v) |  k& I6 R7 J3 G7 H
{* F2 G5 z; s2 R0 q
  pWnd->ModifyStyle(WS_TABSTOP, 0);9 E, a' R+ X0 z. c% M+ V
}
$ I8 X4 \* ~6 ^/ U# F- D/ D  m pWnd = GetDlgItem(IDC_BACK);: N. n: x8 x( l, L
if(pWnd). S' X+ N; F& q* b/ ]; C, m
{
' A1 ^) {  p' F2 P  pWnd->ModifyStyle(WS_TABSTOP, 0);. k4 G% X' R7 Q9 N( H# k% z
}
, Q1 ?3 T6 I  R pWnd = GetDlgItem(IDCANCEL);
3 K( j' O% k1 n if(pWnd)
& Q$ u9 C6 g! v& _  `; a {
: I# ]7 M+ B5 P0 {4 C5 Y  pWnd->ModifyStyle(WS_TABSTOP, 0);
9 i# O. ?# R  w( N' u3 t2 y+ U, G }0 b3 ~" ~3 X9 `. c7 }

/ p2 Y8 Q: Z4 S! g3 y" o# [ g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
- {% \9 }5 K8 ?6 P8 W if(m_hkKeyboard == NULL)  g$ d+ ?) Z) R! k" Y& W/ [; j
{# P  y3 i8 g) C: K9 v  Q
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
! K  S( Q7 [: r }
- M, u* \3 }# g1 ?9 _3 q if(m_hkKeyboard == NULL)' p# M0 Z- f7 Z. f% x" v
{' @/ [3 m4 u) o* Z/ p7 J  J
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());# W7 Y- T$ v" z- _: J( H& f
}
if(m_hkCBT == NULL)
2 m* L) H' T) B& r {
- {0 j3 q  Q) Q+ ~& K& Z  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
- j6 G, V# F0 w1 O% M/ Q4 P6 p }' R# b3 h- ?0 S% j7 J9 k; j! U8 d2 f
if(m_hkCBT == NULL)
+ J5 ~  N1 S/ O, H- L6 q9 N& d& L {
2 w) q( g4 X! E) c6 K* I# i0 o& v  TRACE("Set CBT Hook Failed: %u/n", GetLastError());
. E, w, i% {3 r, L3 F& \ }+ y; l; U6 P( H0 J

% |8 G0 P/ S/ G. `0 t8 R; | return TRUE;  // return TRUE unless you set the focus to a control+ E& g. r3 r% w1 a( {
               // EXCEPTION: OCX Property Pages should return FALSE- x4 c6 x0 M% e, n
}
void CHsPMEDialog::OnOK()
% O2 H, [3 ]8 g3 e+ c: ~{
8 ]; V7 Z$ `$ |1 N  [6 @& S CDialog::OnOK();
- a, M- B! k- W if(m_pParent)
4 V. Z, H* v0 G; T. l- v4 | {( C# [' _, @, |$ F
  //m_pParent->DestroyWindow();
& `" A& y$ A4 C+ C# O; N6 h  //((CDialog*)m_pParent)->EndDialog(IDOK);
- d( b) K( f7 m! X" X5 O- \: I7 Y6 M  ((CHsPMEDialog*)m_pParent)->OnOK();; O1 m" o) t# Y
}
) a# p, p* k2 H2 f}
void CHsPMEDialog::OnCancel()4 h; S% }. P# Z2 ~# a' f
{; ?, o! j# N  l- S
CDialog::OnCancel();
: a9 A& d0 e! p1 X/ p9 o if(m_pParent)) P  t4 O1 y# V4 L
{
+ M. L5 E* p! B  //m_pParent->DestroyWindow();
6 Z6 y' ]: W( x! O/ I  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);+ F! q" |" x1 u
  ((CHsPMEDialog*)m_pParent)->OnCancel();
4 S5 {1 R2 i  M }
8 f! }7 g/ y; v, S3 o}
void CHsPMEDialog::OnBack()/ H5 P9 A% i3 u5 a/ G
{
( h$ O& u! a9 f" M' i  V if(m_pParent)
" w: f  B& W) [6 V- x {' T7 N5 [% k( O) P1 ]* d
  m_pParent->ShowWindow(SW_SHOW);
' k& G$ V7 v8 x }
1 n# d( n& I% Z0 [( c CDialog::OnCancel();
# Y% `0 {& m, n  A9 T# V1 T" a}

5 d% y" I' h  `/ S0 P' {BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)% V9 Q! F4 @; i  B' s
{
- }& t! i" ]1 n! \$ | BOOL bRet = FALSE;
; J4 Z& K2 M7 u if(pChild->GetSafeHwnd() == NULL)
0 \0 q5 ~* `' H8 l  U6 g, U {0 k4 S, ^; b% W/ m: a1 l+ C
  bRet = pChild->Create(this);3 I; u* u0 a# n, n- b# @0 \6 `
}% B' c9 ~8 d1 S% Y% C( h" l3 N
bRet &= ShowWindow(SW_HIDE);
. z, ~' w. h' b$ \" W2 G' n& r bRet &= pChild->ShowWindow(SW_SHOW);
; u4 v; \! y1 z7 U6 X2 P: d return bRet;
; s/ _- n, b, n! O$ ~}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
  t7 L9 r! l5 P9 b' O0 j8 y{1 C. b, D3 I" A0 G
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup. c3 g7 X& D9 c9 \- @! H
{2 t' {# P1 i9 @9 z2 A
  //TRACE("Key down/n");
7 R% f6 e% I$ d: y- h" V  ~6 K  CWnd *pTopWnd = CWnd::GetActiveWindow();
  p. e* b5 n$ b# g  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))# j+ x& U4 q7 N2 w; E
  {9 m# u- L3 M1 X% h
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息9 z5 u3 W7 d+ Q! N. M
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)
3 D( O5 b9 e: e  p6 R   {
, v: E0 T9 x3 o4 v    // 只截获tab、esc及回车键# o2 J) n  J- q8 E) Z# P
    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
0 S/ N5 |5 _! v# E/ c    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
( ^5 F  _, i$ _, F& t   }8 J+ c: }: x: a. b: K1 r
   switch(wParam) {
9 j  }: ?1 u, h4 y6 f   case VK_TAB:( u( R- ]$ r+ t! y. q+ Y$ s9 M- J
    {
7 x5 v6 I% B. R8 S     CWnd *pWnd = pTopWnd->GetFocus();
6 Q2 `, }# E1 @* r$ v     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);' P& @. X! H: P' ~5 t! K
     if(pNext)
. \/ r! j" O" I% m7 b" N/ {     {
2 C$ z1 S5 b* @- S. F7 s0 Z$ w      int nCtrlID = pNext->GetDlgCtrlID();) |5 h! g+ ]) S6 ?
      //TRACE("CtrlID = %d/n", nCtrlID);7 ]4 k+ |; ?, \" j4 d/ D
      pWnd = pNext;
0 Q' F, _: O% r. `7 k      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
# V2 ~) y: a* V/ `0 u) U/ t) n      {
0 u# w% x( Y, ^! Z, L. C9 ^) H5 V, T& A7 j       // 根据UG对话框的属性,这三个按钮是没有焦点的/ L! }; o& Y' H2 P
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
) a, b! _8 E7 G0 _! P8 r( x       if(!pNext || pNext == pWnd)7 A% ~9 a6 t: |- \
       {3 Z2 h9 @7 [7 D
        // 对话框上只有上述三个按钮- T; q+ \; j& K: F9 \: a! [- R
        return CallNextHookEx(NULL, code, wParam, lParam);
) G' x8 t' V( y) ^* {! ~6 f( d       }* N2 u* L8 S% |5 T( j
       nCtrlID = pNext->GetDlgCtrlID();
' S0 |( r  x' U5 G$ b& q! s       //TRACE("CtrlID = %d/n", nCtrlID);
  S# B. I* u2 y      }
5 p0 F; A( Z' x8 a      pNext->SetFocus();
7 ^" [  m5 `( F9 z4 A. z9 U3 n1 r     }6 m( W, X! z" n4 G
     //return TRUE;7 S4 x. K" S: L8 `7 r0 B$ C; ^
    }
" P2 E9 Q5 J4 P  a: d0 G- Y    break;# h: s! Z& E* d7 m: t# o) Q
   case VK_ESCAPE:
- F3 e( [9 b- f2 B* K  F; n    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
  c. j) B. p+ F    //return TRUE;  D" I# d5 e5 {( }  d
    break;9 n5 u+ j) f4 M6 E) l$ N8 M9 T
   case VK_RETURN:
. x' Q6 F+ l* I! y- m( p0 g    // UG实际上并不处理回车键7 n6 O+ O% }/ }: `# P% t
    break;
) D% }! I8 X* e7 M+ Q   default:
$ |4 B' l6 q6 g    break;+ @; O' a) o; h1 v- r$ }! I6 [
   }
6 e& O5 i7 J# p2 r# Z  }# F) F3 u% W. D1 t4 |
}+ G! C0 Y( |9 r' Z3 g
return CallNextHookEx(NULL, code, wParam, lParam);- {, A, Z  s, X1 ]
}
void CHsPMEDialog::OnDestroy()
; R! W& e- W& z8 ?3 Q0 A{1 h$ \" [/ a' {5 s% W5 p
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
' {" ]: x0 _: l' x- a if(m_hkKeyboard)
: ]9 e  _& b' Q {$ Y) D# @) X. T, L
  UnhookWindowsHookEx(m_hkKeyboard); 2 B. E4 B  z. _# n$ }
  m_hkKeyboard = NULL;
, C/ a- p, T( s! X' m }
if(m_hkCBT)
# I! k) K5 B3 L% W {
! X7 g) ]  k, z2 l! w4 w# x- o  UnhookWindowsHookEx(m_hkCBT); 2 @$ \$ `7 }; y" e! c
  m_hkCBT = NULL;
$ @$ i9 X* L: U8 T) K$ t }
) t% q- O/ Z" d}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)! ~8 _- W$ _# z$ {$ l/ G! a
{% \* P# f! t: K1 T, \; z% U. Y
CHsPMEDialog *pTemp = m_spHead;. b6 s4 e8 d1 \) k+ Q) l
BOOL bFound = FALSE;' J6 H. f% b' c2 Y3 D
for(; pTemp != NULL; pTemp = pTemp->m_pNext)/ |4 T! G! n. ?
{5 ?# v8 o$ t1 N- z* O
  if(pTemp->m_hWnd == hWnd)6 A5 T) c: Y3 p, b' p8 h  U" a2 v
  {8 v7 D3 I# [) C. c+ J2 h! W( X$ n
   bFound = TRUE;
* s! ~. Z& f* t  f6 a: V4 S   break;6 B% j/ Y  y% N4 E
  }: C* V& b! I! I# _  l6 P5 J
}
! t/ n& Y$ B& B  l' p+ k return bFound;
' z5 x* Q5 U4 m5 m- e! E8 \8 Q}
// Returns the HMODULE that contains the specified memory address7 M5 s- s: Z) R$ t" ~% L
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv) / m5 B" k( c# J6 e
{9 a- A. U1 s/ l, Q  K  Q
# }; b& m# ]6 m1 R
MEMORY_BASIC_INFORMATION mbi;
$ n& L" [' M9 }6 L return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
- S/ Y4 ]7 B1 h' p9 c6 ~9 P! X  ? (HMODULE) mbi.AllocationBase : NULL);& U5 \" T) S+ o! K) e) ~5 K. A7 `
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
* Z$ Q) _6 {2 L4 H{; p, O4 H2 m9 Z+ j' i
if(nCode == HCBT_CREATEWND)& @0 {% E/ q5 Q" O, ~
{
; ^2 R. C: Q3 H8 T8 O  //TRACE("A Window is being created/n");
# O5 f, J3 B8 X: R, {  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;
. y3 n5 p3 q, `( ^  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);6 R  {4 l" N3 p! d/ }4 `1 v
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))3 x$ u6 S8 K  e! K
  {- `& D* I7 y! F7 A- s7 e
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
: E* x) R) |" e7 S8 k% {   // 取得窗口处理过程内存地址3 u6 V, q( ?( V8 B$ X
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
: `/ v4 B8 z. P  L& H# N   if(dwUserData)8 \' P8 H) K4 \5 O. r
   {% f' ^7 H7 u5 C4 {. h! H
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
0 f6 g( e6 f3 a( \* D    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};8 O) b! \. [% N1 `% Y) k1 `7 D: m
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
# L4 {" o! }: a& i& O    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);: {7 M9 Q3 ~/ _
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
  _: E! O0 N* \% K- I+ H    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
7 d- W+ d# Q2 N: T* O0 t. `  _    if(stricmp(szUGPath, szModulePath) == 0)
1 W; F. l6 ^9 w, y# n2 c7 L    {& ~" B2 O2 ]( @- q# N3 u0 {
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)# ]1 R0 f# i' p% j& T
     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)# [5 L1 t5 b) E' T: p8 \* E( v
     {
1 |6 p  i. l6 g0 `1 \& ~      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
' G) E$ f$ a1 H6 t* N0 ?6 o; ?4 j# [      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && $ M9 @6 {' r) P) }4 F3 X
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
( Q' r4 f" W0 ]# f      {
+ L4 E: l0 i& M4 U5 Y7 q( _       // 窗口非本窗口或其子窗口
; n) r% d- A3 ~8 W3 f1 L       g_pHsPMEDlg->OnCancel();* p& K* L( T. [4 b# f; {, r  @
      }! R8 Z! ^+ t9 W9 v5 Q" p) }
     }
# s% n7 e" }% _  N    }
9 Z; [7 I$ [- r. t5 P/ F   }
+ z9 t& p) G" d3 p  U8 A  }9 _9 `- W& _2 H$ z1 F" [. C
}
( _! ^+ A, S! e# H: ~' C return CallNextHookEx(NULL, nCode, wParam, lParam);) h% b: c" a) y
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) . y/ M: P  J6 E- p' x
{$ T/ H+ R9 Y& u" R; U
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来- @% ]8 m7 }$ C+ ^
/ W7 q7 m  W# G& c) j& f1 ^9 D1 c
return CDialog::WindowProc(message, wParam, lParam);
0 a) R# R1 C- \9 X9 X}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) % G7 T% `: F/ `' b, m7 g' `" [
{
6 P+ L; @- d- K* V
) o6 e2 P7 \+ \8 _8 Y return CDialog::DefWindowProc(message, wParam, lParam);
$ U; {" P& Z/ |! C$ r}

; ^# u1 D! \0 _( l1 H7 W+ E; e3 O
上海点团信息科技有限公司,承接UG NX,CATIA,CREO,Solidworks 等CAx软件,Teamcenter,3D Experience等PLM软件,工业4.0数字化软件的实施\二次开发\培训相关业务,详情QQ 939801026 Tel 18301858168 网址 www.diantuankj.com/ doTeam.tech
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 注册

返回列表 本版积分规则

  • 发布新帖

  • 在线客服

  • 微信

  • 客户端

  • 返回顶部

  • x
    温馨提示

    本网站(plmhome.com)为PLM之家工业软件学习官网站

    展示的视频材料全部免费,需要高清和特殊技术支持请联系 QQ: 939801026

    PLM之家NX CAM二次开发专题模块培训报名开始啦

    我知道了