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

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

[复制链接]

2017-8-31 13:24:24 3278 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------3 O& e) Z. x: D- Q& q9 C
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类9 e* p3 h4 G5 X' z; l: C& o
//    该类来自网络,稍作修改,版权归原作者所有# r% `# r3 h& X( W8 n6 R1 j( [
//-----------------------------------------------------------------------------
& P+ x9 W  |  U$ D' gclass CHsPMEButton : public CButton
- O+ v& \2 V3 ]& [2 M9 f{
, \0 D9 m, }* ]' d0 E // Construction6 P( i: _  |' c
public:0 P1 i- [& p* r0 a# L& Z+ x( A0 v
CHsPMEButton();8 C9 G, e! m6 Z' ^( E! ^6 w$ G

) B& A9 ?! x. B7 h0 |# L- g // Attributes, |7 [# C: r5 Q. ^6 o3 n- S+ b
public:6 Z/ z0 Z+ e4 n* Y% w/ @9 T/ p

8 d6 H- ~: ^9 o$ b' H) f  H // Operations
+ ]2 C. b  G3 T7 n* P& qpublic:0 U+ W1 w6 K8 X8 h' m& }( y
inline void SetNormalTopColor(COLORREF color)/ a, ]4 \* M( H4 z& f% V% ?2 Q
{* \/ ^+ R8 U+ l
  m_NormalColorTop = color;
1 g3 W- e9 I% k" \( G; A. v, A! L) `& T }& Z( U6 ?$ o4 b
inline void SetNormalBottomColor(COLORREF color)
) h, h' B( a, `" m: E3 d  {8 Y {
! d- Q: Z% D4 p  m_NormalColorBottom = color;
: }/ p. K$ J( {6 ]9 I: {9 ~ }0 k2 m/ t' @: l5 }8 Y
inline void SetActiveTexTColor(COLORREF color)
+ P" ]0 d; j7 v. @+ }( B# s {$ p' w, Q" X' {
  m_ActiveTextColor = color;% x  A% |3 Z/ J/ F; ]
}
- F/ Y8 m4 J' F2 e5 S: X inline void SetNormalTextColor(COLORREF color)
. c2 p1 Q* m- s! i. h; w {: ]5 u- Q2 S3 x: Z/ R1 U9 U6 b
  m_NormalTextColor = color;
% I" @% P. }+ C' O8 W+ z }1 B* Q; X) ?7 G8 B) s
inline void SetSelectTextColor(COLORREF color), r3 L7 y' D# u2 l
{, U, O3 s* B; r, n; n8 r! r
  m_SelectTextColor = color;8 p4 Q4 B" u9 y) y  f
}
; h8 ]! R$ e- ?/ {/ C inline void SetFrameColor(COLORREF color)' U9 j7 X) F1 G9 ]* F9 q
{
& F' r, I4 G$ l3 {9 _/ l% d  m_FrameColor = color;
( b: M1 K& [4 g* P$ B) x1 ?9 r) ` }& m3 S& H5 A( b0 a4 G4 L' w
inline void SetActiveColor(COLORREF color)4 F: d! f5 Q# _$ |3 w! @
{% o% P9 C: q1 q  i5 p- c$ _% w
  m_ActiveColor = color;
. k# k; J. C* _0 T }8 h& u. K3 q5 R0 Y; @
// Overrides$ V5 Q2 Q8 O) g# B' v3 O8 Y
// ClassWizard generated virtual function overrides& W9 C% I( T/ x- C5 u
//{{AFX_VIRTUAL(CHsPMEButton)
+ O$ h) {3 i& T1 E* Zprotected:7 ]. s4 H) ?& Z
virtual void PreSubclassWindow();6 N- h4 |! W2 R4 N0 G, C8 v; o
//}}AFX_VIRTUAL
5 W8 t# W. m+ E/ B# j1 h, G# o 0 r+ c. a- p6 ~$ W& J3 a4 {
// Implementation
- _7 b  _/ I% hpublic:% G. I4 P% q2 Y
virtual ~CHsPMEButton();
( k8 C; z3 K6 u* d, a- h. k" w + b! ?% _2 Q  y' W& N$ x2 w$ B+ q
// Generated message map functions% U- C6 {6 Y& q
protected:3 S' O3 @; a5 m  Q1 y& J  S
//{{AFX_MSG(CHsPMEButton)
- j1 m) X6 K% G. p2 U afx_msg void OnMouseMove(UINT nFlags, CPoint point);
: I; z' P: X  A0 ]8 M //}}AFX_MSG
' \# i7 r6 N( j- C: h' L " _' p7 b% @7 T9 u1 Z) ~- @0 a% `7 w1 d, v
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);$ V' U# n; F0 [" {" ?
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
' m/ W' v. i. v% O% F) x void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );% i3 C! {# A( ]1 H5 D- m( B
LONG OnMouseLeave(WPARAM, LPARAM);7 ~. y6 _; h# Z1 K, m7 Y/ e/ y
BOOL m_bIsMouseMove;: g5 }% q1 I6 M' T
) J$ h- K- o$ T2 u* F1 e: T& D
COLORREF m_FrameColor;2 q, R" q% K& ?9 Y
COLORREF m_ActiveColor;+ [5 V- k4 T7 c5 {+ H0 \0 ~

3 h( Y7 B4 x; |$ Y COLORREF m_ActiveTextColor;
9 f2 T4 p3 z( B) t$ T COLORREF m_NormalTextColor;9 v) T) {1 d5 u+ `2 f4 {
COLORREF m_SelectTextColor;
0 U  c  R2 q" C% C. J( m2 e # p+ Q2 f8 y% Y, ^
COLORREF m_FrameHeight;2 q' Y, I# ?4 m2 W9 t
COLORREF m_FrameShadow;
: R7 f9 I1 S/ d
, `7 y; e$ r; E4 y- v: t. B COLORREF m_NormalColorTop;; x) M7 \  e# W, l8 K  _  |
COLORREF m_NormalColorBottom;
  n" D. S$ z0 X  m& C2 h/ m
; j* \4 \2 B" {# Q- f. q- v DECLARE_MESSAGE_MAP()
# P' u4 l7 U' e8 J};
/////////////////////////////////////////////////////////////////////////////
& ~6 @+ V- U+ s! w// CHsPMEButton
CHsPMEButton::CHsPMEButton()
$ x# [0 N) t( t& C{
) M5 {  y0 n2 Y- Q% |6 z' r$ s m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);7 ^! b) x& e: r! G* d& j: w7 q
m_SelectTextColor = RGB(0, 0, 0);
: N$ y+ l  u$ j; ]) R: N# R/ ? m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
& y4 w0 G; P, B7 z! n) } m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色  d6 m& a# [3 q6 Z, ]
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);- F3 r9 r1 ?' w* @* e
m_FrameHeight  = RGB(230, 230, 230);3 f  U8 L4 f+ T% ~3 {
m_FrameShadow  = RGB(128, 128, 128);
7 ?5 K, I  \1 l4 T( B}
CHsPMEButton::~CHsPMEButton()
. m8 m  w' \* q4 Q{0 p. _6 S3 G# Z( r
}

) X; }& h- x2 k6 E# ]1 z/ R- ]BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
8 D$ N& B1 W; N  }, { //{{AFX_MSG_MAP(CHsPMEButton)
% I$ s4 z* |( b" Y1 | ON_WM_MOUSEMOVE()
5 T+ G! t4 u1 |/ K+ g //}}AFX_MSG_MAP! K( h' @- E- u2 a! R' G* u
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
1 ^& l$ `" I# A9 x, oEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////9 R  [6 b9 L; j7 U  b( E2 H/ t
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )) Q+ n7 |& X( _" S
{; v# y: Q& S) x5 D$ B$ A
//*. Z4 d% o/ y& u" R* K1 T
CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);- X2 S0 E& t. I: Q) p
DWORD nState  = lpDrawItemStruct->itemState;
! Y7 R0 m: `3 B* c DWORD nAction = lpDrawItemStruct->itemAction;
  B6 C! Y. E" V- p3 M CRect rc   = lpDrawItemStruct->rcItem;* K& m2 D& s) a, T4 i, f& z
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);& k! |7 o( [* `6 V, C
CString strText;4 W' d8 r- R! J" ^* c) [
GetWindowText(strText);
if( nState & ODS_SELECTED )
! m; g$ m: s: s: @% y, Z {  b6 U( x5 ^( @$ D! S/ H6 b! S
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
* m3 z6 T# N6 e3 b5 u% \0 P  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); $ _) e/ z4 q/ K0 F& U
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);, m! p4 B2 j/ Q) h2 G
}
7 z6 Q6 \( a8 Z8 W. C else //Normal% K1 e  c/ l8 }8 \) H
{
, q6 x' b! m0 }; |, R  }  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);- u2 }/ [( O) y
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);7 ^- V0 ]8 I. E" \/ c/ O( k
}
if( m_bIsMouseMove )  ]' x3 h. F1 ]+ i2 n
{) y4 i: J' O0 l
  CRect rc2(rc);
" i" `. X$ [+ R  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
1 u0 z7 D1 t0 \: u  G, S1 C5 x  y   m_ActiveColor, rc, rc, pDC);/ T6 B& v  U- X) h0 [" K1 ]. u3 p% k
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;$ _% F% v8 R5 Z! D! L& A6 d
  NullBrush.CreateStockObject(NULL_BRUSH);9 f# `9 w, W7 K0 K; P
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);5 N  ]* l* y4 s& y& y/ {
  - t2 T& k# @! l' |5 w6 M$ s  b9 O
  CPen Pen;
: E! l! U' m$ x% |2 `- O  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
  h8 e% ]) O+ O5 j4 q6 E  CPen* pOldPen = pDC->SelectObject(&Pen);
3 O8 M! u* @$ \* N+ I9 T  K+ o  rc.InflateRect(1,1,1,1);
, l4 A/ b7 h* t# d  N  pDC->RoundRect(rc, CPoint(3, 3));
2 O: Q  p9 H6 g  //rc.DeflateRect(1, 1, 1, 1);
! C5 g2 C- f" R; B  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);/ ]: H5 s* G5 |3 G! @
  
8 M" C: ^; D, G* o4 J  pDC->SelectObject(pOldPen);
3 }7 |  t+ |( l( v1 R% T  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);0 a, n& @+ n9 M. A0 N2 Q: J
}9 D8 [, N/ D% C" M0 M) J

) p! U' E+ V2 Z5 r7 R6 J pDC->DrawText(strText, strText.GetLength(), 5 W8 G/ m* B5 e. n0 D2 G
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
; k5 L1 p) k9 [) O' q$ M$ p //*///
& U6 }; M7 \2 l" H& g& A2 Q}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
: h5 d7 m+ U& P) E# s{
" ]* N7 g( `( m1 h$ F // TODO: Add your message handler code here and/or call default
3 K# W# ?. A2 q7 I, X  W* i if( m_bIsMouseMove == 0 )
( }* W/ V+ J  @$ I# I. k& x# w {% s' b. g9 I1 m2 v3 e7 M
  m_bIsMouseMove = 1;
0 o: k& y0 s0 C: x/ [. O  Invalidate();
) u  n3 n( e% R# Q. |$ ?  # q8 V" a. _( j
  TRACKMOUSEEVENT trackmouseevent;
3 J& }; b. z/ D" O& S  trackmouseevent.cbSize = sizeof(trackmouseevent);
1 u1 f) C7 U- O/ T. L" n$ I1 u/ u/ t7 O  trackmouseevent.dwFlags = TME_LEAVE;5 w% p* I- n) T, e( g
  trackmouseevent.hwndTrack = GetSafeHwnd();
. B3 B0 k0 g- `8 e  trackmouseevent.dwHoverTime = HOVER_DEFAULT;  k) ^0 Z% R# B2 h) w
  _TrackMouseEvent(&trackmouseevent);1 e/ V+ u/ q- H0 x7 H5 l3 f- ^$ f$ t  y
}* x. Z6 _4 p) [  n* d( ]& ]

4 u/ @% m! e8 Y CButton::OnMouseMove(nFlags, point);
+ b% B8 V, _' r3 l7 `$ r0 e  S2 I; p}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)+ F' Y. Y7 x- m" ?  D; c! I7 L9 k
{' v) J; k  D, r4 V1 c% p- m
m_bIsMouseMove = 0;
' x# P4 s$ Z" D! A7 [ Invalidate();
return 0;' e) _, L: h' W7 `3 |; D! R
}
void CHsPMEButton::PreSubclassWindow() 9 D1 Y9 B$ g7 o8 Z0 g, y* k5 V6 ~  Y
{) ]9 T( N3 u: _8 j( N* e
// TODO: Add your specialized code here and/or call the base class1 M6 B3 r  X. q
UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style4 r" V: M( r$ S7 E8 O2 B
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
' U2 y5 X' G3 ^. Z}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
/ Z, n) V; L* t{
% e+ N" M  w1 Q3 Q# X CPen Pen;
7 b' Z: p6 ?  o& Z8 E8 [  m CPen* pOldPen = pDC->SelectObject(&Pen);6 M" S8 \% F1 ~) n* H! o0 g
1 s6 T9 t* [7 |% ^+ |
int R, G, B;
" d9 h3 u: ~2 v  I" k& Q R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();4 M% C8 k# Z9 Y$ ?5 D' W4 H$ _( J% r
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();* u( r6 R6 ?4 @" b, }( A0 n
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
; A+ Q8 x: @4 ?; ~- W0 \ 5 e3 }' U9 f: w* o
//R = R>0 ? R : -R;1 Y8 `" y8 ^, ]; o7 g2 b
//G = G>0 ? G : -G;* E5 F7 Z8 b4 {* h- `4 @- I  N1 D
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);/ A- \  i# o, \  b- ^
COLORREF ColMax = Top > Bottom ? Top : Bottom;. F* M/ d' e, W0 J, J  D
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)# t/ t; x8 q! d. m2 Y9 p9 P; m5 v
{/ T& S! ~% q3 J5 r2 d5 E+ Z( d
  ColR -= R;
5 f6 g5 x* b* t$ b% E  ColG -= G;! e- s* R: ?6 P# P  t, H
  ColB -= B;
  /*
$ B+ S, B: F" M1 l5 b3 ]0 W  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
9 y# A6 e- ?  r$ y   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||5 Z) G$ I* z! G, ?8 `1 W
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )9 h. g) L; @0 e& {
  {
/ j/ A: I1 r0 }9 a4 E1 B   R = G = B = 0;
8 Z$ H, U6 z- l) L: @1 S0 _  }///*/

4 c6 z  c: m2 g- Z( G  Pen.DeleteObject();
7 j- M2 i4 R( C! S0 C  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));, e) `( p+ v: |; g$ m3 i; `
    8 ^' _' C) b; e
  pDC->SelectObject(&Pen);
# s$ H) n& k  A7 Z  3 b3 g% `4 k, @$ d9 f( o
  pDC->MoveTo(rc.left, rc.top+i);. U- M  \1 u- G: o$ C+ n
  pDC->LineTo(rc.right, rc.top+i);
3 q# e4 r8 X) D( x' M* L- W* }0 ?& A0 k }
pDC->SelectObject(pOldPen);
9 d. I, D0 I% F2 v: x/ c( @. k}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)* U" q; u7 g1 P9 q9 v
{" F+ {, w) J" M+ ^
CBrush NullBrush;7 L- A3 L( V8 d) u+ b% m3 r
NullBrush.CreateStockObject(NULL_BRUSH);
8 z9 J( W7 r3 B: a. {0 B CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
* J; _9 f% }( j Pen.CreatePen(PS_SOLID, 1, FrameColor);1 }- T0 T# E' U# o# C
CPen* pOldPen = pDC->SelectObject(&Pen);! T1 q8 F2 g- o3 j
! m7 p  F; p) ?( N0 b4 Q  v3 Q
pDC->RoundRect(rc, CPoint(3, 3));, q; I1 {, o5 _+ G! v1 n; z9 F
rc.DeflateRect(1, 1, 1, 1); - l- ~+ ?' ^% h
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
+ v+ B) P( j2 d( b7 f pDC->SelectObject(pOldBrush);
. S. G) }6 Q" X2 b& t4 c9 k}
7 g5 x3 H; S/ I, W+ G- `
/////////////////////////////////////////////////////////////////////////////
4 d5 @0 y  a* W' L// CHsPMEDialog dialog
6 N( ~1 D0 C% |+ S9 \) p: u  P//-----------------------------------------------------------------------------
) U% i% m3 ~8 U// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
% |3 O7 I: X! o8 I" {& F: s7 h' }//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
7 W$ B& ?: K' b- k! r) {//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
6 g/ t4 |/ Z! H//   指针将其显示出来,然后隐藏或销毁自身+ W( o# F' N7 O. v
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
0 e! a6 _) Z8 K1 b! o0 E9 Z! n//    采用的方法为使用上面的CHsPMEButton作为按钮的基类4 o2 J$ [. ]7 O& C* X! \0 v$ U
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,& W6 O9 F7 O" U- C8 x8 R3 \& S
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
5 X3 j* b- n+ O//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
# w' L( U6 L+ w( ^//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框. F4 s( `, r/ Z% e* X3 s
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。6 E4 M& r+ G9 j$ k
//-----------------------------------------------------------------------------( q" x6 ]$ D  M3 Y6 @
// 注意:8 b/ y) {( ?* K- G( M
// 1、在构造对话框时必须给出其父窗口指针
, x, t6 H6 K' k, M& p// 2、在初始化基类时必须指定对话框资源模板ID6 r5 S$ W# H8 t5 b
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
$ P) m' d; \( X& v6 j" Q; i// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel, Q- ~4 Q  r  y+ W) S; n% r, v
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog, k2 Z; a: ]1 l9 I
{
/ F+ v  [1 L& v1 p DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
6 W7 d  z" Z! E7 G* @9 ~. c' w. d// Construction- _& f5 F  a9 `. S% U
public:) }6 ]$ W9 I- P. b* k
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor$ Y( r) \6 C6 l# |- i
~CHsPMEDialog();
  F) W) C; N. z( P0 A! E7 V BOOL Create(CWnd *pParent = NULL);0 x5 a; Z1 O/ m' b3 P

( a9 [7 J/ T$ @% [# `: E, Y// Dialog Data; R5 p" b) S6 }1 n, N1 n
//{{AFX_DATA(CHsPMEDialog)
: U6 ^" }' @# N //enum { IDD = _UNKNOWN_RESOURCE_ID_ };
- A2 z* Z0 o0 P+ N8 S& Z  // NOTE: the ClassWizard will add data members here
9 {; G& I2 G5 m //}}AFX_DATA

# d6 I2 v/ q5 V  @0 h0 P// Overrides& A. q, P* o. b7 `; p
// ClassWizard generated virtual function overrides
4 [- Y$ w- ?) s% n- d1 D- h //{{AFX_VIRTUAL(CHsPMEDialog)
6 W' G" e" g7 I protected:
: ?" c; B3 B) g, c  j0 L" { virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
& z+ ~! C" m$ K5 y0 h virtual void OnOK();* _1 g" X, T) k7 K$ K+ h5 }3 b8 I8 j
virtual void OnCancel();
2 y& x! `$ C& W7 C1 s. G virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);+ Y( [  T% X  P, E
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);3 S2 D: e2 O1 A5 X, q: b" w6 `" N
//}}AFX_VIRTUAL
// Implementation* i6 r; Q# k4 A' {9 w
protected:
// Generated message map functions/ A8 o& p) B, D7 V, I
//{{AFX_MSG(CHsPMEDialog)) b" T  C2 V! g
afx_msg void OnBack();1 a6 {0 D! {% d% @3 A6 i5 b5 W4 ]
virtual BOOL OnInitDialog();* Q6 r/ T+ i3 c4 E0 }
afx_msg void OnDestroy();$ p6 i* U/ x  k) P6 |+ i
//}}AFX_MSG
  ^( l; W4 V0 f0 Y, ~) c DECLARE_MESSAGE_MAP()
protected:+ {: s) L+ J5 P
// attributes
. N3 ^& Y" O6 W# r; I/ U. ~# E CWnd   *m_pParent;     // 父窗口指针
! K4 f+ o9 \$ X1 g HICON   m_hIcon;     // 图标% G2 y: G3 Y  x0 ?# j# C- F2 ]
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
0 N  w* L- L, l' K2 m4 N' w' }& b8 t CHsPMEButton m_btCancel;
# j/ M( f7 x+ D. R6 i CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
6 w9 R% v* f1 P, d8 H HHOOK   m_hkCBT;     // CBT钩子句柄
% s4 g  d2 a5 _0 D, E1 g3 _5 A) _) ` " k* m! c1 J" o* ?6 U# p; B
//-------------------------------------------------------------------------4 F3 E- ]+ o. f1 e. M4 a$ S: G
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog/ j- z% k1 J  `; Y/ c6 G
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
/ ?7 e" e+ k0 x9 R1 d1 a" k // 链表的头及下一个结点的指针4 F& L: i- x- i$ ^6 @5 B$ D) t- @- z
static CHsPMEDialog* m_spHead;: F: y2 @" r; g/ i
CHsPMEDialog *m_pNext;
// operations
0 G& C! f' B7 }- r // 键盘钩子消息的处理函数$ S3 _* q2 P9 ]( l
static LRESULT CALLBACK KeyboardProc(, i" K  F6 t  ~. s
  int code,       // hook code
8 Y$ \3 l& w& @2 X! t  WPARAM wParam,  // virtual-key code
  h: X: j& G* _# _5 ?* y! k  LPARAM lParam   // keystroke-message information
5 E  p; z" I' H5 [1 Y" D  );- Y2 \( ]; L2 S6 b! l& D+ h' J
// CBT钩子消息处理函数) S5 V* d! e2 _' O5 p
static LRESULT CALLBACK CBTProc(
# {, F* B3 `- U3 H, A4 n$ u' V  int nCode,      // hook code. O$ s# N. Y& ]5 b! G
  WPARAM wParam,  // depends on hook code7 ~0 G- R+ h) W4 y( l. B. ~+ d
  LPARAM lParam   // depends on hook code9 L/ b5 W* N  b% R0 V
  );
; F3 @  H3 M6 y  X! W- J
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口* h1 B. N/ c' _' R$ ^
static BOOL  IsWndKindOfThis(HWND hWnd);) D2 t8 v' w- {) M  P* x$ U$ e, ?- v
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)" h/ @+ I1 u% M; O( |6 d9 H
static HMODULE ModuleFromAddress(PVOID pv);/ S& j3 \' J% w$ F0 D+ M0 e3 u
public:9 h; f# K  h" ^# t
// attributes
// operations
1 J8 Q* A! h3 y; w5 b // 用于模仿UG的创建一个子对话框,同时隐藏父对话框
5 J0 u# H5 i% O& k" M6 I* W BOOL CreateChildDialog(CHsPMEDialog *pChild);) n! S2 u) E4 U% n
};

1 J7 L; \  _3 gCHsPMEDialog* g_pHsPMEDlg = NULL;
' U0 B# U8 T* k" k' u* h. [/ PCHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
) g* E2 }3 K9 F! g6 {5 HHHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)3 R+ |0 q. W: P( M. C$ M6 _* d9 l
: CDialog(nIDTemplate, pParent); q5 d( H$ B, j3 g
{, z0 b  |% c" j! A" w
//{{AFX_DATA_INIT(CHsPMEDialog)
+ a& b6 v5 r( Z7 U/ X& k: `2 t  // NOTE: the ClassWizard will add member initialization here
, L; b3 e+ h# q: Y4 g8 c4 ` //}}AFX_DATA_INIT
% I+ {4 P2 i5 c! O; l! T7 ? m_pParent = pParent;
$ j$ D& z$ S( R% n3 |& S, u m_nTemplateID = nIDTemplate;
5 R" d( ?0 l; v& o& C. E% f/ G0 C m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表7 f0 x( U; w8 B' n7 _
m_pNext = m_spHead;
8 b  Y# J) U7 x m_spHead = this;2 Z0 V' e- v6 T; f: @
m_hkCBT = NULL;
9 [) Y! W+ p: q! u/ o: H1 {}
CHsPMEDialog::~CHsPMEDialog()$ b7 d; ]: ^+ D) n
{2 ^, W- S+ j7 Z% o/ d% s
// 从链表中删除本结点
( f8 }# k( P( x) c2 J9 b/ ^ CHsPMEDialog *pTemp = m_spHead;
: C- w4 T3 l9 M7 d7 h if(pTemp == this)
% L3 @+ F! P# B' c1 L {
: o" l5 }+ |0 g) m, h. T  m_spHead = pTemp->m_pNext;- @- K& V+ v7 K* V  T* V
}
1 D* ~  x, E* [) d/ |+ v( ? else: L# Z+ ?7 `- Q" B* m0 d" P
{
* Q8 @& r8 r3 m' U9 F  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)" C8 m! e1 g: _* Z, e8 [  I1 s
  {
$ @' d% f' R0 {/ D   if(pTemp->m_pNext == this)
" {) I! `) _3 }8 Z   {
' \  s8 I1 ^; H- f    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
: o$ B, l4 p8 J7 Z4 F; X: Y2 X    break;
2 ^& J4 [# F2 e. h$ Z1 p  m/ a% l% X   }4 q) n. t% n8 K6 y
  }1 V! R1 g$ z1 B* |, w9 u
}
# L$ N. N) G" |1 |}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
6 C3 V* _3 A8 G1 g{# H2 O0 D. `; x5 D
CDialog::DoDataExchange(pDX);
" X" N' c9 R& n //{{AFX_DATA_MAP(CHsPMEDialog)
0 O$ g6 b. I! w DDX_Control(pDX, IDOK, m_btOK);
: F7 I* p9 A' `) L DDX_Control(pDX, IDCANCEL, m_btCancel);  q2 W0 v" a3 x3 ?" R) z
DDX_Control(pDX, IDC_BACK, m_btBack);6 Z# T+ |7 e" o" Y& p
//}}AFX_DATA_MAP
5 c8 n5 J# X" p' D. G5 ~}

7 m6 w2 U. E9 v/ N+ @1 b: s9 YBEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)6 T% N$ e7 V: L: ?) p! g0 Y
//{{AFX_MSG_MAP(CHsPMEDialog). Y6 D  D, W. |* t$ O. l* K" u
ON_BN_CLICKED(IDC_BACK, OnBack)7 d1 T0 J$ j# D8 ]2 @8 c
ON_WM_DESTROY()4 h* i% s* h" B- i8 A
//}}AFX_MSG_MAP; i4 K) S5 ?9 g/ `% ?1 {2 G$ N
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////9 q, b+ n  Y5 E# E; |* g
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
5 K' t5 q; o1 E6 y  D; F, n, I{
) ~5 a& G2 \2 Q% z  Y+ Z  e m_pParent = pParent;
- v# r( E1 l+ D6 x return CDialog::Create(m_nTemplateID, pParent);
- F) g4 r6 @% F; T/ I}
6 l! h. C0 l! G7 L4 i* ]
BOOL CHsPMEDialog::OnInitDialog() * Q9 ~0 p( F) f- S% e) V9 C5 M
{+ F( `* K& ^4 K
CDialog::OnInitDialog();
// 设置标题栏图标
* b& A4 A7 v) Y3 k SetIcon(m_hIcon, TRUE);
- t+ ~/ ?, I  P* y+ [ SetIcon(m_hIcon, FALSE);
' t. C( v1 x) v. H
9 h2 X! \9 Y$ v // UG的对话框的几个标准按钮没有TAPSTOP. m5 }) ]" A! b7 w2 B, F
CWnd *pWnd = NULL;1 i" G; U( S& S0 c, b; R
pWnd = GetDlgItem(IDOK);7 T  ]- Y1 X, b, v- f9 S
if(pWnd)
( q  `+ N) O% Y% P! k {+ u% m+ b: H/ ]5 D  C( m+ A
  pWnd->ModifyStyle(WS_TABSTOP, 0);
2 \4 X: }6 ~! T8 W- k! b( A- R }1 v, ^5 _6 r0 z0 b
pWnd = GetDlgItem(IDC_BACK);* C2 d. H7 j$ Z1 G0 D- e# m
if(pWnd)/ z5 l; e! _# Z" n* Q
{
; _3 e, n+ @5 Z  r0 ?' w  pWnd->ModifyStyle(WS_TABSTOP, 0);
/ I. o9 I5 K' c3 n9 y) L  _3 _# M9 s }2 `- D+ e  x1 i6 i3 S, I
pWnd = GetDlgItem(IDCANCEL);2 f  B6 l: z6 ^) \: t
if(pWnd)
& l) F4 n) o  J% @8 {1 c& u9 [! O' s {- H6 Z6 @7 C* x. X% m# l5 B
  pWnd->ModifyStyle(WS_TABSTOP, 0);
/ b( ^$ e6 b- t# t' T }
7 r& j& F& F. S- R ' V: T. m) K" \% E$ m  Y+ ^8 j2 t
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
5 [  |$ {$ e* b+ W: z if(m_hkKeyboard == NULL)
, y7 \' _: r6 O, L) S2 d: N. ? {
# G/ g3 P& p$ x2 \" b: X8 k$ N  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
# \! @1 X. q- n. N: p- B }
+ }: L) j, _$ `( Q" z, O if(m_hkKeyboard == NULL)
5 ?- j5 R- {. l* a! I' Y0 a; E% {( M {; e; `' @1 |' I9 J( Q8 T; e
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());: F6 ]1 k3 V4 R1 E! d
}
if(m_hkCBT == NULL)
! ], T  l# m% `$ J( L {% E/ I; ?' ^) f0 l8 U" j
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
; \% Y7 E5 g* H8 _) r7 f" E }
8 A) l- K& Z8 k7 k9 E! ` if(m_hkCBT == NULL)
! S4 M$ S, o% S( G# a {
+ Z5 g5 Z6 m* |  U, A. g' T5 W  TRACE("Set CBT Hook Failed: %u/n", GetLastError());/ O9 T  G7 J/ n+ m# u
}' k0 a3 Q8 h0 i/ E8 }% l

1 o+ j' ]* W! R. \% F- ?# R  L# J return TRUE;  // return TRUE unless you set the focus to a control
+ G: E* K4 O1 L% W( k8 n9 S               // EXCEPTION: OCX Property Pages should return FALSE2 ?* x% Z/ V1 m! @
}
void CHsPMEDialog::OnOK()
8 _+ l' k* u3 U+ A{6 Q7 v' i9 Z8 H3 v" x
CDialog::OnOK();, X& p9 i' L. \" p! X9 J; ~+ S
if(m_pParent)0 X& I0 S2 O6 ~! L: e" U& P
{2 E' u7 G' E$ T6 D) W& s
  //m_pParent->DestroyWindow();8 f7 u+ H3 n9 t7 _
  //((CDialog*)m_pParent)->EndDialog(IDOK);/ s: T+ l7 w7 A' `; n0 ^5 j
  ((CHsPMEDialog*)m_pParent)->OnOK();
6 v3 {5 z3 q" K7 a }
2 M+ k( P" {! X, o9 v! I% G* {}
void CHsPMEDialog::OnCancel()/ _! `: X* n% N. y2 L5 m
{- u0 M. {" h/ U; J' C+ H( {9 n* ~  [
CDialog::OnCancel();
% L( w. T. l# F, y$ ]7 X; t if(m_pParent)) r' n5 \: }) q' L" H5 T9 f
{
% u% x: g$ L+ N7 l' ~$ |1 K. r+ D  //m_pParent->DestroyWindow();
* O6 |! }5 l( z$ N6 L  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
% f0 W% i5 P1 P: b. z9 R  ((CHsPMEDialog*)m_pParent)->OnCancel();
, b6 d* l, ]& F& Y }
/ `. Y# A: d( b5 i( Y) Z* ]6 \( r- E/ I  e}
void CHsPMEDialog::OnBack()
6 L$ a1 }( k, S0 K) r{
7 w( M4 b& b. n: E( B: S/ K: P4 ^2 V if(m_pParent); f$ k8 M% A% T  I8 h1 ?0 q5 x
{3 K2 i$ ?+ c& A% ?4 f" ~/ @/ O2 v
  m_pParent->ShowWindow(SW_SHOW);
3 D8 M; w1 s0 ^; k9 i* t/ } }) m2 y; C7 u  W4 f+ o
CDialog::OnCancel();
# s" Q7 p. `3 W}

% _8 g5 g: j* mBOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)8 x) a5 x6 Z- {# e$ g
{& D1 O( Z4 R* T) t
BOOL bRet = FALSE;* E8 U. p( e0 U; _% r6 t
if(pChild->GetSafeHwnd() == NULL)
( F4 b$ Z' o" H) ~ {
0 x" T, O% A, a( {" f' ~  bRet = pChild->Create(this);; l0 W7 t$ p* S7 m8 A, G/ ?0 T. P1 Z  B
}
) h& Y# o4 ]- X" W: C  g bRet &= ShowWindow(SW_HIDE);
+ Y6 b6 E9 b+ R* U, N5 {! n% s bRet &= pChild->ShowWindow(SW_SHOW);
6 t4 A: w. V- } return bRet;; r, i4 Z4 s0 e' L- l
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)8 x' z5 K& C3 w  E; d% T
{; Z1 h( w- ~5 O5 T4 m! z8 {0 K
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
8 p, J2 T3 q6 E1 H {
8 h9 [, i4 v9 c; Q  //TRACE("Key down/n");
5 R, V- s) `. f- v/ W( V  CWnd *pTopWnd = CWnd::GetActiveWindow();
* D/ x* J# `1 a2 Z0 l! f  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
2 p. P" P+ J: ^; J) R9 d  {# L) Z" V+ \6 w7 B
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息5 X3 s- K4 ]/ \7 x
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)+ J% p8 `' l3 ]9 A! L# e  }
   {
  q6 r5 c$ M/ x# f. X6 j    // 只截获tab、esc及回车键
4 ?$ h0 i4 R4 N8 i! D2 P    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
, a- N! i8 l# v    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
; D: K4 g# B( S% Q' U   }1 s, f5 m4 J7 M/ z2 [& @
   switch(wParam) {0 d4 D) @& }6 [$ h
   case VK_TAB:
1 h( ?! d: b8 ?4 ~    {
1 q  ~0 k" T/ M, F     CWnd *pWnd = pTopWnd->GetFocus();
. P: }/ H0 f# N% ?1 L, C7 [$ C& V     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);4 }% P4 Z8 @3 p$ J$ b  |
     if(pNext)
# ]$ h( K' n& V1 ]* ~     {
3 l0 l+ K9 z* g: P5 N; S      int nCtrlID = pNext->GetDlgCtrlID();
3 C; M* E2 n0 W7 m      //TRACE("CtrlID = %d/n", nCtrlID);
/ ^# l1 H+ r; Z/ M      pWnd = pNext;
  _, |/ Y, @: H! \8 j. a1 G      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)3 A5 Y- Z0 |6 @. c
      {6 }0 X( K8 S$ V/ `
       // 根据UG对话框的属性,这三个按钮是没有焦点的# q) D7 c' R) N* P, v1 k/ _
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);7 Z- o) A0 x. R( Z# n
       if(!pNext || pNext == pWnd)1 w, r8 [5 r& H: |
       {
- D7 ~  ^, t. H+ T        // 对话框上只有上述三个按钮; H8 o, E% i! N% k% D9 }
        return CallNextHookEx(NULL, code, wParam, lParam);! F1 U9 q5 i+ W  @# I4 `
       }% V( G+ d) h; O2 y9 n
       nCtrlID = pNext->GetDlgCtrlID();
' d1 g/ Q7 B1 t" h* U' G6 m       //TRACE("CtrlID = %d/n", nCtrlID);- `8 z" n4 T  c- M* W
      }
' r. g# `3 o2 \0 x      pNext->SetFocus();
3 _0 a% m: d0 X! F/ k. ?     }
" ^  }! J$ }( b$ w' ~' L     //return TRUE;3 r$ [* c2 h" D7 ~1 d
    }0 Q4 p! |) w; G9 o% ?: m' w
    break;5 z% ]9 i( H0 V! w. i" V# }" B* H
   case VK_ESCAPE:" ~7 B- h1 f3 j; x
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
- s: V, w  Z% h1 y; I$ @2 d; M    //return TRUE;7 g8 K& U/ A4 Z! u2 v6 M! m+ {
    break;
9 U. Z+ G7 C8 h6 s/ W   case VK_RETURN:
3 J* w7 [) r5 L6 R. ]5 G% E, `/ v    // UG实际上并不处理回车键
7 N, Q) K2 X. b  B# r0 g( y: s    break;1 k$ d9 g  k2 @+ ^* M, Z. c, u/ ?1 X* g
   default:
8 \( t& U; I3 v9 q$ h; B- V: Z    break;
; k7 e. J9 \) u) ]/ _9 _   }. Y0 L  f* O  i$ L( g
  }# V: {, d8 G9 T5 U. C/ U8 z' j5 f
}
' a7 u8 p0 Z3 o- z; M$ z. \ return CallNextHookEx(NULL, code, wParam, lParam);6 s& g1 M! O8 C" n' h: U
}
void CHsPMEDialog::OnDestroy()
. }9 r2 L9 t1 ?$ a% }6 A9 |{7 [% m# w6 O2 `: K3 P6 H
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子% M" s' j* {' q" u: k4 G
if(m_hkKeyboard)
* c+ ^$ w4 S- l- t7 _0 c {7 S4 K' I. r7 w" F9 z9 ?8 j) ~$ v
  UnhookWindowsHookEx(m_hkKeyboard);
) L1 q# S. r4 i" ~) E* f: N  m_hkKeyboard = NULL;
: l  n/ P6 D0 o, F* \! Z }
if(m_hkCBT)
! k+ k$ Z* z( \ {
6 w: t6 L, k( K6 W9 _9 }; m9 W. X  UnhookWindowsHookEx(m_hkCBT); 7 W. q- x( _. `$ ^5 M; L
  m_hkCBT = NULL;9 j8 V1 T& E/ {$ |8 b
}, z6 h0 \! h2 [5 h0 N% I+ c) n& O
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
4 w; }$ ?: V$ p% r" ]; U{. j- T9 A& _# d
CHsPMEDialog *pTemp = m_spHead;
* x; s, I2 a0 ?; {" S- t BOOL bFound = FALSE;; P4 r! {3 ^% x+ G( ^
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
4 O  U( \# J9 W5 o" N- t1 ~& b {
+ ?( v4 f: D* x5 L  if(pTemp->m_hWnd == hWnd)+ M0 Y4 f$ Y# m% }- A& F" X
  {
4 p% o8 c# j, e; Q% S   bFound = TRUE;- }1 ^; e) r$ y' ?& G& j" H
   break;1 ]) ?' k" J$ i$ S- M) g9 R) T" R
  }
3 T: T& N* z* y* W. E( W6 v2 z }
4 E+ [$ t2 ^- G& b$ j5 g return bFound;
0 |( O- Q: r2 b4 ^, c- X& G, {}
// Returns the HMODULE that contains the specified memory address+ H* ?! i" Q. i! E1 Y
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
! H" R; Z- _% F: @' c5 l8 D# P4 s{
/ s$ f7 e9 M! }% o4 { - `" h/ {# I  Q4 d0 M) [* ]
MEMORY_BASIC_INFORMATION mbi;
7 Y) D( X, |, T- e7 |; `% r return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
" E$ I: N) @5 |$ M$ r$ @& I  ? (HMODULE) mbi.AllocationBase : NULL);. Q1 N. ]! O! O- y7 R$ o% G
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)  P; R/ N# t" L& P
{& s# J( d. [3 s3 q
if(nCode == HCBT_CREATEWND)
0 R- b5 d+ q) @' e0 x) I# q" H {
: F) ?% h2 v# L  K; X# D) {5 D  //TRACE("A Window is being created/n");
0 K1 W* i. O. g/ ?' y& q  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;4 i# A3 L; n0 x' D6 D, ]& K4 C2 F; c
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
  Q" C3 M. ?4 B6 v' ?) C) B$ ^  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))$ w- @; L- q+ l3 f( B$ _
  {" @$ e& U  ^. x; y* x+ l
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应+ T! q9 {1 m: U1 _% S9 ?
   // 取得窗口处理过程内存地址
2 f7 D% M" r1 ?: u- ^   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
: Y3 X/ v" K! V5 A' ~, m) E) O   if(dwUserData)
- v  h( @( U/ N0 ?+ \/ V+ j   {
  ?4 I* a; H1 o# n' a# m    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);7 z- ^  \% ^2 L$ `+ y& l
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
9 ^: X- T. L: \) n% f' ?    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);7 a, \; ?7 [, Q9 g: g( h: c8 n
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
8 u) ]3 M% B3 x2 K, ?% |    TRACE("CreateWindow Frome Module: %s/n", szModulePath);( K( k$ d- I: B- u8 O% f! e4 a2 k
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);1 {1 _/ x" ?$ i, i! a
    if(stricmp(szUGPath, szModulePath) == 0). I* M1 v) N" N0 r# F) H
    {" Z2 V* [5 T, X3 s
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)! @+ n7 I+ d! {! J2 j
     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)/ z$ z( D' r$ H& }- ?* O) R7 r
     {
$ Y0 A5 |; j# C      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog), O# \+ q1 @0 z2 U, l+ F: q
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
- F" ^9 V$ [0 U$ m       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
5 m7 q5 {" w2 z* |" f+ W9 |      {
$ N2 e9 z. S0 e; ]  g. `       // 窗口非本窗口或其子窗口( l0 o* v2 v: d) W+ |
       g_pHsPMEDlg->OnCancel();
* R# V3 t) [/ _' O" s9 J" I      }
! ^4 @0 b8 D; n/ B* o! S     }
7 p- u" D. D8 U5 W- A    }: X- s2 S/ Z6 b- \4 E) T
   }0 d$ {6 `: `- N" W0 o* L9 A
  }+ E/ `8 {/ {  m; l
}
  u" n! m$ i6 @7 K# Q4 F return CallNextHookEx(NULL, nCode, wParam, lParam);$ q/ y: O- ~. ]
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) ) E- P. Y' X8 z9 S- o! h
{8 Q# }2 r6 e$ T; X% A& }
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
) P. K: k) V9 e$ O8 ~0 M+ E   p+ C8 N) `) J6 |3 T
return CDialog::WindowProc(message, wParam, lParam);
0 I0 f& F" m. k% C6 d}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) " C  y) k6 P- b  V. x& L( `( r
{
$ p' T+ c# i4 I) N5 I! g& j+ w 1 v  h* @5 u. h; [, |. i
return CDialog::DefWindowProc(message, wParam, lParam);9 d7 r: v, f( u# V0 _% r
}

' Z: d4 q3 _! C. l( k4 L
上海点团信息科技有限公司,承接UG NX,CATIA,CREO,Solidworks 等CAx软件,Teamcenter,3D Experience等PLM软件,工业4.0数字化软件的实施\二次开发\培训相关业务,详情QQ 939801026 Tel 18301858168 网址 doTeam.tech
回复

使用道具 举报

发表回复

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

返回列表 本版积分规则

  • 发布新帖

  • 在线客服

  • 微信

  • 客户端

  • 返回顶部

  • x
    温馨提示

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

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

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

    我知道了