PLM之家精品课程培训,联系电话:18301858168 QQ: 939801026

  • NX二次开培训

    NX二次开培训

    适合初级入门或想深入了解二次开发的工程师,本培训结合ufun,NXOpen C++,大量的实例及官方内部的开发技术对于老鸟也值得借鉴!.

    NX CAM二次开发培训报名 NX二次开发基础培训报名
  • PLM之家Catia CAA二次开发培训

    Catia二次开发培训

    Catia二次开发的市场大,这方面开发人才少,难度大。所以只要你掌握了开发,那么潜力巨大,随着时间的积累,你必将有所用武之地!

  • PLM之Teamcenter最佳学习方案

    Teamcenter培训

    用户应用基础培训,管理员基础培训,管理员高级培训,二次开发培训应有尽有,只要你感兴趣肯学习,专业多年经验大师级打造!

  • PLM之Tecnomatix制造领域培训

    Tecnomatix培训

    想了解制造领域数字化吗?想了解工厂,生产线设计吗?数字化双胞胎,工业4.0吗?我们的课程虚位以待!

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

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

[复制链接]

2017-8-31 13:24:24 2825 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------  H: ?) \3 @- |% ^' Y% M
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
* x8 h: Z" \1 t8 \+ U# q- G//    该类来自网络,稍作修改,版权归原作者所有
! W% S- e' D8 D5 c1 [1 g( e//-----------------------------------------------------------------------------0 r3 h+ g2 ~. H6 d
class CHsPMEButton : public CButton
6 [+ }( w) ]) {  ~7 s* t{( i1 D1 F9 M+ u8 l7 i7 U3 z% V' V
// Construction
) U6 ?6 b& d1 opublic:
6 Q0 O/ w! n8 a/ ~5 {5 j0 B CHsPMEButton();5 m$ g  k! O5 S' V0 q& J3 G- e

7 K) D; p9 n+ k* b // Attributes3 D0 Y9 H+ |; _2 Y! n# ?4 Y
public:
# h" Y+ o6 U. `( N0 E ' M. {+ I. k# _; N
// Operations$ S9 r8 m: W( Y8 F# g
public:9 ?  [% m. Y6 N- i
inline void SetNormalTopColor(COLORREF color)
4 y; M1 m) m/ q {
3 I: ~. m+ w+ k4 s. n  m_NormalColorTop = color;8 Y& c; x0 g4 W2 k7 O/ H# t  \
}
% B# E4 c  d3 T6 [- W inline void SetNormalBottomColor(COLORREF color)% p$ A) v* C4 c. A
{
' x/ |" Z" t) e. R! W  }  m_NormalColorBottom = color;1 x7 U: t9 V. q$ q# r0 I* f
}
& S- J) h, M0 O# t/ O4 \ inline void SetActiveTexTColor(COLORREF color)1 J: U' @* {4 |; u1 }; T6 V) k# h
{4 ], y/ f/ W* B3 c9 [5 _
  m_ActiveTextColor = color;
9 c6 f! N  B! R) @0 U }
, g" M# B8 w* M+ Q0 d. N inline void SetNormalTextColor(COLORREF color): f& L! V. ?9 R) B
{
+ y8 r/ s$ y. a, N: s% W  m_NormalTextColor = color;
% o" W* P0 g6 e  { }+ R! ]! L+ w3 [' f: @
inline void SetSelectTextColor(COLORREF color)
* |& @6 s+ ^' K9 Z; W {. G$ b, M2 ^6 s5 s- d% q
  m_SelectTextColor = color;
! g( Y3 j. p* e* V. i# \ }/ O' Z, E8 k% t; o% ~
inline void SetFrameColor(COLORREF color). N7 u, A  J) e2 x3 S
{
5 N2 n) E! O* R' B! B  m_FrameColor = color;7 _; E" Q, r: X! }" q5 K
}' L* c9 _7 }; j  f7 ]
inline void SetActiveColor(COLORREF color)/ h: `3 t' k: f1 d; G. {4 s
{
0 A9 r+ M- o# [6 \# i4 }  m_ActiveColor = color;: d3 O  w9 s: L$ l, \( ~
}; n; q5 X+ E6 f: p9 X, U
// Overrides
2 U" m& }" |+ u$ X0 [2 q // ClassWizard generated virtual function overrides+ ?* E" {, s# P. x2 o' Y' Q, B
//{{AFX_VIRTUAL(CHsPMEButton)
& R* |: L6 d# n$ [! m6 Kprotected:
$ _5 Q/ z/ f" c: e) s) s* n virtual void PreSubclassWindow();4 e: _( G) X% o% d( K' _
//}}AFX_VIRTUAL  t5 W: _+ f5 |$ U7 ^4 ?' m
# X  ]0 ]6 f) K; [: l, H4 p. ]
// Implementation
* b4 Z  y* i1 L1 S4 N5 @public:
' m4 }6 P: I. b4 U4 Z6 r# e4 m virtual ~CHsPMEButton();9 Z$ Z, m4 s- c3 |4 a

' R) L( n8 m8 L4 T' _( a" p7 E // Generated message map functions+ E5 I, H6 Y: X- X( T
protected:2 l) [0 B: c/ D6 Q! w
//{{AFX_MSG(CHsPMEButton)  r6 X4 H* V) M1 |: y, K/ L( {
afx_msg void OnMouseMove(UINT nFlags, CPoint point);  x4 r  |$ p5 r9 G& A
//}}AFX_MSG
! F( u5 @2 l1 W
2 e1 V* t. a2 f4 Z) q' v2 }8 h void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
* R: Y3 R  ?0 {% t$ x: R void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);7 c: `" I; y3 a
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );8 h9 S& h* G! Q! C
LONG OnMouseLeave(WPARAM, LPARAM);+ R6 h! B3 `4 V2 J- N
BOOL m_bIsMouseMove;
9 ^3 \/ n8 C3 {+ n9 @
' j1 F& d" H: \ COLORREF m_FrameColor;* B! r0 D+ l/ c% d
COLORREF m_ActiveColor;
. c" @7 A; A! O4 ^& w9 c
! ^4 d, p2 K8 f5 a+ T! m COLORREF m_ActiveTextColor;' v5 e+ X' P* o" C/ A0 \9 i
COLORREF m_NormalTextColor;' t0 E* ~  n7 B" G+ T5 Q
COLORREF m_SelectTextColor;
' u6 f, g% e' _ / r" c- i% r7 T5 [% n' d
COLORREF m_FrameHeight;
+ w7 v4 p! n7 x. w' M, j COLORREF m_FrameShadow;* E) j! a2 ?) N: O

+ c1 x7 |8 B% V9 n COLORREF m_NormalColorTop;
% H- \2 A. w; f2 N2 R9 d# g COLORREF m_NormalColorBottom;
0 j$ v" v0 U- K' F( T* L 3 k! Z$ r; K7 |4 q5 L3 ~& c
DECLARE_MESSAGE_MAP()
/ w- l5 {# k. S& k: G. {5 F};
/////////////////////////////////////////////////////////////////////////////: T7 |  i$ `( {8 I4 H" n
// CHsPMEButton
CHsPMEButton::CHsPMEButton()
! [3 y1 t% \( d$ L; N" o{; b2 F5 @: K5 Q* U
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
  z# D0 P: b0 S4 l- ?+ H m_SelectTextColor = RGB(0, 0, 0);
0 q8 L2 e' E" A& T m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);% |4 e9 u- l/ y5 h! ~/ ^% ?
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
/ m( n4 h; K  G, P! `/ T2 x- u m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
: Q" l! p# Q1 E% s$ D m_FrameHeight  = RGB(230, 230, 230);  e! c4 @( z, o9 @, O7 x
m_FrameShadow  = RGB(128, 128, 128);+ U. o' z; r8 {  L
}
CHsPMEButton::~CHsPMEButton()
* r( k4 {2 G& V# t{, n+ U7 m' n2 a" D/ U/ I5 O
}
! W9 [: Y3 G; \2 |8 N! Q( y6 K
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
. e$ {' e5 S  X1 ? //{{AFX_MSG_MAP(CHsPMEButton); {* Z9 c0 k3 w; y. f0 z4 N
ON_WM_MOUSEMOVE()
. S5 ~9 a1 J1 A" K* y //}}AFX_MSG_MAP, x! c, e. f+ B3 \, F
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
# [  V2 ]% B) E- A# W% pEND_MESSAGE_MAP()
////////////////////////////////////////////////////////////////////////////// n* L4 N, v+ {% t6 P
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
) m: x1 T0 t) z# Y5 S; a3 l" R! y{
+ b: Q% w- ^* F8 m' w/ R //*
' ~$ M8 C% s- r" i* M8 z! w CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);3 T+ q( F/ g) m" F# q# z/ H
DWORD nState  = lpDrawItemStruct->itemState;
& H( {% {+ _# O9 }, X# q1 R( K DWORD nAction = lpDrawItemStruct->itemAction; 9 @% |3 E: q2 R$ b
CRect rc   = lpDrawItemStruct->rcItem;1 S* M4 Z5 R/ M# U4 k6 N5 {' t8 w
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);9 Y) ?: J0 s# M1 y3 g2 V
CString strText;
) c& P, w& K1 N( H: g! \1 e6 i GetWindowText(strText);
if( nState & ODS_SELECTED )
6 J* Y6 c3 N! i/ S$ A% y {9 G7 o* R+ h" A, d
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);3 K# g( H) l& v' w. Y
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
9 [+ b; z# v4 D- s  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
# k  z; v/ v! R- ]# m- N }4 Q8 F2 v$ h8 U$ J/ B- o+ o
else //Normal
3 C& k9 h" W3 h+ ` {
# _. [0 g& a$ Z$ m" L; y  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);! p) y0 [+ L& ^; m! x" B
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
7 M  f4 c9 I0 T }
if( m_bIsMouseMove )
6 V" e( b; g3 W {% l: Z! \  V3 j( Y
  CRect rc2(rc);, P' Q) q% N" I$ g5 P/ J% `- j
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
9 m9 X7 D/ \4 q   m_ActiveColor, rc, rc, pDC);5 e* g. D0 D2 @
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
% a+ D( D% m5 M& f) R6 D8 T  NullBrush.CreateStockObject(NULL_BRUSH);+ R& e% P& ^  Q7 x
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
" d/ U& L. R% {! P5 v  & k- l; O3 i! V2 m8 k
  CPen Pen;# u" I, v) D4 l0 r  V, {1 }
  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);( R8 T4 Z* T; Z8 X
  CPen* pOldPen = pDC->SelectObject(&Pen);6 I! y& ~* |+ w  ]
  rc.InflateRect(1,1,1,1);
9 |) f. [6 R, ~3 ?  pDC->RoundRect(rc, CPoint(3, 3));0 |& D! N! T4 M: [# s2 e& P; n# d
  //rc.DeflateRect(1, 1, 1, 1); * M' z' f- {" }+ w
  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);; v, K2 K; _! U
  
# B2 c" e6 m) ~; y! a6 c- Q5 K  pDC->SelectObject(pOldPen);9 P. Q8 a) R# R( L4 t
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);" s  O; t! q0 \* {7 S0 y$ D2 i
}
! U( w) |4 d' {: ]1 F+ I + [, }, O, x% v5 W6 H+ j
pDC->DrawText(strText, strText.GetLength(), 1 \8 h  t# U! ?6 R
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
  E8 C  k4 K1 t' _6 v4 v( { //*///
% O# E; F6 c( I" Q. j4 G. N0 h0 ?}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) ) Y! `) y# o; I
{
0 {2 C# }2 ^+ S) |! ~" P // TODO: Add your message handler code here and/or call default7 L+ G3 M/ I+ G. s1 q" `' D
if( m_bIsMouseMove == 0 )' w9 H/ ]0 t" J$ V# _
{
  Z4 |: A' Y5 t- D* N0 F9 \  m_bIsMouseMove = 1;
/ Z1 E5 |; J; S) H( u7 g0 G% q) H9 u  Invalidate();
! U7 \8 k' Q, c& S# Q4 l- p) k# x6 f  ( Y9 W7 T; L/ F
  TRACKMOUSEEVENT trackmouseevent;. E' S- d7 V0 l; q/ W: e4 a+ B
  trackmouseevent.cbSize = sizeof(trackmouseevent);
5 C  p; x, a3 U: s: |4 t3 V  trackmouseevent.dwFlags = TME_LEAVE;
: ?# c( v9 \' k! A2 {+ ]* X  trackmouseevent.hwndTrack = GetSafeHwnd();  v6 @# m4 t$ t0 ?
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;- j# d' d1 b$ k1 E' f' A3 c
  _TrackMouseEvent(&trackmouseevent);3 P. C' c/ I5 X* [& k6 D
}
6 [2 ~8 G' U' }% q! q0 n
# R7 ?' h, v5 ?' Q! |7 k1 g0 q0 v CButton::OnMouseMove(nFlags, point);
8 ~0 I+ G2 [& N9 w3 V" H$ d+ a& x}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)8 G4 l% z  Y, `3 j6 }0 H7 ^
{* \! |2 o' P! e( l9 c9 i
m_bIsMouseMove = 0;
* }; M6 d: I# ] Invalidate();
return 0;
: D. ~) y4 ^) m, a; Y}
void CHsPMEButton::PreSubclassWindow() # r* k9 ~" f  }( ^" v
{
6 v% i8 \; p& ?6 w // TODO: Add your specialized code here and/or call the base class
# ?6 g# j, m; o4 M UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style' g' D, C% H2 W+ W" B6 X# E: |
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
) }7 w1 U' w4 m3 l- J$ X, ~}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
" ?0 a8 E  ]+ i5 U8 a+ p! _2 p4 i{4 f% b5 B  A$ v' R* z: U2 A
CPen Pen;
& t3 U. J7 j3 p: [! x- B% q9 `' | CPen* pOldPen = pDC->SelectObject(&Pen);2 f& z: f, c! h! ~( u9 N5 y+ ]

0 a: {! _1 I# \, Y$ { int R, G, B;
  j/ t( [' h) f: x: }# e9 `4 ]; x: ^ R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
% w! |, `+ A2 `) }+ S: a, M% p G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
( f; R% a0 Q7 f7 g* Q B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
9 ~0 h! a) B; B: F2 K' G9 ^
  s  A# \% T6 z& e$ o- o //R = R>0 ? R : -R;
/ k: p8 |1 ^1 r //G = G>0 ? G : -G;+ }2 E7 o& j" Q" \' {$ b
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
% q2 J- q2 [& L5 N. _ COLORREF ColMax = Top > Bottom ? Top : Bottom;% d& t% U2 J8 G0 Z9 p& n4 @" y& I
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)2 W2 U' U8 k6 F6 ^& |: ?' d
{
4 o# ~# \  c  [4 m$ S  ColR -= R;
! H1 V, U( x2 i4 M) |$ Y' |  ColG -= G;5 E% {& |( ~- u6 N( O; {
  ColB -= B;
  /*7 z0 m3 Z" X1 K; W
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||) G$ r/ h7 S- }- ~9 B1 ], _
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
( b4 @: l7 z) v3 I; Q! y7 d   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
* x: ^: S" j3 Y+ H) o  {
( n, A# c6 a- Y   R = G = B = 0;
, J/ e$ h" o( T0 O  E+ c2 S  }///*/

4 L. ?+ ^6 _# ~4 D, R  Pen.DeleteObject();
9 }( S% A4 j: T) s" q( w7 m, i4 k/ [  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));9 J- Y! M: l7 [" j# C
   
- G- D# e- i+ G9 K2 n9 ]  pDC->SelectObject(&Pen);/ K( v7 A* v# ?6 o
  & v5 z+ n- u, q" k7 A8 B
  pDC->MoveTo(rc.left, rc.top+i);: B$ j/ L3 M" u" N8 F
  pDC->LineTo(rc.right, rc.top+i);# C" S* [' k' |, l; a2 \* F$ i/ F
}
pDC->SelectObject(pOldPen);
. [- s5 @% n( O/ s' @* s2 i}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
# i4 T5 Z$ `, t7 R( y3 m4 O  b0 X{. T, n2 O0 ~' E
CBrush NullBrush;
) y+ C& {4 J) n  D, I+ n" a NullBrush.CreateStockObject(NULL_BRUSH);# ~$ k) ]3 h: M- u
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
- `# g: P2 r; U3 M& o, `3 Y Pen.CreatePen(PS_SOLID, 1, FrameColor);8 N( @8 ~" q& n* A8 C6 N4 L8 c; X# L4 L$ b
CPen* pOldPen = pDC->SelectObject(&Pen);
; k9 H( n( h* \7 Y* U / q6 u, e$ I8 E# _' h8 s. ^
pDC->RoundRect(rc, CPoint(3, 3));6 c4 Z' ~& D7 _& u8 e
rc.DeflateRect(1, 1, 1, 1);
) F0 R- h$ b7 D0 e* s& w/ p pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
( }% r* n: W# z9 d pDC->SelectObject(pOldBrush);8 K7 Q+ \9 S$ ~+ V" ]: X$ [$ d
}
( u) d1 a; l" p1 m! C+ N2 h
/////////////////////////////////////////////////////////////////////////////
+ b1 N9 q$ ?& t// CHsPMEDialog dialog) `7 F' c9 F, \" |. \$ [
//-----------------------------------------------------------------------------/ p4 z' N  @4 T9 I! ]$ i
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:3 @9 j$ b6 [9 \* l) D+ y" Y
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级; y& i, J+ Y# H& Y; h  e
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
1 t0 w4 z* P9 D1 @% z8 L//   指针将其显示出来,然后隐藏或销毁自身
# y0 X; x- F5 h# ], r* X" T//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
+ W- F. J  v. j9 F//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
2 R" E4 Q" P* X# E$ u  {//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
* I6 U# Z; u- K# s# x//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。, ~" [. O1 D5 Q* L
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。* ~2 B, i: W" g: J& ?
//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
  b' }& W# [3 \2 N1 U//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。- |  j5 ^2 y! ]. r+ X
//-----------------------------------------------------------------------------
* W6 W; G! H# k! V0 S// 注意:
' A5 h$ `% r# T3 u6 z// 1、在构造对话框时必须给出其父窗口指针
# t% W& r5 B; j- p0 x// 2、在初始化基类时必须指定对话框资源模板ID% V* H1 P$ ?; z8 r. x+ P" U
// 3、对话框资源中必须提供ID为IDC_BACK的按钮# T( `" t$ b& X2 f8 O
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
/ d2 \1 W; _( q, J" ?9 ?& V/ V( W//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
* b, v3 o+ @' }% m2 w- v" E+ {{, j$ j# l7 v8 R" D' j; l0 d
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能: E4 q) A# A  }; O& P
// Construction
) |, S3 t' r5 R( epublic:
+ g+ ^9 B( V  Z" c CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
, q% ^* Z* `. H ~CHsPMEDialog();& y  @8 ~: J  g- b  Z% G
BOOL Create(CWnd *pParent = NULL);
! F& r0 P# }( T4 J2 ]
4 Y3 h2 U8 Y7 ~8 S; [. p( I+ Q// Dialog Data: C' s; ~: j7 G0 j- ^% p
//{{AFX_DATA(CHsPMEDialog)
# r- s. b' X1 h$ H/ s! }: {0 r //enum { IDD = _UNKNOWN_RESOURCE_ID_ };
, V1 e& H% J, \9 b  // NOTE: the ClassWizard will add data members here- Z9 {4 j3 ^$ t0 @5 m& \
//}}AFX_DATA
( q& W) j' y# C! ]* n
// Overrides. S3 t8 G% l# L3 M6 H3 v
// ClassWizard generated virtual function overrides
5 S" N; k* `; n8 j( i //{{AFX_VIRTUAL(CHsPMEDialog)
& S$ C" p5 ~3 s* W protected:
, j$ c3 Y! ^7 b8 ^' M8 ~ virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support1 E! C2 g9 H1 r7 |+ T: n
virtual void OnOK();' H  G% Q5 N) Z
virtual void OnCancel();/ D- P) u( [: q6 K6 I+ t7 x
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);3 f2 f, b- j- u" T1 }, S4 ]
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
/ \1 }; w6 {% M" N' N% j3 q, W //}}AFX_VIRTUAL
// Implementation! a# D# M# F1 c( _
protected:
// Generated message map functions: h. s( ^3 B" [/ }/ C5 g; U; R9 X
//{{AFX_MSG(CHsPMEDialog)
* r" T! j% d; }7 a) A8 C' ~6 ] afx_msg void OnBack();  i' i9 _. K) K# V' u; x9 n
virtual BOOL OnInitDialog();1 L3 C7 }7 v: n. C0 x' g+ a4 |9 {
afx_msg void OnDestroy();% R1 B3 X* Y8 V' G
//}}AFX_MSG
1 O% @- L, C) G9 [ DECLARE_MESSAGE_MAP()
protected:
  g5 h# i3 o% [( m7 w: y; f // attributes
9 L! l+ C  ^4 a! S( v CWnd   *m_pParent;     // 父窗口指针1 Y- T/ L+ s; p0 k  m9 Y' |
HICON   m_hIcon;     // 图标, h. d9 I4 i! P7 u/ n" @7 }* w
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
2 Y) D7 K7 Y9 @5 y, k3 N4 O CHsPMEButton m_btCancel;# P7 U4 a0 J& d& z
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄' K. f3 \4 h' `1 [$ {
HHOOK   m_hkCBT;     // CBT钩子句柄/ K* T/ j5 Y# M. S

' p( r# C; ~) X& F, W //-------------------------------------------------------------------------
  Q7 m/ i" b, b: a/ i( P0 X5 N // 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
$ ^- v* h. q- t5 g0 y: h) b( E // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为2 l; c( w1 m! |% ~
// 链表的头及下一个结点的指针( t( n5 K0 E" s8 g
static CHsPMEDialog* m_spHead;
3 J4 J( _9 ]; ~1 H+ i/ R4 S& ~ CHsPMEDialog *m_pNext;
// operations
& x- s+ ^6 M) B9 v( @0 W0 } // 键盘钩子消息的处理函数8 @" g2 A% X- r2 ~0 n' Z$ k
static LRESULT CALLBACK KeyboardProc(0 [  H9 V: e4 @7 o
  int code,       // hook code  }: _- p7 U) Q7 ^
  WPARAM wParam,  // virtual-key code
/ p2 N) D8 Z2 B& f9 x! w) T  LPARAM lParam   // keystroke-message information9 p8 ~% U  @" Y" a, T- Q) Z" W
  );- C' T' I: r+ O% s) C0 V& k
// CBT钩子消息处理函数
# l# s" h) z3 b5 W" U. a$ V* _ static LRESULT CALLBACK CBTProc(& T8 ]- p3 }2 _5 m2 D
  int nCode,      // hook code' g7 m' T+ r8 p8 l* J5 b5 B
  WPARAM wParam,  // depends on hook code2 R9 l% c4 @2 v# A( G9 @) P" F; K
  LPARAM lParam   // depends on hook code
0 Z  P, N& a' D! u0 i  );
3 G: I6 \# a8 a. f' g9 }; A- J
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
2 X; X: m# F: H9 a/ m" j* X static BOOL  IsWndKindOfThis(HWND hWnd);- o" j' j9 @' O. f0 \
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
; U8 k" t6 j; s. Q0 {0 k4 x/ q static HMODULE ModuleFromAddress(PVOID pv);8 d) I8 N% g( _0 b0 g, W- h
public:
/ n0 r6 r: L( b // attributes
// operations: d" N" C$ [3 \6 U) d% S+ ^: x
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框
1 n. p) ?- w( Z' P* ? BOOL CreateChildDialog(CHsPMEDialog *pChild);; r- J6 S8 N7 U9 @% d! {
};

/ a0 v! D. j6 ]6 Z1 ^) Z6 @CHsPMEDialog* g_pHsPMEDlg = NULL;4 y0 J4 h  h. D# j; C
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
4 T- \1 d" b1 b  w4 v% o. p# lHHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
+ g6 G3 R' M; ?/ v. A : CDialog(nIDTemplate, pParent)
* m2 g) A8 O  y& y' l{4 }0 `. |* n+ r$ a; N( Y
//{{AFX_DATA_INIT(CHsPMEDialog)/ W) ]/ L/ `5 M- b( U: w
  // NOTE: the ClassWizard will add member initialization here- f( J, y! }2 P) ^9 ~- Z
//}}AFX_DATA_INIT5 }* A& K3 y! ^- ^  ^- V8 g
m_pParent = pParent;8 X" ?! V& _, F/ `( ]/ A( B( Q
m_nTemplateID = nIDTemplate;9 a6 w8 a# r$ ?! o9 ?) }
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
* x0 p; s( X$ r2 ~, y m_pNext = m_spHead;: N' p! U' K* r7 ?- t6 [
m_spHead = this;
0 F5 [' U& S2 @4 e m_hkCBT = NULL;# S2 K: @# w) c# Y2 E
}
CHsPMEDialog::~CHsPMEDialog()
) b4 [' K+ l+ U7 ?+ V{
$ F# W9 O7 L/ i# j% Y // 从链表中删除本结点
6 x8 N3 {% f/ ~. ^  h6 V( g CHsPMEDialog *pTemp = m_spHead;  ^- ?0 A# b: k7 [  ~1 w5 y
if(pTemp == this)4 D$ D, d! ?/ @% ?6 f
{# z% R7 i: ~6 E7 y$ x4 G
  m_spHead = pTemp->m_pNext;9 ^, r& L* ?% X0 w
}
3 D, X9 v% [, k& w% { else2 r6 Q$ q! [0 H7 f# \
{& V8 |3 r% R1 G
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
4 J8 ~3 ]. _( \* D  {
! g9 r/ Z$ V  E* P* u   if(pTemp->m_pNext == this)
/ d$ {* ?# Y+ l   {& I  F2 c  @: W9 q( h
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
! F" w& K: x+ `. D; i; m0 F    break;
! y/ ?- Y1 {7 j6 a0 ]   }
: A- Z% H- I; ~" Y! `  }
. f7 n# E, S, m' Q# t3 y3 d$ ? }
  D2 l5 Y1 U2 S2 O; e" z}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
$ s3 F" L4 R2 n+ U8 B8 h/ W# Y{" `% K, R+ o2 R* O  y9 v6 V' h7 C
CDialog::DoDataExchange(pDX);
! }3 p0 Y+ q, I$ \: T; K! w //{{AFX_DATA_MAP(CHsPMEDialog)" S% F+ n, u1 B
DDX_Control(pDX, IDOK, m_btOK);
$ q3 U% H; U/ F/ X1 n6 e- t7 t3 a DDX_Control(pDX, IDCANCEL, m_btCancel);
. M* P$ y6 R# j/ A: c: [, H DDX_Control(pDX, IDC_BACK, m_btBack);
- t( f% h9 i  i  d$ Z* K //}}AFX_DATA_MAP
3 D/ g' c' W. u8 s2 q$ ~; l}

+ B5 q8 X6 S8 F$ _BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)2 s3 k$ }) c* i: p: u( ]+ R
//{{AFX_MSG_MAP(CHsPMEDialog)
' e; G1 h, P  B1 ^$ f5 [0 w ON_BN_CLICKED(IDC_BACK, OnBack)& }, X2 o& _, t( l, C
ON_WM_DESTROY()8 l- l, }9 M8 z/ K5 o
//}}AFX_MSG_MAP
7 w3 Q0 m% K, B; F( c, K( N) UEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////& {6 l( a3 P4 r  o- \
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)# G; L" X7 Z9 l6 ]$ V
{: }" y, }* z* F! j0 j; A
m_pParent = pParent;) m* l0 A+ t- {: |
return CDialog::Create(m_nTemplateID, pParent);/ s( G9 z% k  i& X5 i7 T
}

- R% ?! e9 ~% {; B' {; |1 iBOOL CHsPMEDialog::OnInitDialog()
9 i% T* H" U& p- M{5 h8 Q6 [6 B) q; J" n0 q
CDialog::OnInitDialog();
// 设置标题栏图标
2 }+ S2 [5 [' g3 K SetIcon(m_hIcon, TRUE);
5 e; |4 h- F9 S# V( }+ z! j, b! K SetIcon(m_hIcon, FALSE);6 G" G) V3 r3 [- a! V, K
, i% ^! s4 U; }$ D5 O; C: \
// UG的对话框的几个标准按钮没有TAPSTOP
* r2 m# Y6 e+ R( C6 y/ j8 i CWnd *pWnd = NULL;$ l5 ]: h$ z' {& W2 ]9 G
pWnd = GetDlgItem(IDOK);, c" V8 J1 G* A$ Y& Z; W# u. H
if(pWnd)
2 a7 A  C, z% _( c/ g/ O {
  u9 ?2 ]; S" u$ k& k5 b# H  pWnd->ModifyStyle(WS_TABSTOP, 0);
, ]% A8 \* V, _ }
1 ~' \4 e* h6 J2 a5 M7 E3 j* D+ H pWnd = GetDlgItem(IDC_BACK);
* g* t/ h6 p% W- O2 J' _ if(pWnd)3 c0 S5 ]+ t6 A; v/ t$ I) D
{
: w# V; l" w: H. n6 k+ r% O  pWnd->ModifyStyle(WS_TABSTOP, 0);
. ^9 m. k2 [! O. A( Y( `0 V }( w6 S2 ?& n: N5 k/ N$ h1 K
pWnd = GetDlgItem(IDCANCEL);
9 @* v3 E: J6 ^/ R  f if(pWnd)
" V9 I8 b4 A8 Y, r0 ]! d1 e {
4 j$ }' M% X& y* C7 |  pWnd->ModifyStyle(WS_TABSTOP, 0);4 a7 c6 Q: {7 V, D1 m7 m
}
3 W# J) g/ O( k, D% v! H4 z4 M 2 r1 i9 G. O. r: D
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
% w" z, M8 V" R6 h- ^" w" w5 e% Y if(m_hkKeyboard == NULL). Q9 E# B, e) s) w3 ~+ r) y
{) z$ `% i' [+ R
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
; @8 a7 M% `4 S1 o2 [! N% o }* N1 F: o& H& P
if(m_hkKeyboard == NULL)
/ V; W+ l, x0 P( g+ D3 p$ V4 U& g {
& b: }/ n& r- e  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());- H  ?( Y( T! r
}
if(m_hkCBT == NULL)
& h1 P8 W& j. _+ b4 N# U' J {! L6 R1 i; {: Z! E' k
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());5 E; \, ]9 ~6 l0 K- b. C6 `
}" k9 r$ y5 x! [8 e# e$ V
if(m_hkCBT == NULL)
3 ?. D+ q$ q* d, @ {
; L6 N( Z* _( m# R  TRACE("Set CBT Hook Failed: %u/n", GetLastError());: S: A$ K2 v' _' W) C- u
}
3 \1 g) ]% B. S3 G 8 z* M; O6 k  x# k! j
return TRUE;  // return TRUE unless you set the focus to a control$ g  w7 y2 o+ Y2 L
               // EXCEPTION: OCX Property Pages should return FALSE
8 K2 l7 t) T! w4 E7 c}
void CHsPMEDialog::OnOK()' O  G& h' i4 q# B% F! j9 J$ v. f
{
" S* X5 T$ }* Q7 k% L1 e7 W. { CDialog::OnOK();
& y8 W: h& c) ?9 y0 d if(m_pParent)
$ O- C6 D) u  x& q% e {. w$ s! u* b+ W* ?2 _
  //m_pParent->DestroyWindow();
" T& E3 b2 o3 s/ |1 d  //((CDialog*)m_pParent)->EndDialog(IDOK);0 C: d1 A2 ~# E5 e4 o. U. e" ?
  ((CHsPMEDialog*)m_pParent)->OnOK();
: f  H: p, Y6 Q7 d; w0 F9 c }
; R" |' V, F& y& [) T}
void CHsPMEDialog::OnCancel()/ d# B1 l5 S8 Q4 A8 d
{
3 b7 l5 b) d1 ~ CDialog::OnCancel();! X& u% T( x/ |7 m& z$ i$ ?
if(m_pParent)
% B1 u, @( Q  A3 o' O, _ {& t% s6 V3 `" }+ y! G+ h; z
  //m_pParent->DestroyWindow();
/ v4 S! b/ b( }  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);2 `/ }1 K: d4 W  |0 P7 R, ]
  ((CHsPMEDialog*)m_pParent)->OnCancel();$ U% k" |2 K2 ?. Y; U& K$ B8 @2 O
}
6 U. I& ^! G& l0 q. T}
void CHsPMEDialog::OnBack()) y/ h  Z/ @. O/ a% @
{
! w, Y- ]( s( R' i" K  k& H/ M8 C if(m_pParent)& y% P0 I* V$ ?7 ?" C7 g/ t: }
{
- P5 A3 M- `- b5 N  m_pParent->ShowWindow(SW_SHOW);! c* Y. r2 a1 _8 |& i/ _8 H+ `8 v
}- X3 L0 B& G! o  W' i5 y
CDialog::OnCancel();
6 J& U$ f  e( b1 n9 L) @, y/ f% N}
) g1 d$ P4 h3 i$ a
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)5 `) O7 ^: T  c
{2 Q5 T. k7 S( k" K+ O
BOOL bRet = FALSE;
) j: |; e* x3 P if(pChild->GetSafeHwnd() == NULL)
7 f6 _5 b5 d: E  b" q, N2 B {
  I& T7 f- t. D. Q$ R5 p8 P  bRet = pChild->Create(this);: Q/ s8 ~$ w$ P; }3 I: g4 h
}
' Z; k. P( t, o; \ bRet &= ShowWindow(SW_HIDE);' R3 @' o: p' i1 l' E" T$ U) h: `
bRet &= pChild->ShowWindow(SW_SHOW);
& j7 V$ D- E) b9 W+ N return bRet;
! a+ D. F. b2 A) \9 @}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)  e, q4 x% i& z2 n4 w
{7 k% T: _3 D. L6 T0 r7 \
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
* K) H: r5 M4 w$ [7 R% M9 f# q {9 U, k* k  v3 K: }' [, f1 ~" B, b
  //TRACE("Key down/n");, k$ R" r5 E5 E7 I, a! E7 @3 _3 _3 B
  CWnd *pTopWnd = CWnd::GetActiveWindow();: F8 B: a7 e/ ^' W1 Z0 V! d+ E
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
2 E' c$ X- o3 q( ]  j2 R9 s0 [  {
& J! }* u9 @* o, ^   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
; h+ j; x5 v3 d% p- W   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)+ [& a& Z! }- p1 o  S- y6 P
   {
( Z" u. U; \, U7 U* g) T8 y/ B/ V    // 只截获tab、esc及回车键; ^8 E! d; R: E# N
    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
$ ]2 G3 D! o# ^( h7 r! v    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);: G) w/ P0 M5 Y; x/ s' Z# W
   }
1 x$ j0 H2 s0 j  D# q- D  v   switch(wParam) {# m8 J! w. C1 p0 H6 e+ d: c7 x
   case VK_TAB:
& c) c2 C/ D# v; ^$ |9 P. U. L0 N    {
1 {" j9 a: _. R! X4 r. D5 r8 H) S     CWnd *pWnd = pTopWnd->GetFocus();. a4 \  V% g1 n6 y
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);+ \1 S% a7 v0 ~% @: Z
     if(pNext)
6 I' e) l4 R4 W     {( r/ O* ?& R' ^: R
      int nCtrlID = pNext->GetDlgCtrlID();' e$ y) r- t- t# B6 o, W
      //TRACE("CtrlID = %d/n", nCtrlID);
/ z8 c( @: w% s6 U" a  z      pWnd = pNext;
! E( R  V1 N5 i# B2 y1 D      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
5 j% `, n  j8 l0 K! k      {
! ^3 G/ {1 F" T9 N* s+ H2 j       // 根据UG对话框的属性,这三个按钮是没有焦点的" ]* B, E+ x4 r2 @1 O  ~5 O: L
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
% b$ X' F' u5 p7 R       if(!pNext || pNext == pWnd)! W# x; \  _( F  R4 l; x! u( Y
       {# p! f/ ^( F' r+ b2 r
        // 对话框上只有上述三个按钮( I) A  T5 T" G' c% N$ K
        return CallNextHookEx(NULL, code, wParam, lParam);
  A" U' L; w# J       }& R# w. n- T9 J
       nCtrlID = pNext->GetDlgCtrlID();$ N6 _/ x! |* k
       //TRACE("CtrlID = %d/n", nCtrlID);
) B$ O( E5 W& V      }* M; b. a; e: I9 Z* M0 _8 K
      pNext->SetFocus();
, ?3 H  Z; ^* D) i     }& Z3 s: {! d5 d' N) Z( f
     //return TRUE;9 l- a$ Z5 z- q
    }
0 e8 Z0 _* P1 J9 b    break;- n2 ~+ U- o$ {; R$ K
   case VK_ESCAPE:4 j4 C9 N& |5 o
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
- ~! V" p) P0 n8 a& m% C' q$ u1 B    //return TRUE;
5 O) P' M1 z0 v  b& T; z; r    break;0 e& v- y3 w. p* n! o2 W" |; f
   case VK_RETURN:
9 K- U% y3 q; T% A9 I    // UG实际上并不处理回车键2 q1 d: q) k1 N/ x
    break;) w9 j, _' \' s& `9 U7 y
   default:
& G* t/ e  q/ k    break;
" M3 a0 `& l  s8 O4 P: \* o4 O9 W   }" q' _+ e; F1 y$ W# A
  }5 _2 _# i' G, ]8 u
}
0 E5 B$ I/ n# m3 C return CallNextHookEx(NULL, code, wParam, lParam);! L7 O; X( ?& K2 T
}
void CHsPMEDialog::OnDestroy()
$ S& v7 G! ~) R8 V7 k- _, z{
0 j; }; c" N  q0 l& F CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
$ W5 t+ P9 u# I if(m_hkKeyboard)& U1 {3 R; Y6 O0 ^9 @: E! G+ g0 k1 z. S
{
- k7 c3 q' W8 w5 `* K! u( j  UnhookWindowsHookEx(m_hkKeyboard); . Q# _9 X. H/ T
  m_hkKeyboard = NULL;% E+ |7 V! r6 G, r& K- t
}
if(m_hkCBT)2 ^: z0 u1 k% D, w) [
{1 c7 N: {! E# o% V) w" _
  UnhookWindowsHookEx(m_hkCBT); 6 C: ^" b! j. G+ _- t; F3 Q$ e
  m_hkCBT = NULL;
! p; w$ I8 O4 e* R, M9 y }0 a( v( Z; W( y2 s. R7 x
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)0 J/ v, e+ }7 f! \) C- w6 V
{8 H7 `4 Q. K) _; Y7 M
CHsPMEDialog *pTemp = m_spHead;
7 o' z! W4 ^$ b- L BOOL bFound = FALSE;
: V/ ^9 g1 m. N* I for(; pTemp != NULL; pTemp = pTemp->m_pNext)
! L7 k9 e, m# l. r {4 q( n, ?1 \6 }  l2 W: {
  if(pTemp->m_hWnd == hWnd)+ g" a5 s" h9 t3 Y  o' L
  {
1 S* y8 t7 `0 ?: c   bFound = TRUE;
% s, C' C6 a& |6 J# d8 p$ P* Y" z   break;
( d  Q( k/ b1 H1 g8 W  c  }
+ A+ Q, k2 H7 ~, }" W0 h+ g: p }
3 W$ ^/ J3 N3 R3 E. u3 R, ~ return bFound;
; K( o9 D8 _/ a' U4 \  [}
// Returns the HMODULE that contains the specified memory address
4 z1 U# _& K# ?  e, XHMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
% l6 P4 {2 e! @$ ]3 n{- W8 W# p; f) K. z6 o8 B

5 m1 o5 X3 j( A9 D( M4 u8 ?) N- l MEMORY_BASIC_INFORMATION mbi;& W( E; H8 H+ R. ?5 g, P
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) 4 t! Y* {5 t) Q, L. A
  ? (HMODULE) mbi.AllocationBase : NULL);) i. f5 g& V: [
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)* `+ K& D/ a) P; P* k
{
; Y8 @$ L& i9 K$ K if(nCode == HCBT_CREATEWND)
  O* ?/ N, p. V  _2 H2 x {
" C7 w0 S3 ~1 l7 |2 d/ U  //TRACE("A Window is being created/n");6 I7 z6 v9 d9 c8 Y2 Y, b0 R5 Q; N$ v
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;, W% [+ v$ d, }- h0 [1 T+ h
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
9 c5 T4 H4 f' n7 ^, ^/ I  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
1 _% x! |4 G# n! e4 X  {3 Z) G# e! G7 u5 Z$ K
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应, J+ Y% X/ X/ R/ G+ S5 F; s
   // 取得窗口处理过程内存地址
. d7 o% u1 M7 V5 l; \0 `   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);* `  Y2 t3 f: j% v1 |
   if(dwUserData)- G, H" y- E1 b9 w0 d/ R
   {4 o! l% e3 g1 s+ r2 c
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
# v1 `* d0 d- E) `7 n; k. a    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
2 B! t: h0 M+ f6 ]2 L% `+ p    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);: ~& ^0 P; N9 L9 D, E7 j$ s
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);/ t5 d7 p. p- |, u1 I6 I
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
! @. |4 R# L( @: m7 u2 M4 X/ H    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);  u5 @, W4 ]& N4 H
    if(stricmp(szUGPath, szModulePath) == 0)
: j2 W2 d$ p4 W$ m9 `) o* u% \    {
- l! V$ }6 X* `/ Y, ^     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类), N/ M+ l. D$ f+ N
     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)8 t7 g, W% P$ d$ }3 \
     {6 Q' Q) f/ F( p, h
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
# j' n6 O5 }6 C* g0 _. X      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && % c. Q# `- r- |% ]6 u8 u3 s
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)3 E) x! L  u; i' V& x
      {
8 }3 H# \+ O3 r, ~& A       // 窗口非本窗口或其子窗口* w$ h, Z. u, p. a. w( M/ p
       g_pHsPMEDlg->OnCancel();
' L- U- @# Y  f9 K$ d      }
; K, a1 a( P  r8 w) P$ F8 ]+ w     }
0 H; V* _1 G+ I0 ~* ]4 d. N/ q$ r    }
( H! O. n" h' i' H- M- d" ?+ W   }( M3 B: |: |% N5 q- X7 S# [' U
  }# c9 |1 p+ a  p: E; q+ t1 o2 D
}6 s; }) V* n* D9 s' E* p- t
return CallNextHookEx(NULL, nCode, wParam, lParam);
; T$ W. c% m, p' Q4 g$ y0 u9 z}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
- A8 E( b8 N/ x! [8 p2 ^. @9 C6 z{- g1 x8 D0 j( k0 K
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来8 Y% O9 w  l. [9 v7 I3 L

  D7 j, f0 d- X return CDialog::WindowProc(message, wParam, lParam);
8 `% e2 _0 ^1 A' o}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
0 `( M- {9 _& ^3 j5 }5 z{
- [! s; F9 D# c# X+ K' Z$ X% V
5 H6 H( O/ `0 L. j/ _+ C/ { return CDialog::DefWindowProc(message, wParam, lParam);
4 a! x3 E' F7 Y$ U" _4 i& g}
7 ?( ]9 C* U/ p! \. O7 C6 x' c1 c1 v
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了