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

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

[复制链接]

2017-8-31 13:24:24 3213 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
1 f/ {) b, R! p8 j) x' x& a/ `// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
3 Q8 {( y$ i' Y//    该类来自网络,稍作修改,版权归原作者所有
" j8 b- w9 E& p//-----------------------------------------------------------------------------
  t( z" y8 ]( z0 I- Q+ Sclass CHsPMEButton : public CButton
5 v0 s* d* K( F: V& g- u{
4 A* Y/ n1 c: A$ _* j // Construction
7 _% Y! f8 R+ F7 [3 |2 F# e% h1 ?public:$ o. _: U! m2 s5 d- ?# k8 B8 D. c
CHsPMEButton();2 m/ t$ {7 \" j

) ]7 m3 r/ J0 { // Attributes
7 E8 |* C$ p% j+ l+ jpublic:# W4 p1 v6 m) K# u& I

# E- T) G2 s; ]7 ^ // Operations- [! z+ v: A! Z* j' s& {
public:
) g0 ?4 ^6 N1 l; \7 I9 w0 E inline void SetNormalTopColor(COLORREF color)
! c' b7 r4 ~) R2 O" \) h" F6 v$ [ {2 b6 r3 ^+ r6 u  J
  m_NormalColorTop = color;
' t$ [) N7 m1 W }
9 K/ A" H  N( _; P8 u8 ] inline void SetNormalBottomColor(COLORREF color)
6 ~+ R+ X3 A  ?7 l, K$ V/ Y# u, R {  U- m# n5 P1 E8 H
  m_NormalColorBottom = color;
& M( @8 s# x* d; j# X }# E  z1 ?7 g7 ]* H5 s
inline void SetActiveTexTColor(COLORREF color)
' o, a& s* B9 M- x {% A" h# H" V4 p7 X- C6 l
  m_ActiveTextColor = color;
' N+ ]$ N" }# G7 z  L, R. a2 ?: C }) u( a$ Q7 I* I: s- s# g: }
inline void SetNormalTextColor(COLORREF color)
/ w" |4 G; w' [8 }0 I$ O* }$ ^ {  `% Y$ D/ W" \' a, e, z3 q& Q
  m_NormalTextColor = color;& ^+ Z3 n. T& R: l. r
}- m9 P' ?% I, ]: e: D8 \) Z" m$ }& K
inline void SetSelectTextColor(COLORREF color)" l& x' T6 l) M3 v
{
" I( Q3 X1 {' R. A! N  m_SelectTextColor = color;
. v( c& m" O% Z; k8 c; v" y/ t }- V. L$ @1 Z6 Y
inline void SetFrameColor(COLORREF color)
6 ]# [( s1 _' a, I, m+ d3 W {7 I$ R8 B: H" f* W; d8 \- s, j
  m_FrameColor = color;
+ p+ ?( x* n* ~! `; o6 U6 `, K  ^4 s }
6 n' l- O, i7 W9 c2 ?( X' n# z2 \ inline void SetActiveColor(COLORREF color)
4 o& h( d& b% {+ ? {
7 M+ f. {3 f" {* G7 m: D  m_ActiveColor = color;
1 O" T) `% l3 w' {! G  i9 R& `' d }
' i. t( u% n' l5 e- ~- r // Overrides& a, Y3 ~/ U0 \2 k5 t( p
// ClassWizard generated virtual function overrides
' v6 G$ m( Q4 I" H8 a //{{AFX_VIRTUAL(CHsPMEButton)' K) `! L" i' C: g; C- j
protected:: s0 T. H  a7 o
virtual void PreSubclassWindow();
& v( O/ u" R0 @: \  y) T- F# k: O //}}AFX_VIRTUAL
7 O9 Y9 k- m& p( e0 S9 R" V
! U0 c: Z+ B0 m1 k3 a // Implementation3 O" O. Z! ^2 A8 v! O( W
public:
. @. G) Q* e8 _" e7 f; K- y virtual ~CHsPMEButton();
- X9 ^3 @, d/ M% u  Y+ j
0 j, z0 c3 y6 }% J6 X/ f // Generated message map functions
" o* F( y1 ?4 o) eprotected:
7 M9 V, V1 q$ i" J) \- ] //{{AFX_MSG(CHsPMEButton)
1 t& Q( b4 i' b afx_msg void OnMouseMove(UINT nFlags, CPoint point);% A3 i, j7 x2 Z& H  w
//}}AFX_MSG& N- @! {& Y/ D
$ Z' s) B4 Z9 }
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);3 Q1 N4 J: V, ?9 h; T8 H6 g
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);* F5 _1 E# }7 [8 D+ u
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
( s1 i0 d+ q/ V9 y/ t6 Q LONG OnMouseLeave(WPARAM, LPARAM);
" a* M- [; t( ?( ? BOOL m_bIsMouseMove;
. L9 B5 F& y0 h, h ) _2 u8 G! L  L& u. @! i5 k# u9 i! j
COLORREF m_FrameColor;
6 V# t4 x# z$ S COLORREF m_ActiveColor;( [4 v4 g5 A/ L  B- A3 l: ^/ w; ?

" s" W6 Y% M+ h8 F( o+ \& H COLORREF m_ActiveTextColor;- H6 l4 @* p3 r$ l  J/ }& b+ J1 y
COLORREF m_NormalTextColor;- ^) W, Z* }0 I$ b5 e
COLORREF m_SelectTextColor;
( T& p) v( \" h* r2 h 2 l7 ~8 a! @. T
COLORREF m_FrameHeight;  O. ]# W0 g( G* ?
COLORREF m_FrameShadow;
" q) W& N; @5 _+ j6 i; A; c
- h4 H' W. J/ l! \ COLORREF m_NormalColorTop;+ i9 ~9 Z6 f, t: O3 K) d8 [- W
COLORREF m_NormalColorBottom;& Y; @2 c7 b3 k9 o6 ~

6 [0 S3 q2 ?' w, s4 t2 M; S: V- o DECLARE_MESSAGE_MAP(), q7 j+ }* R; A, t9 ^8 h* X
};
/////////////////////////////////////////////////////////////////////////////6 P, z# ^7 w0 C8 m7 }* N5 k3 @
// CHsPMEButton
CHsPMEButton::CHsPMEButton()
; \8 L6 c3 ]6 I) i4 I{; |. E5 `9 G: V2 p/ }
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
3 T/ k9 ?" p4 X/ L1 i m_SelectTextColor = RGB(0, 0, 0);& S* _; y8 ^$ }+ }/ {9 a- P* @
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);  ^; S% n  A# g7 G* p( f! t
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色% _& h% T7 X" K# B1 n/ y) c
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);  R8 Y, V6 B$ @# k4 o
m_FrameHeight  = RGB(230, 230, 230);
& K1 ?6 f; l! m2 | m_FrameShadow  = RGB(128, 128, 128);# }/ }  I/ B! q, j
}
CHsPMEButton::~CHsPMEButton()+ I* [  j, J. {/ V( d
{
6 ?, }! y9 p4 @0 T% F  D}
% X8 ]# r* U- g1 X$ I& C
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
2 \) ~& w$ W2 G //{{AFX_MSG_MAP(CHsPMEButton)
2 z! ?9 X2 @" S% z& {. g0 R7 H ON_WM_MOUSEMOVE()/ ~6 {6 U/ k8 @
//}}AFX_MSG_MAP- `' ^4 F+ C5 s% T% g- O
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
# k+ h1 k+ K) O* P9 LEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////2 u# }) k5 L# U
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
) I4 e# `# h' L. x{( C  o, b9 {6 ^' S4 E2 \! f
//*' ~7 B3 a' F8 M
CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
1 e+ P# ~8 R- S5 w( R: x9 h DWORD nState  = lpDrawItemStruct->itemState;
% y5 @/ T. Z/ r/ b DWORD nAction = lpDrawItemStruct->itemAction; 0 \" a2 B6 s# z/ u8 F" u& c4 d3 [( J! A
CRect rc   = lpDrawItemStruct->rcItem;
, L5 l, U" _. }. T UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);
/ g6 \  o0 }0 J0 J# \; T CString strText;
' X- Q% G2 _( C GetWindowText(strText);
if( nState & ODS_SELECTED )% e6 u% b  L; T3 a/ ?
{6 J7 ~8 n% i) @9 y; ]+ l: X
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
! L+ m" x! H1 O+ a& k  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); $ ?# N1 x' k. b' X, H4 s: F" H* @! }& q+ n
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);- }" R1 V7 h& f  q8 l% [; f3 ?
}
' K! T- l; ]( d2 M; o else //Normal
9 S" M" Y. ?8 \ {% O9 O+ e, l% J% C
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);& Z1 j6 l# @8 b, U; J8 n
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
5 o$ W& B$ O$ N: Z- R7 C6 H$ A }
if( m_bIsMouseMove )
, u, G; V/ }7 A1 Q5 p {& T  i5 b) a( x8 ^! b
  CRect rc2(rc);# w  M& p* e; s
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),$ F4 b" @$ w$ ?* h
   m_ActiveColor, rc, rc, pDC);
. {; l. _7 |6 x$ w$ g  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;+ S( ]# [) a+ i7 K8 w
  NullBrush.CreateStockObject(NULL_BRUSH);$ B) v- g$ p) \: |' D/ _, r
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
0 G. J. ^: o( n8 D' z) i  + ~4 u5 [! `) u, I3 G+ ~0 s
  CPen Pen;
  t5 A* d) t8 s: J, S- n; i  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
  p; q; ?. w: @- O! V- @  CPen* pOldPen = pDC->SelectObject(&Pen);; E& g0 [: T$ @* m
  rc.InflateRect(1,1,1,1);
3 G& [8 {5 N& Q! p+ W5 b! d3 D; T  pDC->RoundRect(rc, CPoint(3, 3));
. ~; Q/ |% G" c+ c( b, ]  //rc.DeflateRect(1, 1, 1, 1);
7 B- G6 l! X2 |8 g  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
6 j( V7 j5 ]% D1 j) @  
& l4 G. g- J, ?, U/ w+ l4 z  pDC->SelectObject(pOldPen);
9 s9 Y$ |& a. a1 ^: B  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);8 Q  \  H# G1 m
}
0 w- _; `  e( K) p$ k
1 w* \- o1 L. v0 t5 z/ ? pDC->DrawText(strText, strText.GetLength(),
! J$ h" b" `4 u" M9 f  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
& i  @0 G, h! W' C9 Z% T //*///& \* Q8 `- \4 J9 W2 c: n
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) * S. h1 f0 D  L& a/ Z3 p& a; k
{
3 Z7 z, O9 B# K# F // TODO: Add your message handler code here and/or call default
% T; z. g6 a1 C9 P8 R if( m_bIsMouseMove == 0 )
+ x7 k/ C  q' Q/ Q( t: R {9 ]. {# B5 ?. P
  m_bIsMouseMove = 1;7 J+ b6 `8 d1 X# }; f" L' X+ B
  Invalidate();
0 e6 z2 k! |& h, y+ H' K  
0 n) X# W* r" r) A( g/ X( g- `! S  TRACKMOUSEEVENT trackmouseevent;- I0 v( v/ r4 b0 _9 @7 [
  trackmouseevent.cbSize = sizeof(trackmouseevent);
9 T+ b: B% A- X/ a, o  trackmouseevent.dwFlags = TME_LEAVE;5 ?* C( h1 ^1 D! [2 O1 V
  trackmouseevent.hwndTrack = GetSafeHwnd();
! |! I2 z# u# o. p  trackmouseevent.dwHoverTime = HOVER_DEFAULT;9 x9 D& B6 u0 s* Q
  _TrackMouseEvent(&trackmouseevent);
8 b& D  g3 H9 A( h& } }! ?3 S5 r5 [0 r$ X
1 f+ m8 X, R2 p# \+ X  M' a- x  o& u
CButton::OnMouseMove(nFlags, point);' E0 |( e3 f% [
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)% q2 C6 m# P" }9 S" ?
{
5 L0 h. r, P0 {2 a0 J* B m_bIsMouseMove = 0;
8 S  j% y4 W% \ Invalidate();
return 0;8 c; e; h& W+ e4 G& o9 h
}
void CHsPMEButton::PreSubclassWindow()
1 k! C  J; \+ G1 N2 g/ L; b: d{
. h$ d2 q5 n3 o  ? // TODO: Add your specialized code here and/or call the base class
% F+ X/ t' D& P+ ^6 ~8 }/ y UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
- x% r9 N, W% Y/ u SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();! V; g5 U8 R" x" Q
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
% y& P& {5 x# P4 e{- l4 |. f! C/ N8 g, U
CPen Pen;8 f3 e7 W6 N: {# S
CPen* pOldPen = pDC->SelectObject(&Pen);
" i/ X* @: P; Y. q
6 I* F3 a$ e0 K# F: n- Q6 S int R, G, B;
) {  m+ u$ p; }+ _ R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();" z5 T. ?7 |7 n9 C$ x
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();5 _5 ?0 T- v/ ^
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();* f' m5 |; T; W
4 {- f/ [% a/ U% x) L* K
//R = R>0 ? R : -R;& Z# I, B2 L( `5 j, a% `8 H0 m9 c
//G = G>0 ? G : -G;
9 R& a# N" O+ F# p5 W  _ //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
% H& U$ Z/ M" J. w+ y1 X/ a COLORREF ColMax = Top > Bottom ? Top : Bottom;
0 N& c2 {& W4 F COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
% d/ v  J. I5 Y) \# ? {
# [& {: p5 Q$ \$ i  ~% w) J  ColR -= R;
0 R; ~+ _/ l0 m* ^+ U* _# o  ColG -= G;6 x, O# B2 I2 D  R3 V3 Z3 Q
  ColB -= B;
  /*$ l' L, t3 k# x5 t
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
1 B5 l2 W* t9 n+ G$ [' ^- `   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||9 F8 ^* i/ p* \; e" Q
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )# m# E7 ?8 G5 q& c8 R! x0 z
  {
& L' _+ V. a+ y( d; X1 T   R = G = B = 0;& V1 _! K8 ]: S2 l, P" Z6 n& y' W
  }///*/
! P( z( Q; ]; O- u; L0 w# n
  Pen.DeleteObject();
6 n1 D! ^$ i% f3 @/ ]  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
) V( n7 ^+ y) Z0 `+ t! O; U1 M9 h    ) g% A( c6 `% Z
  pDC->SelectObject(&Pen);
/ n  |2 C% ~0 g) S* a  
7 A4 h7 t, s! J' x0 c  pDC->MoveTo(rc.left, rc.top+i);
/ D' w8 T7 @8 z0 B  pDC->LineTo(rc.right, rc.top+i);
2 |$ F5 M$ n/ @7 r# d }
pDC->SelectObject(pOldPen);
3 z9 n) _( `; _4 S$ m, ~: ]}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)8 g  J7 i" s) ]6 _
{
* O2 ?& h  u( [2 y3 _+ S1 G4 o( d" y CBrush NullBrush;
6 D! W& i6 D; f, B7 C/ P5 n NullBrush.CreateStockObject(NULL_BRUSH);
6 B. Q. |; H0 d CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;8 S1 P' \( W; ?4 v/ G+ T
Pen.CreatePen(PS_SOLID, 1, FrameColor);
( i, b9 Y/ [+ A* f CPen* pOldPen = pDC->SelectObject(&Pen);0 k# A3 @' \2 `: o

$ O" u  t9 Z- V) `2 e pDC->RoundRect(rc, CPoint(3, 3));
: ~' t3 N! P* i- y! N rc.DeflateRect(1, 1, 1, 1);
% l% A5 }% ^+ x! p" u pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);! c9 ~# ?' n$ C! _- I' r+ ?- O
pDC->SelectObject(pOldBrush);) u' I/ n) l7 N% N) W
}
' i) n7 D- i# I& Q# a( Q6 J6 P) B3 K
/////////////////////////////////////////////////////////////////////////////
; H* H3 `; u1 W4 ^  h2 [// CHsPMEDialog dialog
! o7 O" P+ v( |//-----------------------------------------------------------------------------, i* {+ L7 R4 s/ E3 j) E! V4 ]; r. Z
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:# o" b2 z! s- F# Y0 ?) N' ?
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
$ _3 Z+ T" I- v6 a//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
- g' l2 l! r: s, S//   指针将其显示出来,然后隐藏或销毁自身' w6 Q1 y/ l! E! A8 w: q. s
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。# M2 g" Q9 ~9 X& I' d* }+ U
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
& K7 F# ?9 E1 R//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
* k- e; D' n7 }; p) J//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
. u. p, ~8 n% W: \3 H) M//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
5 {1 j1 ?% T; k//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框. N. x. P. r) i) c
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。
6 s/ Y  ^4 i6 s0 t- s//-----------------------------------------------------------------------------1 W- s6 J# w' P8 R
// 注意:
) m4 s/ h, u: ~  ~// 1、在构造对话框时必须给出其父窗口指针( [  K. l3 F0 }" B
// 2、在初始化基类时必须指定对话框资源模板ID
5 Z9 t* ~9 W1 g( a$ u0 B$ ?// 3、对话框资源中必须提供ID为IDC_BACK的按钮
& o$ X$ g  h) H8 ?" j8 b' @% |3 o// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel4 x: J6 \' ~0 R& o& k! ?  \, W
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog" f: I+ k4 m) A* z
{/ q5 S6 @: X" q2 o4 F8 x
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
% |8 {) A/ U5 h6 f6 q// Construction
& i; s- q' C2 m- |public:# Q: }0 a4 D# e) {. Q
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor5 c+ J& K$ Y; _5 P5 x$ x
~CHsPMEDialog();
" b# W# q- n, }( v( y' P4 l BOOL Create(CWnd *pParent = NULL);$ x& q6 q  L9 a% b" L! b  |

7 o' c3 c$ s# E8 G// Dialog Data
4 `+ m5 O! `8 ?1 \ //{{AFX_DATA(CHsPMEDialog)6 @" s- u2 o/ s8 P) k5 Y  }
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };3 s( C" y4 V2 _# h. j
  // NOTE: the ClassWizard will add data members here& X, ?9 J( M  X4 ?% e
//}}AFX_DATA

, Z; A: T9 u1 x// Overrides: P1 Y) j0 d0 y$ N# Y
// ClassWizard generated virtual function overrides. f* X: |: U: I% V7 Q) i+ ?
//{{AFX_VIRTUAL(CHsPMEDialog)
' ~+ \$ M* O% V protected:" R) C+ l. P' [8 b% U
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support* [- \- d7 Q6 h0 B4 t+ J
virtual void OnOK();
6 K$ L! V1 y) f# W* P4 m virtual void OnCancel();5 K, z8 Z! ~! y& _  j
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);$ F2 I6 |8 h& Z2 H  l6 B
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
; O! X! }- _$ ^* E- G //}}AFX_VIRTUAL
// Implementation* X5 H. F0 f$ e- q; O
protected:
// Generated message map functions
4 }! X! s( r. ]: n& V4 @. ? //{{AFX_MSG(CHsPMEDialog)+ a/ y- _' d) q( d, f
afx_msg void OnBack();- r2 X' X9 S+ u0 t! o) ~
virtual BOOL OnInitDialog();- x( N6 ]/ C: \& j
afx_msg void OnDestroy();; i5 [, m& X2 O  x
//}}AFX_MSG2 I, A: R- k% m% P
DECLARE_MESSAGE_MAP()
protected:5 R9 l% q2 J" q) D" d
// attributes
6 n7 z: X' J+ x" n8 l, @! K/ }  F5 {- n CWnd   *m_pParent;     // 父窗口指针2 e$ G# J  i% T+ A
HICON   m_hIcon;     // 图标
: _% y, k+ _4 b. y8 ` UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;- X, S. H* ^0 [: p
CHsPMEButton m_btCancel;" c8 Z, y# T, m( k6 M
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
8 h( G) C% e; |6 }8 A HHOOK   m_hkCBT;     // CBT钩子句柄
: |# E8 l+ T$ n. }5 {
; i' O( g/ k% ?: }7 K //-------------------------------------------------------------------------
/ \3 Z% R: m- Z+ B* n // 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog/ j! o9 L/ h' d) a. x! ?
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
* h" ~- V9 N2 }) Y& L // 链表的头及下一个结点的指针$ N! b5 U5 O2 w4 ?/ R( b
static CHsPMEDialog* m_spHead;+ h- \# `& f. d
CHsPMEDialog *m_pNext;
// operations' |; W2 b8 J# a& Z4 x/ L$ h
// 键盘钩子消息的处理函数
) t: p# J, K- t) A% o static LRESULT CALLBACK KeyboardProc(/ @# T. C8 X& S$ w$ z
  int code,       // hook code
# {( t6 \+ r! f: @/ ~  WPARAM wParam,  // virtual-key code
( Q5 C# `" A9 p* _9 o  LPARAM lParam   // keystroke-message information: R5 p8 W* q! [0 T& S+ N
  );
( h* u; T( [- `1 K, |/ Q // CBT钩子消息处理函数: J6 w* O! a% P' i' f" u3 R* i* T
static LRESULT CALLBACK CBTProc(
; L4 t- d! U7 W7 \  l; G/ ]' ]% Q  int nCode,      // hook code
* K1 {+ q5 w: ], {( v  WPARAM wParam,  // depends on hook code3 u( v8 t  I: ]1 h' S
  LPARAM lParam   // depends on hook code
3 [6 g: W- s- O% L2 A, a' ~  );# c* X7 K$ l0 c5 W: {7 k0 {6 ^
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
( p! ~# v  Y3 d static BOOL  IsWndKindOfThis(HWND hWnd);
0 y5 w/ H" \" B& [ // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
. c2 k+ \3 J! a0 x1 R2 Z; I/ ? static HMODULE ModuleFromAddress(PVOID pv);
/ a( {# J+ C8 K# y. rpublic:
0 x# G, N# P' Y3 C5 J // attributes
// operations
: V% F$ @- Z! b0 t" ] // 用于模仿UG的创建一个子对话框,同时隐藏父对话框
$ m, e* B2 ~( c) N2 p9 R BOOL CreateChildDialog(CHsPMEDialog *pChild);/ _6 n: e" G1 ?" ~$ p5 i/ ^* S
};
% r- l& [7 W& U3 i! E% g* w
CHsPMEDialog* g_pHsPMEDlg = NULL;
: P3 z9 s5 B; G- ACHsPMEDialog* CHsPMEDialog::m_spHead = NULL;0 L7 e, }. A2 w1 _; q4 o9 q
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
- e& J# s/ D9 a : CDialog(nIDTemplate, pParent)% r, F5 H9 A7 |. W9 j$ e4 `+ H
{: V( M- j& N; R! A% V' g9 q) o0 I
//{{AFX_DATA_INIT(CHsPMEDialog)- q' n/ f# z4 B/ O: ]1 w; I. \
  // NOTE: the ClassWizard will add member initialization here$ O+ b3 d( Q) K5 v0 c- w  u, f
//}}AFX_DATA_INIT# Y. i8 f& O& @9 c) x
m_pParent = pParent;8 n) ^& X2 z3 O7 n" e% r
m_nTemplateID = nIDTemplate;
+ h8 y* o% b! P5 t- l: \4 Q m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
6 [7 y) H  Y  n- P2 { m_pNext = m_spHead;
7 m: ]7 i- Z7 @7 `! v& @# m' a m_spHead = this;
2 {$ G! k* u2 ?- P( Q" z m_hkCBT = NULL;2 T+ e+ M. ^9 ~" N( \: p+ |
}
CHsPMEDialog::~CHsPMEDialog()
9 f: d" e7 H- _; m{
  h. I. U  B# d. y // 从链表中删除本结点! F  b' b' j$ ]
CHsPMEDialog *pTemp = m_spHead;8 ^' X7 [$ f+ ~( t4 `9 A& F
if(pTemp == this)0 p( P# N) Y3 n# ~; k# }/ s2 k( l
{5 F, a* ^$ _+ x# x( U% _4 ]2 R
  m_spHead = pTemp->m_pNext;: A8 W" S3 v) B% u+ M$ [. P
}
! {4 {1 C) x) R& L( X else
. {  o/ m7 E5 I {
4 _8 m# g9 b6 [) @2 b0 N3 X  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)) t2 E& e& |: S# G0 {! f- Y
  {/ r6 @# J7 G3 v# c  z
   if(pTemp->m_pNext == this)
4 [( A* ?7 h7 ]- B% R  q   {
5 ?0 L3 d1 r3 j9 r# _* `" F    pTemp->m_pNext = pTemp->m_pNext->m_pNext;9 N- K7 Y1 @, T5 Z. y3 i; k
    break;
0 [6 W1 u, p9 b  R   }$ p8 }. C% N7 Y
  }# F1 |, e% T1 t  i( B* `
}5 ^# p  N) H6 p+ f4 Y
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
/ c# @+ ^2 O& R* U! W{
4 \3 [- c9 r% w  B/ }( g CDialog::DoDataExchange(pDX);
& G/ a2 A& \0 }3 `* F: _8 E //{{AFX_DATA_MAP(CHsPMEDialog)
1 w8 u% b5 v) J; [. s DDX_Control(pDX, IDOK, m_btOK);. O" \* u# p9 Y
DDX_Control(pDX, IDCANCEL, m_btCancel);
: R0 E% A% p& y$ \$ B DDX_Control(pDX, IDC_BACK, m_btBack);0 _6 A) z7 C" b. P0 ^
//}}AFX_DATA_MAP, q  Y9 [6 R' b! n7 G
}
; g5 r; R( w1 C
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)$ _# j7 }: e, N# a3 Q
//{{AFX_MSG_MAP(CHsPMEDialog)
! x+ ^8 K4 k4 g8 R1 L ON_BN_CLICKED(IDC_BACK, OnBack)
0 _% h+ S  Z* o6 l5 w' K& M ON_WM_DESTROY()
+ u. l8 Z, C1 ~% k  f //}}AFX_MSG_MAP% o1 p, N- N, p$ o# g0 o' [
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////' C. d( \7 F6 d" s: D& C$ r: {+ d
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
; o& ~( R! d" g0 T+ P9 w4 d{3 M! i  \: v; {1 b/ C
m_pParent = pParent;5 c8 a. S; z+ e
return CDialog::Create(m_nTemplateID, pParent);- l5 s, J, w. G' J1 u" l8 Z
}

# u- V6 @0 \, |0 l. }% QBOOL CHsPMEDialog::OnInitDialog()
/ p+ S+ P  |2 }  E) I5 Y9 H" C{
$ h( S4 K+ \1 Q CDialog::OnInitDialog();
// 设置标题栏图标
+ f! [6 i" F. y. d; E7 l% D SetIcon(m_hIcon, TRUE);, N# r( ?1 I( d9 S0 L, C
SetIcon(m_hIcon, FALSE);. T) I% ~. K+ V7 B9 n# `+ T1 p) u

& C# K$ h3 X* S  ]* V7 m- @5 f // UG的对话框的几个标准按钮没有TAPSTOP
$ l. e; B0 h( J3 B CWnd *pWnd = NULL;
: l1 t- f" J; X* a; G; r pWnd = GetDlgItem(IDOK);
: ?3 e7 L: ]4 j  j2 n9 L if(pWnd)' ^( T7 j- }0 C( U1 G' T8 N
{6 m0 }" a; e" m! r4 O
  pWnd->ModifyStyle(WS_TABSTOP, 0);
9 F- i' I. G% F* z/ C }
  @3 H* Z( ]+ j8 `+ B" k pWnd = GetDlgItem(IDC_BACK);
/ k3 A: ]8 @( F, L if(pWnd)' S+ I9 ~9 I3 V
{
- |! B; z% v' N6 ^  pWnd->ModifyStyle(WS_TABSTOP, 0);
* C6 c$ `- Q& A& L }7 O: U6 Z4 B$ y
pWnd = GetDlgItem(IDCANCEL);( A4 o3 t, f0 c% L2 l! d" G
if(pWnd)
- ]7 F# h; o. P: i3 O5 G {9 F: N* {$ R/ i% F  i- T
  pWnd->ModifyStyle(WS_TABSTOP, 0);
8 u! N2 Z( `6 b, y: ?0 @* w' ~" c% E }
4 |6 p( u6 r+ H) q: s6 k5 h# S
1 h( \2 Q% X9 S g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
$ @6 T: d% Q5 z, l if(m_hkKeyboard == NULL)1 G$ I5 X. T7 k8 l( S
{! Q" F2 i4 ?- Q* M
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
9 _) ]3 `6 M. `- z; t4 t }
( z0 n& K7 j  @+ G* Z/ H6 V if(m_hkKeyboard == NULL), E- }' y3 l  e, w) E! g* F0 {7 K
{
6 b" G3 j$ a, k, x9 `5 G* _3 b8 j  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());
2 `2 F, }. p4 W# I# \% M- s& \5 u }
if(m_hkCBT == NULL)
! c0 z- V5 L1 T5 i- c8 q# ? {
6 N! ^1 B* }' f6 F# I  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());1 ?9 r) H$ `; W  l
}: Y5 Z; L4 {) _6 p
if(m_hkCBT == NULL)
& c( t  k, d0 w7 B' g. ?& z  E6 U {5 o6 Q5 e6 w% D' K" g
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());+ |7 X( D* F2 P" z+ }& B6 p
}
% V% H7 R; q1 @( M& R/ [" r* C , K; y/ N" B( _5 r
return TRUE;  // return TRUE unless you set the focus to a control
7 D3 P! R! t% v# p               // EXCEPTION: OCX Property Pages should return FALSE
6 B! {% v" @/ E/ k( e}
void CHsPMEDialog::OnOK()& {  i( l9 y6 @: Q, M; ~
{
& S' p4 f# ]5 U* i! e" Q6 @ CDialog::OnOK();2 d. T6 H( L) c3 E7 Y" a7 t  T: \7 E
if(m_pParent)
# F) q" {% A: y9 s4 {+ a2 N! k# g {/ U+ v& r) \) s' u; h
  //m_pParent->DestroyWindow();
* ]7 n7 R# ^% c. W6 n1 U% a6 e6 i  //((CDialog*)m_pParent)->EndDialog(IDOK);
5 a' f; ~! ~3 G  ((CHsPMEDialog*)m_pParent)->OnOK();
  t8 w, D3 l4 w( h& \5 Q/ b }8 A" f; Z# l- {; a
}
void CHsPMEDialog::OnCancel()7 r5 p. s2 i, Q  r
{% w. U* S/ [* X1 _6 u: {, L
CDialog::OnCancel();
( S* ]- ~" i: Z1 H/ r) k if(m_pParent)
1 g% u7 i# }3 Y8 l1 \0 s6 A4 z {
* n' c$ [/ F9 Q8 b: N9 a+ v  //m_pParent->DestroyWindow();* E7 z% J0 B4 G( P
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
- V* O# z; D- v1 k  v* Z# I  ((CHsPMEDialog*)m_pParent)->OnCancel();
8 ]: }  e5 c+ C8 q }
9 x* N- f1 B& t}
void CHsPMEDialog::OnBack()/ z, C0 Q7 ~: c6 ^
{) d" W" r- g1 _
if(m_pParent)
$ E) g- g0 C! T& y! j {0 V4 T3 K+ i" b; s% p+ E
  m_pParent->ShowWindow(SW_SHOW);
. r' ]& s2 {. g }- y; l0 N; b( Z9 _; N
CDialog::OnCancel();. r4 K( {7 w, ^, ^0 Z, ~+ f
}

" K; x+ j% {! |8 K' l+ P0 o! N! QBOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
, y( q- y8 L! l* R$ B& G, \; t* [5 `{
5 x9 s% _0 t( C- A' |0 d' x. N3 K BOOL bRet = FALSE;
0 `8 X5 K/ I; \2 V( m if(pChild->GetSafeHwnd() == NULL)" {# }5 w: w- c
{
7 T) o3 R1 w2 p  ?  bRet = pChild->Create(this);. u. |3 b% o+ S: m3 r% T+ C
}
2 D7 P2 i, V: U( O; V. ?" s bRet &= ShowWindow(SW_HIDE);
" I. @( L* b7 u) K3 z) P2 Y bRet &= pChild->ShowWindow(SW_SHOW);
: N4 J$ \) v+ j' X( l return bRet;
6 q: Q7 a, N& `* Q0 `# B}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)  y0 v9 x% E" X+ n, I1 c
{; e% F# p! v4 X2 K; G
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup5 E; ~6 R$ j: q
{) a3 _6 ?) U' a, K
  //TRACE("Key down/n");
) O3 H: y- t% k' m( E  CWnd *pTopWnd = CWnd::GetActiveWindow();2 e/ \7 n+ k. M# f4 i' i! k& U% \
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))3 x9 C6 t1 e- }5 b" Y/ X' U
  {
$ w8 D  J, q2 P0 Q. c: R; ?1 J   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
" N5 E/ l: \0 I1 {% f0 w( w; v* i   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)3 N* Q; \8 J' M4 L
   {$ j$ X9 w0 b) o! V; Q% j7 e1 y9 ?
    // 只截获tab、esc及回车键
8 K+ [8 n: b: R$ K' S1 r, S    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
5 K0 A/ M9 ]: Y, O3 t& G    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);, R4 ~9 t2 Q! H
   }  E* T$ n! V4 i& t. E
   switch(wParam) {' p7 {# g% H# \/ y0 s
   case VK_TAB:3 x8 F$ |5 Z3 a( M' `
    {
9 @, f: U+ T: ]' j     CWnd *pWnd = pTopWnd->GetFocus();% r8 h( o6 D5 \' J: y1 g. L" b0 n5 l" d1 e
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);9 m5 r% T" }3 I% |( t8 @
     if(pNext)
2 H" P0 T8 Q7 V: f. U/ ~6 h     {, p8 X3 b3 ?( w8 \6 V- [4 Z
      int nCtrlID = pNext->GetDlgCtrlID();7 |0 c9 y, I  Q8 m" @) h8 l
      //TRACE("CtrlID = %d/n", nCtrlID);
/ q. M% S& D4 b( r5 n, |1 {      pWnd = pNext;
( J- q) o' L7 j) D0 E; ^/ ^      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
& j+ ?" U' B7 B2 X8 [% l      {' L% |2 z2 |5 l4 ^0 E6 b" n
       // 根据UG对话框的属性,这三个按钮是没有焦点的
1 ]" q/ m1 k8 R, b       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
5 S, V  _3 Q) P- P0 h4 x1 Y       if(!pNext || pNext == pWnd)) i& _) E  P5 T1 F+ R
       {% u4 ^) a4 T: D& l% K
        // 对话框上只有上述三个按钮
3 A7 g$ ]" v- y9 T9 A6 L3 ^5 x, K        return CallNextHookEx(NULL, code, wParam, lParam);
% u- g/ {) I8 J" s  H. [       }
( Z! O: j' w$ j' o       nCtrlID = pNext->GetDlgCtrlID();8 M2 n5 I( s; A0 j& z
       //TRACE("CtrlID = %d/n", nCtrlID);( e) D3 b( ~  N$ S9 k: ^
      }
" U8 f7 B6 |" W5 z9 S      pNext->SetFocus();
, H3 z" }! Y3 A4 y2 C' j; e; z     }
9 Y- E4 ?7 @# p9 M/ y& a8 L     //return TRUE;3 |5 w' l! n+ K; @
    }! T7 k9 l) F! B5 d; z% I' J
    break;! s( a) Y/ ?, M9 S
   case VK_ESCAPE:8 s0 i5 R" i# W$ R2 K2 i, l  p
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
) ]/ R/ b% d& e! u  {    //return TRUE;! N$ Q) S) V2 A5 ?6 t
    break;! k( I" f& t8 F( R) n4 ?/ ~
   case VK_RETURN:" Q! ~0 O( L9 X  C; B4 L+ a
    // UG实际上并不处理回车键5 J8 B* K  E5 @* F  z4 M
    break;1 X6 N4 }6 [1 S4 [
   default:
1 s) z8 `3 O) {& P- M    break;
4 e1 a" k' B4 G& N* O  S   }) W9 Z, U; C3 `6 Q+ b
  }
9 ~8 Y% o6 Y+ N* J }7 g) Z. c" z7 M
return CallNextHookEx(NULL, code, wParam, lParam);
# @& j6 B! ~5 \  C$ G}
void CHsPMEDialog::OnDestroy() 0 i+ |1 N; }2 i1 v2 d" j+ t4 F( a
{
+ y  l, U* d% K' e9 C CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
9 K! \& n6 U  ~6 f; o! E/ x2 E if(m_hkKeyboard)# n2 Z* y2 a* t) j: T
{! o0 j1 q! i/ K7 T* K% i- X
  UnhookWindowsHookEx(m_hkKeyboard);
6 O. K7 v' c( t  m_hkKeyboard = NULL;+ x( b2 y; @* e6 a. p- M
}
if(m_hkCBT)
- n2 e" }8 n( ]: y) j4 O2 K {
. ^) Y0 f$ B( r& m. v+ u; n% q1 @  UnhookWindowsHookEx(m_hkCBT); # ?/ w/ o8 }# a5 u' w" K( G
  m_hkCBT = NULL;2 [% Y3 i' _$ P) l
}
1 ?0 x  t2 a! L}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
0 |, C2 w* c5 O$ N0 `{% G: M( s- G+ J3 x. w
CHsPMEDialog *pTemp = m_spHead;- {$ `5 t6 E7 K5 |5 ]
BOOL bFound = FALSE;* \3 l! w/ a3 q8 o) a( L( e
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
9 ?0 J6 Q4 Z  T1 W. b {3 F; K; q) Y/ b& i. S
  if(pTemp->m_hWnd == hWnd)2 Y! N( P. Q  v% Q& H6 M& B/ i
  {
& @1 c4 f) q( }   bFound = TRUE;
$ `9 m1 {% W: j' H   break;. \/ m; C3 I4 W& x+ C  T
  }5 m5 h0 |2 A$ [$ f
}  e4 Y# T4 q0 [
return bFound;
" q2 F8 g" L( l# @$ f; H4 V& Q}
// Returns the HMODULE that contains the specified memory address2 q& D* d" O! ]3 h/ p! Y- }6 O% e" y2 a5 Y
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
. G6 n. t! Q( d' B3 w1 V{
; O/ A" E) T0 a8 ~8 V9 \0 G 4 m+ D5 F- S$ t8 ^
MEMORY_BASIC_INFORMATION mbi;
' B* T$ [2 N  Z2 Y$ K1 W. } return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) ; v* y" I( C0 J9 B8 ]5 |1 E" O
  ? (HMODULE) mbi.AllocationBase : NULL);4 X7 o+ u3 ^( m/ o! l) ~
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)0 m% b, m& G% ~7 N4 Z2 r5 I
{
0 }9 q1 k! o+ N if(nCode == HCBT_CREATEWND)1 z, s4 j6 v+ r4 k
{# K" }  g* e/ w" N3 R
  //TRACE("A Window is being created/n");
) S, B. m5 F) W% a7 b( i9 f  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;3 Z) |0 t" W7 R) ]9 Z4 z, H
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);! ?+ e. ^, \6 X4 z
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
( I% O8 e( V6 I5 \: N  {9 {7 ~# A' w( g) E6 m8 V
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应9 u- a9 X+ n( u: V/ w/ C
   // 取得窗口处理过程内存地址
2 ]$ y' |* d3 i5 R: L   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);' G! p- Y/ m" a, `, Y% ?# ?
   if(dwUserData)6 ~  r& k% ?% \8 p6 N0 i9 }
   {
. U; y; a8 f1 ~* @6 N    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);/ l1 [' @% }4 O  L% R+ ]& A% {( o
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};3 x6 g) }  }8 p  @# l: [# ]
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);! W' \% Q" o- C! T  n6 l5 D  K
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);3 X5 s: O8 c9 }1 J* r3 z; G( D
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);6 ]9 L/ k- f% h  @/ A; M; V
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
( a+ d* Z$ G+ s0 ~6 r8 t    if(stricmp(szUGPath, szModulePath) == 0)7 O- _- @1 v5 [+ v& y" J. ]- ?! |
    {2 w- b& q! T! x* [. C
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
- i# A; h0 p; C" c0 V+ W     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
3 z- b) s$ V* B7 E3 M5 R     {
4 d$ A2 _3 x7 X4 j8 Z      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
/ {) p( O$ n0 [9 ^      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
+ t7 d  u, f, y       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
, L$ m: y) Y& u- y2 Z) i0 D0 g  z7 W      {
7 \& K$ X0 ]( l' m% ~9 z       // 窗口非本窗口或其子窗口# p; ^% _) x/ D. o
       g_pHsPMEDlg->OnCancel();
" F: }* [+ f& V( L      }
  b! w4 g: I/ v     }. j& l; Y0 m. c1 f( y2 M
    }; Z0 {/ M7 K5 c; e9 i  s2 V
   }
* Y  A% m1 a- k  }3 o- N2 N" [( T9 S! y' p% i
}
( W6 h$ k# q% h) ]" B return CallNextHookEx(NULL, nCode, wParam, lParam);
8 {6 s5 v0 c! L; }9 u% P% A% p# h( S}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) & _* B* S2 W0 v- o3 J, A1 j6 k8 I3 b
{
6 ~. S& l3 @2 C5 [# _ // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
3 R6 k- @! R  p; B4 k9 A8 @1 g + H: Z6 N4 Q4 ~5 S. c% ~6 m! n0 i
return CDialog::WindowProc(message, wParam, lParam);1 z9 `6 ]& w7 j/ K
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 9 \! d& \1 A8 V& ]4 O/ l5 F
{
2 v; @) U* Y+ N+ x
6 }4 o' g" \9 `" e: a return CDialog::DefWindowProc(message, wParam, lParam);
  h+ w$ p3 n! U, Q}
+ }% f3 \* l9 q* N, Y
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了