PLM之家PLMHome-工业软件与AI结合践行者

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

[复制链接]

2017-8-31 13:24:24 3368 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------: A+ z" O0 N6 ?& s  E; Q
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
: [, H! x+ W' W6 e3 q7 |4 L//    该类来自网络,稍作修改,版权归原作者所有
) r, ]+ _! G0 G" r7 U& ^  f; b# c//-----------------------------------------------------------------------------
5 B- W9 r7 _, W3 oclass CHsPMEButton : public CButton
3 N9 \" r0 Z- o& D8 i- e4 {{, A% v8 l; k* b; `) J0 @# ^6 y
// Construction
! A$ V. F6 S! a/ `public:9 n8 a7 a1 [# M6 ]
CHsPMEButton();& h1 H, ^8 `5 X
! w# }2 k5 X- j' U8 f" r7 I
// Attributes: f3 n7 O' t  M! Q+ {. g* T
public:  p. D' q& D) B
! }- f/ K, y( E4 Z! F0 x$ R
// Operations
) n: I0 _+ P7 ~6 v) Mpublic:
: O8 B) [- `$ I% n1 k( Z& I8 ] inline void SetNormalTopColor(COLORREF color)
( N$ _: v( E4 J- a! v0 G& R2 V {; l4 q) Q% ~( s5 x: R9 E4 x2 @% P
  m_NormalColorTop = color;, O' Q  V! J2 t! U0 @/ q# ]
}
+ i4 v+ A# J+ f* U3 R' t inline void SetNormalBottomColor(COLORREF color)
, I$ A1 u8 C, `& {6 i4 e/ B1 F {
2 H5 _  S  P6 l1 j8 m2 m* D* F  m_NormalColorBottom = color;
1 d1 y* }4 B5 t }2 ?3 S; u! `( f, H$ f" p5 i
inline void SetActiveTexTColor(COLORREF color)
5 h. u- l% }. S3 K' C9 V {
% ~4 `: N5 v, J& C) ~  B, O8 f8 B  m_ActiveTextColor = color;9 j$ A' D" p" o- ]
}9 t$ E; M8 a9 K8 w- D4 N
inline void SetNormalTextColor(COLORREF color)
$ I) |# R, v! F& j/ P {0 J! E, F- V$ M# l  M
  m_NormalTextColor = color;
# g  t1 T0 j$ ~/ U4 D  k }3 o2 n# c; a3 _  `9 `
inline void SetSelectTextColor(COLORREF color)
4 ~/ M/ d6 p" Q6 Z; s {
" \5 _. Y  v) V9 }  m_SelectTextColor = color;
& A% g* |$ S$ ?9 ?) @1 z }" e9 j. J4 Y. E/ n
inline void SetFrameColor(COLORREF color)! O8 ~3 k& K  m1 \5 s# m  S
{
9 j# }4 V2 B  e; _  m_FrameColor = color;& Z: C5 E! P9 S5 k1 F3 L. \
}4 a2 A% M, k  `' B. ]6 |, O$ k
inline void SetActiveColor(COLORREF color)/ d) X6 \% v2 c" T) ~  n6 E4 W
{- [7 ~, A! S# F# G
  m_ActiveColor = color;
4 y% \9 ?6 m/ p) p0 f$ u# F }
# h+ v3 L$ }1 x* F. Y6 g6 S0 @; X // Overrides' h8 e+ V, B7 h! {
// ClassWizard generated virtual function overrides
& O/ B; B7 ~3 M4 I1 L- b //{{AFX_VIRTUAL(CHsPMEButton)
3 f+ F' Z! |! ~protected:
9 L: ]1 b! F  c virtual void PreSubclassWindow();
* q0 {& I6 j3 Q% d3 b //}}AFX_VIRTUAL
; n- _, R8 C  O0 m 2 {6 c" m3 z0 U! D  b) f
// Implementation
3 ]/ o  U5 C( s6 n$ [: x) H! dpublic:- L* R' ?) U6 ?1 r$ t9 k
virtual ~CHsPMEButton();
$ k7 w8 a2 `( O" y! P, g' m; E
/ r9 Y3 |, f+ ~8 g // Generated message map functions9 X5 f6 z0 q$ e+ J2 S+ ~1 i
protected:
' K) w- ^0 L( r* C //{{AFX_MSG(CHsPMEButton)
/ D7 k8 v9 n7 \5 f& r6 x afx_msg void OnMouseMove(UINT nFlags, CPoint point);2 V3 [1 H5 {5 }6 e; d
//}}AFX_MSG3 C2 c# s' {; O2 T3 B
8 h1 s* g, S  f' m" p1 y7 f
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
, a5 t4 L: ~( Q3 w+ E) U void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
4 ^. `9 D9 a4 u% t void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
& T8 g5 h7 B; V$ {; I2 b: u LONG OnMouseLeave(WPARAM, LPARAM);
9 ^+ n' ^6 w6 |* |( t$ s* Y$ T, n( K BOOL m_bIsMouseMove;* o5 s. |" g, |4 A

3 x) W; f- S/ R# i COLORREF m_FrameColor;8 ?9 ~* E' z  J7 @) i1 }& t
COLORREF m_ActiveColor;
" M, h9 r; H6 t4 s: t
" S  X4 V( e, x' ] COLORREF m_ActiveTextColor;( ~- ~3 I* h9 f4 J3 D
COLORREF m_NormalTextColor;
9 {0 \+ Z% j% h COLORREF m_SelectTextColor;7 h1 M3 [" c1 z* z9 @1 {" Z5 v. }  R) R
( p5 R" t2 }- x1 {- i' S1 O/ C
COLORREF m_FrameHeight;
  r* {1 G3 V! T COLORREF m_FrameShadow;
& K7 O' q( i5 G5 N" h , H2 N2 n$ J0 }: ^7 ^
COLORREF m_NormalColorTop;2 U4 k- z; O2 u! ]
COLORREF m_NormalColorBottom;
$ H- T8 S! C* l5 f! P; f3 M& M + ?  o6 x: b. B0 h: @8 {
DECLARE_MESSAGE_MAP()6 M. O& m* T2 L, k- b" c5 o, d. u% d1 m
};
/////////////////////////////////////////////////////////////////////////////, Y6 l+ d( \: R- G% @0 F
// CHsPMEButton
CHsPMEButton::CHsPMEButton()
1 _& l3 @& ~7 s/ W: S4 ?" z* Z{
( U; X6 Z# E9 U& S  Y m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
5 P& E# [( @% ^! l/ N% F m_SelectTextColor = RGB(0, 0, 0);+ A" j8 l. @  F; D  Y/ Z  D
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
8 o: W6 g- z% z- v m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
1 R, H) k* z2 |) I0 E m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
% ]# Y, V( ]; U# f$ a! ^8 Q m_FrameHeight  = RGB(230, 230, 230);* V+ A/ e& V7 y
m_FrameShadow  = RGB(128, 128, 128);
5 x( u8 p3 P+ ^* |+ [- t, F}
CHsPMEButton::~CHsPMEButton()
6 p8 c) J  c8 f- A( t/ q; w# u9 K5 A{
5 h3 j* K" ?2 K8 m; Y0 j$ L8 j}

+ Q7 e6 y+ ]9 X3 h7 v! BBEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
! p+ A5 @5 N) S //{{AFX_MSG_MAP(CHsPMEButton)
. E0 P* O- K- I7 K$ c# T6 |0 b ON_WM_MOUSEMOVE()! S9 p3 D+ Q9 i, [& _" Q4 C5 f
//}}AFX_MSG_MAP; K) F  j6 m- _4 x( z
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)% `; j: t# q5 ^  d/ }: F
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
6 O- {$ H' o+ j: V& c! d// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )- T9 {% I2 N4 c
{4 l1 q) d, C+ G. ?' h* C6 B7 p
//*
8 y# G4 f2 M3 v+ {; y CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);2 f* _% U/ S8 i
DWORD nState  = lpDrawItemStruct->itemState;- k9 ~9 e2 h; h
DWORD nAction = lpDrawItemStruct->itemAction; # S2 j  c, g# A7 i% B" B
CRect rc   = lpDrawItemStruct->rcItem;+ W# f4 O, x' U' O2 G
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);! A3 m" _) [9 x/ [- s: q
CString strText;
0 t0 i5 g8 c& X) ^: V GetWindowText(strText);
if( nState & ODS_SELECTED )" {1 h+ Z- {6 e: s: K& [$ L8 o
{# i0 g3 m0 o4 j" L3 B& w$ ^& s4 c
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);5 S, j% P: [  k( n/ c) ^
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); ) _( t/ U4 b+ }% {; P) I' j7 ]
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
' R/ N6 p& r$ p- \9 ^ }
; k9 I; `  \" T5 }: | else //Normal3 I$ X; h6 G9 K
{- i+ [! e- y; D  L6 l1 y
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
* v7 C. Z# {, h" Q- w  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);) Q, C" x  R! H3 K* I
}
if( m_bIsMouseMove )- F4 t# H# V; V
{* ~' j) w5 N, F
  CRect rc2(rc);* u2 x: `, `4 `, C
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
+ ]) x: D, f# S* f   m_ActiveColor, rc, rc, pDC);
( f2 H+ P" a& _; N- |" i* @2 U5 I  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;4 U* T* q8 j6 u+ g& i
  NullBrush.CreateStockObject(NULL_BRUSH);
8 a6 R- F5 f9 ]' a' |. |$ S  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);& M8 V6 R+ |/ U, @/ i8 v# F
  ( ~  U5 b1 y% x, M4 D" i
  CPen Pen;# {1 j3 Z: D7 a: Y$ d3 ?
  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
1 `8 h/ _5 \* y+ i8 b9 T2 s" D6 C+ @3 ^  CPen* pOldPen = pDC->SelectObject(&Pen);
, ?+ B2 H. C* L  n8 x  rc.InflateRect(1,1,1,1);, @  O* C4 }8 m6 ~$ [0 T2 ^% n8 p
  pDC->RoundRect(rc, CPoint(3, 3));
8 R9 P7 X4 ]% J! s" y& i  //rc.DeflateRect(1, 1, 1, 1);
) l. {" y) V9 F  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);! o' F4 I# t& v$ r
  
6 h0 J" d+ ^9 B7 l' r! D# C7 n( p  pDC->SelectObject(pOldPen);$ }4 X. l; E+ G4 {& v/ u
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
  N6 W1 I  n2 O' p6 d }' b) d" @2 B9 \
, K* E' [$ e% `  }: q
pDC->DrawText(strText, strText.GetLength(),
) [) _4 {, K7 e) w5 \  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
6 P( t! ~; ?% t$ `0 }2 X) F //*///
7 M& d# p1 f9 X4 x, c, Y, c}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) . B2 }. J1 y' @
{
) L% `& J3 \" _6 a7 u5 l // TODO: Add your message handler code here and/or call default) S6 I! r& o% D# g+ C. Q
if( m_bIsMouseMove == 0 )
/ T4 r, j" v, _5 O" @5 ]4 g9 l% d {
7 y; ^- v$ I+ k+ X0 L2 `  m_bIsMouseMove = 1;
9 v; ^- o2 a0 @3 L+ v  Invalidate();
/ a8 a& A3 S5 f& ?& `  9 U) h: M' E! S, n
  TRACKMOUSEEVENT trackmouseevent;
% `$ T5 y7 C0 }! n+ A9 T5 ]% m- c  trackmouseevent.cbSize = sizeof(trackmouseevent);
& Y( F& y; J# W/ J8 s6 v' e2 a: W9 N  trackmouseevent.dwFlags = TME_LEAVE;( N6 Z) h, y/ W) A
  trackmouseevent.hwndTrack = GetSafeHwnd();* y6 J: P5 O( a/ F: U5 Z# o
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
4 a9 p0 q+ L- {6 e7 I: T* C- s  _TrackMouseEvent(&trackmouseevent);
( q% t- i6 }5 e2 |# q7 y4 X }( v+ x; d# E/ M9 Z- I/ y
3 r& S  C1 A) o3 s# X& _; u5 ?5 N2 _5 ]5 K
CButton::OnMouseMove(nFlags, point);; k# ?. h+ N$ i+ Z
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
8 a/ k: Y+ ?$ Y) T{
# p0 K  Q* f* R9 I4 }, m m_bIsMouseMove = 0;3 o( V2 N9 K1 v! R, ]+ X
Invalidate();
return 0;
' ^7 t" W4 m3 |( }& _% Z, s}
void CHsPMEButton::PreSubclassWindow()
' {" Z3 g* B5 |7 J/ g+ W) [9 j{
6 n  h! C5 n) P // TODO: Add your specialized code here and/or call the base class
1 J$ V3 ^9 p) y" n: f UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
! E( k6 }- H* z: C; A SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();* n  L& U* s9 B$ d. e5 x
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
5 K7 o1 G) z7 ~" ?& A{6 g  q+ y" o* F  ~1 j% s
CPen Pen;# S+ E$ p+ |# n2 {
CPen* pOldPen = pDC->SelectObject(&Pen);
; C+ ]% H# W1 d) M' B
! y0 j8 i8 g6 U& C- e) Y9 [ int R, G, B;. ^0 U/ ?5 ~2 ?. S! r9 W  i
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
1 w$ j( J; t& g, K" I% j! ? G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();; N& H& J8 F  T- X
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();3 r/ b6 n1 T: o* R4 H5 `* t- k

4 E' {4 j( |/ |. E4 { //R = R>0 ? R : -R;
6 ^, D5 x, ^  U //G = G>0 ? G : -G;
" D$ c+ C# ^8 U+ J) Y. } //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);* |8 b  F! G4 h/ G1 Y
COLORREF ColMax = Top > Bottom ? Top : Bottom;: w) B* l& j! L/ }7 n$ q. k, k0 d
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)# |$ E8 _. j; x- v. W5 `; i" n/ u
{, R. N% v4 j" s0 d
  ColR -= R;
- K) @/ t! g; u- W  d6 k# Z  ColG -= G;
3 |, u" S  N7 n" ^* s' K& F0 h" }) ]  ColB -= B;
  /*4 p  i2 L  [! P" n
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||/ \* k- g. H6 L( b1 n/ G
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||5 Y8 N3 A8 L4 \6 g/ k! }4 A
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )8 Q- l) \( |' x* I& ^% Q, U4 ^
  {; B/ B+ ^3 u, n3 u* g( U+ B2 T
   R = G = B = 0;0 @! `" I; J; e9 r. R9 i9 N
  }///*/
) J# I  ]) q( c' x
  Pen.DeleteObject();
) j3 P  A8 {1 C1 h' o. l% r, j  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));! O7 o0 ^( `' b2 X
    ( d8 i, T& R& J% J, E) [4 J
  pDC->SelectObject(&Pen);
" n. R# N, `4 b) V; z6 u1 x0 [  8 c  X$ Z% p2 g  z& m
  pDC->MoveTo(rc.left, rc.top+i);
" u: J+ W3 ~1 f0 Q( d  pDC->LineTo(rc.right, rc.top+i);
  O7 V1 m* D( w0 I0 y  g: W8 C }
pDC->SelectObject(pOldPen);0 _$ U5 z6 f+ B/ D& L: d) b& ~
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)6 I, p' s; i8 @+ O
{5 t7 i! k1 c: Z6 K/ b9 f* x
CBrush NullBrush;
2 {, C! Q; o$ ] NullBrush.CreateStockObject(NULL_BRUSH);5 k% X  H6 _& j
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
5 G  n( P! Q$ l2 _8 t6 H: B Pen.CreatePen(PS_SOLID, 1, FrameColor);5 Z+ Z; d- U5 E6 ]) ]4 X
CPen* pOldPen = pDC->SelectObject(&Pen);* B6 A/ n$ V+ Z( ?8 p0 `

9 R4 F. Z6 |7 M2 m4 c' C# r pDC->RoundRect(rc, CPoint(3, 3));( r; f: x# }! `$ c8 C
rc.DeflateRect(1, 1, 1, 1); 4 O* N- p1 ?: Z) X1 H7 r
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
. F: E+ `2 p4 {% f( f: r pDC->SelectObject(pOldBrush);; c# K% v+ C" u, @
}

  E+ V0 s& E# }, T/////////////////////////////////////////////////////////////////////////////6 G9 B, V+ [! b; }* U
// CHsPMEDialog dialog9 c5 D* ]$ x" r  \/ [7 `
//------------------------------------------------------------------------------ T! {( f: N: w% j# g  q1 v
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
" H7 f) e! H% h8 Y5 H6 `//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
$ T) I2 J, C, Z7 |7 O" I//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口3 V( m2 L, O! O0 e9 Y
//   指针将其显示出来,然后隐藏或销毁自身0 h$ o% C5 v' T
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。. _! C) v1 d& s( Q+ y. y, V
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
9 G* N8 y4 Z3 j0 i; R  Q& P//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,9 X, s( R& n9 X. Y! h" k
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。0 ]0 [% B' U1 T: g0 i1 e" y
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
+ o0 \) m5 _/ N) d1 P9 h) Q& ]//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
) d+ A1 t7 D" o* J4 f; b( @//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。& i- Y1 o5 N! J" |% w4 ?7 p
//-----------------------------------------------------------------------------
% K2 E# [8 h; w( w9 J// 注意:
9 Z" @% d* ~2 e; L( H1 T// 1、在构造对话框时必须给出其父窗口指针
9 j0 g9 w* z+ U9 w' G, Q// 2、在初始化基类时必须指定对话框资源模板ID5 p8 N& w, j, k" A9 w% J$ X) i2 S
// 3、对话框资源中必须提供ID为IDC_BACK的按钮, W) R" \8 t/ C$ L! K
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
5 c" ?- u, r. c; ?//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
, k+ Q- B4 D- ~4 {) c. x" C{
4 `  p& E: x# ]" w4 G' E, [$ Y DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能# E1 T% B9 c( n$ w) J9 J7 z
// Construction
" M+ U& M& c6 x  D: rpublic:
) ]+ \! s/ f3 X4 M CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor& `/ \. ]% ]( T/ j( ]! Q& [
~CHsPMEDialog();0 T. D5 `& y' _1 a& x! z
BOOL Create(CWnd *pParent = NULL);5 q9 e0 g! m1 f/ a" ~

  G" ]- ?# a# G. f// Dialog Data
$ S3 U3 x: r7 O/ N" S3 y //{{AFX_DATA(CHsPMEDialog)
; `. w6 ?$ _( b0 l& t, O //enum { IDD = _UNKNOWN_RESOURCE_ID_ };
6 p; C! c* n9 u. c9 }2 n: H" I  // NOTE: the ClassWizard will add data members here- `+ U3 ?- k. C4 H
//}}AFX_DATA

5 l+ I3 R! V7 b7 o7 x  ?% V# ]// Overrides, }3 A* H: [, g0 _+ }4 D
// ClassWizard generated virtual function overrides1 y: Q. G! \2 y$ ~( B
//{{AFX_VIRTUAL(CHsPMEDialog)3 D: D/ |; H8 c0 D
protected:7 K5 H7 ^9 g2 p( e
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
# ^/ a, u9 V# ^# h/ m& g* X virtual void OnOK();5 }! \+ B4 B, Z6 s- F
virtual void OnCancel();+ z* i0 X$ o3 q" X
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);6 a5 C" ^8 m! T$ m2 C2 ^
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
1 r( G6 m8 ~# C" X# r9 r+ n7 H0 q$ g //}}AFX_VIRTUAL
// Implementation0 X+ B6 T+ k2 j& x
protected:
// Generated message map functions
% }7 N$ `+ {5 Z' H& }2 r0 D //{{AFX_MSG(CHsPMEDialog). Y0 ?; f- T" H+ K0 l# {$ U
afx_msg void OnBack();
/ \1 c" D) s2 K/ Q7 v. G virtual BOOL OnInitDialog();
" R5 v9 [5 N8 D afx_msg void OnDestroy();
5 B/ t; Q7 ~  i& g, @ //}}AFX_MSG9 A  ]9 t& y# F2 }
DECLARE_MESSAGE_MAP()
protected:3 S9 W' K, e& ?" g! ~2 }* B" R
// attributes
9 S9 D. b7 Y% W CWnd   *m_pParent;     // 父窗口指针
+ m, P( M: Y  n4 p$ x. z( X HICON   m_hIcon;     // 图标
8 E5 w/ Q  `) r1 D. M1 F/ x. n& I UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;7 X+ b" I. M2 C- P" ^- y0 N
CHsPMEButton m_btCancel;
, ^, ^$ m7 l9 {9 U+ _/ r: s7 V/ p. \ CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
& W* Z/ c3 I: A# |0 J/ T& b HHOOK   m_hkCBT;     // CBT钩子句柄% B' l0 L0 Y0 I; W: J* ]
( f# }3 y4 ^* ?8 o4 M4 \! b
//-------------------------------------------------------------------------) q# K: ]6 w9 ^8 u8 Q& E
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
( ~5 q7 ~' |7 s. \ // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
; L3 y; D* }$ [* o* r // 链表的头及下一个结点的指针0 Y* Z- q$ p( z  Q8 S
static CHsPMEDialog* m_spHead;& c% Q: ~' a4 N) n
CHsPMEDialog *m_pNext;
// operations
$ H* l' B% N2 C // 键盘钩子消息的处理函数* G2 T: Y( \4 N
static LRESULT CALLBACK KeyboardProc(* ^3 J: h( H" D0 W
  int code,       // hook code& D/ I9 n$ r9 s
  WPARAM wParam,  // virtual-key code3 C$ k( n# ^2 R
  LPARAM lParam   // keystroke-message information& a& A- K3 q( L) b: I5 @
  );
  k! k- A* u1 q; L* @* j9 r+ X& {# E // CBT钩子消息处理函数
8 ?( ]. A) o, b! a' B. D static LRESULT CALLBACK CBTProc(- {9 Z6 C# b) H8 ?* v! T- T
  int nCode,      // hook code
. n/ q* n/ P* L, N  WPARAM wParam,  // depends on hook code$ O# s2 d0 Y/ E1 ?
  LPARAM lParam   // depends on hook code4 m1 P5 q8 t5 G7 D9 h$ X
  );
: l+ f/ o8 E6 x6 n$ V1 i8 t: b% d
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
& D+ g( _, g$ H static BOOL  IsWndKindOfThis(HWND hWnd);
2 v$ l2 F) }1 `" n  V6 O // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)  P+ v3 X8 }. q# X0 c# A
static HMODULE ModuleFromAddress(PVOID pv);% A# P2 G+ z1 R/ T" m$ g7 H
public:
6 w2 h% y. l) U( q. q5 l" K // attributes
// operations
( e1 o; Y/ @' e: T) X6 P // 用于模仿UG的创建一个子对话框,同时隐藏父对话框1 O  G& z8 }) a
BOOL CreateChildDialog(CHsPMEDialog *pChild);; V" S) O7 y1 J/ `7 \# ?
};

% F& ~: @$ N/ G! C8 {' sCHsPMEDialog* g_pHsPMEDlg = NULL;3 L' M$ O: u& {9 c
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
( S9 e6 b( o( J1 R5 B( {5 _HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)% _2 m$ z0 U( ^* {4 l& c
: CDialog(nIDTemplate, pParent)
: K8 l" M/ M9 \) Q{& _7 E3 b5 H5 s9 k' K4 p
//{{AFX_DATA_INIT(CHsPMEDialog)
4 G) G( f1 ?2 l" A8 D6 x  // NOTE: the ClassWizard will add member initialization here2 S2 x! I, ]' W9 O
//}}AFX_DATA_INIT
, c( e0 m$ }( G" | m_pParent = pParent;
0 s: ~' d* H6 D3 Y) ^4 i& D m_nTemplateID = nIDTemplate;% W6 Q6 l1 a6 A, a5 V
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
+ M- S) v6 [! e8 z" B' D% | m_pNext = m_spHead;  \& Y; f1 `# _& {9 T
m_spHead = this;
/ f4 j' u+ Y) h1 d m_hkCBT = NULL;6 k" ?1 R3 `& H% R9 B2 X
}
CHsPMEDialog::~CHsPMEDialog()
3 S+ ^$ A2 C2 m0 v5 U{5 ^8 D! S  W4 \+ q$ K+ x
// 从链表中删除本结点
+ w2 p/ w# C) K CHsPMEDialog *pTemp = m_spHead;' Z) L" `" u1 V2 ?" v, t
if(pTemp == this). U" T9 l; O! c2 K$ R/ b
{
" _& I- ^4 O4 @" N7 B; h2 C  m_spHead = pTemp->m_pNext;
( T( S' n; ]4 j# E8 \/ h }) c; x. }' D) I3 W8 x; M, @! |: }! y
else2 C1 E, ~$ K7 s/ t
{5 t& t1 g; R% h% L6 B( L$ l( d; T9 {3 h
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
/ b% c' ^8 c, m  {; g1 F4 o  I9 {9 V! w
   if(pTemp->m_pNext == this)
" }1 t+ \3 b1 {; D8 X0 K6 @0 D! B% l   {
  [$ E; R: |; |0 ]: [    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
, ^5 X. W- o; n    break;- l* ^" ^4 e( u5 l9 R
   }
7 |4 W2 }7 |. K% F" b/ P  g: G9 S  }4 k: k( }; n8 z
}
% I- Q  H, s4 r}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)' G8 E( o- A2 G
{" @/ o: t2 p+ [
CDialog::DoDataExchange(pDX);/ Q" ]9 h+ |9 O; }9 X+ L' e
//{{AFX_DATA_MAP(CHsPMEDialog)5 D8 v, V) O) d; ^0 `6 ?6 P1 Y) F; q
DDX_Control(pDX, IDOK, m_btOK);
; B* Y! S: O* Q7 N4 \- Y: E, F DDX_Control(pDX, IDCANCEL, m_btCancel);) c# F$ [7 T$ J& w5 X
DDX_Control(pDX, IDC_BACK, m_btBack);
" I* q" x1 u' w( w //}}AFX_DATA_MAP9 y8 b9 d3 G+ C& `
}
0 l, _9 `, p! z3 M
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)1 }4 T7 z2 _+ V. {/ z* e
//{{AFX_MSG_MAP(CHsPMEDialog)
# A# q3 U. f; b9 ~9 _! x3 H- R3 M% Z ON_BN_CLICKED(IDC_BACK, OnBack)% G: f* Q; q6 x2 z
ON_WM_DESTROY()
7 F: ?) l0 r( Z0 {) i //}}AFX_MSG_MAP) Y+ L* J" L( L. T) |$ \
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////* f( o$ U8 L9 A6 A2 F6 \* Q
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */); o3 ^. B* T6 L1 j! W3 Y0 a
{
% P7 P" I8 g& K; [ m_pParent = pParent;- ]  e1 p& }' x
return CDialog::Create(m_nTemplateID, pParent);
0 ]$ `: N! S# A$ X}

/ Q. u" T" ?$ Z1 I" W' p; MBOOL CHsPMEDialog::OnInitDialog() 7 h2 e  [: u5 A7 L% g
{
3 ?( A" M- W- @5 n* j  Z1 ` CDialog::OnInitDialog();
// 设置标题栏图标5 Q, J. F0 L$ R3 R! F2 ?
SetIcon(m_hIcon, TRUE);( X2 A/ f8 I; h' Q; o
SetIcon(m_hIcon, FALSE);: J1 j/ }, ]  B+ d  H0 X

) G9 ?1 p, n8 x# R  f6 x% _ // UG的对话框的几个标准按钮没有TAPSTOP* U9 O5 {' g, B; G6 n$ c! s
CWnd *pWnd = NULL;
( }* ]4 `8 c/ e% E# x pWnd = GetDlgItem(IDOK);: ]0 @  ]) L" o) q
if(pWnd)+ W' Y& o. x' d! \% _! j' C
{
# \% i9 |4 V% h7 ]  pWnd->ModifyStyle(WS_TABSTOP, 0);
6 U/ _( `* _' S/ y5 r, S" H5 ] }" r" y: O. }* a& n/ F8 F& g
pWnd = GetDlgItem(IDC_BACK);
+ {) s5 f4 Q$ w5 O% Y5 P" f" u- H if(pWnd)
' g' d( p* E5 N$ B1 d+ @ {
2 D/ M! W0 m5 v! q  pWnd->ModifyStyle(WS_TABSTOP, 0);) a+ z1 p, ~" u9 t5 ?
}3 f7 L' w0 s9 B7 ^+ c
pWnd = GetDlgItem(IDCANCEL);7 c5 B2 Q5 v+ D% [
if(pWnd)
' z; R: X% x! I6 d3 f {
4 g/ m9 {4 Y# [# A3 p# M/ V( J% |  pWnd->ModifyStyle(WS_TABSTOP, 0);
( f+ g! R7 w8 u8 F7 D8 L/ e }
5 N4 T) M+ o% @: ^7 h( a) i/ e $ {3 L: s8 m: J. ?, w3 g  z8 [: y/ Q
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
% c' H) L: e2 c8 D4 } if(m_hkKeyboard == NULL)
6 R( j* |  {. ] {8 k: H% Q# v1 d! C3 B
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());( N+ z0 y6 a; l
}
! Q2 x+ {% H2 \; ~- J7 { if(m_hkKeyboard == NULL)
& b0 W; B+ S3 F% c/ g# e {
7 U6 _2 Q3 n) ]6 c% e, E5 w! E( B, @  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());5 ^% O: O% l' R, k  Q6 U; P) ^
}
if(m_hkCBT == NULL)% w: X# v4 V. t, [/ O3 b
{
5 `' V; ^; g! s* T% t  `  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());2 s. X2 V4 q8 p
}) i" a: }1 Z1 C. l( l' w5 X
if(m_hkCBT == NULL)
7 o2 W4 e( }  u5 H1 L( r {  f+ u1 [+ W6 c8 o+ Y  m$ h1 r5 ?6 l# C
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());
: E: z1 a8 L/ _0 z5 v }
' H$ V  \/ M! B# `
4 I. }) M" h' q# }) p; n6 a$ G return TRUE;  // return TRUE unless you set the focus to a control* J) C7 |9 w( X! Q9 ^6 x
               // EXCEPTION: OCX Property Pages should return FALSE
  w; S' X+ w5 U: k3 o" E, k6 M; H}
void CHsPMEDialog::OnOK()# E( Q! n* E; N* ?
{
! \, P/ |! W( Y" |/ `' ?$ j CDialog::OnOK();, F# P3 M) q) S$ K: p$ ~( x
if(m_pParent)
% p4 B  P& ?9 g* ~9 I! } {
* ^) p" J5 M/ W$ F  //m_pParent->DestroyWindow();
: o5 A% G: A( C+ V  //((CDialog*)m_pParent)->EndDialog(IDOK);3 Z7 l# F  ^7 N; T- G/ y
  ((CHsPMEDialog*)m_pParent)->OnOK();
- q: `$ s) Z# l9 Q }
! h8 |2 S5 w# v& z}
void CHsPMEDialog::OnCancel()6 |- W  x& X* {) L* n( h
{
# w0 Z. Y7 i( v1 b( o) ]8 ^ CDialog::OnCancel();
$ U% E: }: n8 M& r' g$ Y. ?! g if(m_pParent). K* n1 }1 P$ M3 ~: P0 z
{
, [0 i( A- Q* l; G+ x7 r3 Y  //m_pParent->DestroyWindow();0 }4 D+ l  z5 U0 ~, ^# j8 p$ Y6 w( R
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
- Q4 U) e3 B- Z3 x" y  ((CHsPMEDialog*)m_pParent)->OnCancel();
. l9 t/ D: u6 T! k }
0 y5 ]4 K& V$ o1 T) r5 ~}
void CHsPMEDialog::OnBack()$ k9 T1 T( \+ P0 e  t
{
4 H! F$ [) g  V( H: A, M if(m_pParent)3 Y+ r4 l7 y5 }6 {( u) J6 E
{
5 G1 _% c+ b1 C& {4 x  m_pParent->ShowWindow(SW_SHOW);. ?" |( x, D3 v6 S/ ~3 {
}
6 a" D" l% f5 r; P/ L$ v CDialog::OnCancel();! C. e) M! p# C# ]4 t, F& u7 C' A
}

: |9 k8 k1 t! b( u0 k1 M, \BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
* k8 Q, X4 `# h( ]{- |2 A5 U  _' W) @$ r0 F
BOOL bRet = FALSE;( R8 d* b% h7 p3 f' Y
if(pChild->GetSafeHwnd() == NULL)
: L3 H" s+ g& M6 r* x {
9 D4 G4 b- q  ]* g; |  bRet = pChild->Create(this);' G. C9 n1 l6 o6 N* h" E" s
}
7 J+ [5 E+ w1 S bRet &= ShowWindow(SW_HIDE);
+ N  F% S& T1 |# o$ N bRet &= pChild->ShowWindow(SW_SHOW);0 q+ x; `! [; o. d; R" x
return bRet;  ^% M! j( D' K* A/ a7 l. N  i  l
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
6 M  [, N7 @4 P1 m3 r2 f{1 |9 y3 N1 ~, m( L. \" A
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup6 \  }. C; ]# @
{
- D2 F; Y* H. E4 f( M- O  //TRACE("Key down/n");
/ i( y0 w+ Y8 w! Q6 f  CWnd *pTopWnd = CWnd::GetActiveWindow();8 U7 b! N- O* O
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
( H* q/ M& }/ T4 ?8 N* A& y6 S  {" ]  Z  ]% r$ r
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息  h5 c, Z1 a' {3 X
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)/ M( f. K$ b0 y- z3 G
   {
1 y8 S. C0 N, V    // 只截获tab、esc及回车键
  C* [; _5 l, H: V* A% t& z5 Y    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);6 w, \- {0 q5 O" T: G1 ^8 _( A5 r9 a
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
4 }* ?# H9 H" |. \   }
8 k* A: U' u# \% N   switch(wParam) {. H! V: _3 P  I; u- p- K* P. g
   case VK_TAB:4 |3 N* v0 X- `8 Y' j
    {
) ^9 @% s# D7 K4 S9 o. l, Z: ~     CWnd *pWnd = pTopWnd->GetFocus();% V0 ^! R' h1 t- @, j
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);$ G0 b/ R$ `! {6 J; `. D
     if(pNext)
! d9 r! i4 k* b, ~     {0 ?3 g! y' c/ T
      int nCtrlID = pNext->GetDlgCtrlID();1 b1 K& ]4 N2 ]1 n; x
      //TRACE("CtrlID = %d/n", nCtrlID);- d0 d* C# o0 ^6 N, p
      pWnd = pNext;
9 g+ }" c! z1 @: C4 f6 ?" T6 p      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
/ g* T9 h0 t& E8 u/ W5 \      {8 x( Z% E) a% q0 z* t: o
       // 根据UG对话框的属性,这三个按钮是没有焦点的! {* b- l* q7 Q3 W
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);8 Y7 I  v; O7 K" c7 X6 L! I  Q) E
       if(!pNext || pNext == pWnd)
0 Y$ a- F* u5 {- @! G* y. h9 N       {* A( L" n0 E8 H5 y+ g' Y' J  g
        // 对话框上只有上述三个按钮
5 u( l, W) y& J- D7 j        return CallNextHookEx(NULL, code, wParam, lParam);
2 f4 c: L7 r: W; K8 u) p/ Z! u% D       }
) \6 v$ e: I: u5 X       nCtrlID = pNext->GetDlgCtrlID();, z6 w0 P% J; z8 ]# ?" o8 O- c. j: N
       //TRACE("CtrlID = %d/n", nCtrlID);; L- l/ v+ S, H0 y7 Z% E. ^
      }
5 f: p8 p8 ?6 q+ d      pNext->SetFocus();- G% _7 {$ _' e4 @
     }" v, c- B$ q/ H: Y1 @) d) I
     //return TRUE;
5 o& H( t, z3 p# _    }- b# m; Z  n) d& k* U5 z4 Y" k
    break;& e( Z& }& D) F- ~
   case VK_ESCAPE:: D# b6 [  N4 S8 \
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
, Z' O6 m2 j! H    //return TRUE;) q8 t7 I$ J# ^. h, h
    break;6 X1 _+ ?% k+ S5 _, T! C
   case VK_RETURN:/ l/ A5 A. K3 W
    // UG实际上并不处理回车键1 _& }: C! [: [) p0 }
    break;: J1 Q& b1 A# H1 w/ w% ~0 F
   default:
7 b: [  C; p# g- l* ~4 f    break;
* {& k7 E+ \  n   }+ T: c, N, I0 j3 j7 P6 v$ |& ~
  }3 h8 g- }$ o9 |; D
}7 p( J7 N9 u! D, ^/ ]6 \2 `
return CallNextHookEx(NULL, code, wParam, lParam);
& P) f5 L* [+ i& |" h}
void CHsPMEDialog::OnDestroy()
  D; L" T7 O1 N{
- C, \, I6 m& F; Z) T CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子& L+ O1 p! T" k
if(m_hkKeyboard)
) `* r! |+ O  g {
" Y7 ^! Q+ A: u0 u2 F8 J: `  UnhookWindowsHookEx(m_hkKeyboard); 2 c+ P9 S3 }  \" Y6 ^. x
  m_hkKeyboard = NULL;# z8 n9 P" z! l/ D
}
if(m_hkCBT)6 W; q' P+ ?8 E  ]% X. ?- a$ A
{  w' r$ o* ]6 E% z
  UnhookWindowsHookEx(m_hkCBT);
% s6 I& U+ h% D  m_hkCBT = NULL;
% J: e( c' Y5 I* c  s) Z }7 G' F7 \/ a, ^" q" D# o$ P
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
7 P; g6 [' i+ s{
. Z+ {$ m, @8 e CHsPMEDialog *pTemp = m_spHead;
7 A; e: {9 v$ i2 ?; [! W BOOL bFound = FALSE;7 m# Q3 B, m1 ?
for(; pTemp != NULL; pTemp = pTemp->m_pNext)7 y2 S% s/ N; U$ I4 `
{
1 m8 d! U, K6 K, x* k  if(pTemp->m_hWnd == hWnd)
+ @* O5 }. k! T9 |2 z# Y% I  {. J9 Y& s. k: T: m1 P0 ]( D
   bFound = TRUE;5 N& T' Z1 p4 ~& w; V3 @
   break;& H& @0 p: H# H- U' Q) h& }7 @' Z
  }  j$ h% K1 w, O6 s/ K2 Z
}5 T) _, W7 j5 G6 I
return bFound;
. G5 {  b- d0 D* r; L" }/ z}
// Returns the HMODULE that contains the specified memory address
5 }+ {, T" P) L' H; Q% N! V5 GHMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
' n2 B( p0 I0 @$ S( x{
% Q1 N6 W; x3 w/ h
" C# D% r3 g5 n MEMORY_BASIC_INFORMATION mbi;# s( t) x8 T5 d# s! g4 [! g6 k8 q
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)   i5 v- e* b3 R8 d7 K$ P& q6 O
  ? (HMODULE) mbi.AllocationBase : NULL);
" d5 |) T4 G4 q5 _8 s}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)3 {% k/ j- j, H
{
7 B4 Z  F! v5 q! E; \2 d% b if(nCode == HCBT_CREATEWND)* y/ {$ U) r* t% ?5 J- a# h
{5 p6 {4 T/ o: }' @
  //TRACE("A Window is being created/n");" ^- P! a) X7 f2 n( e
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;; M4 z$ E" r. n% K( U! R
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
1 ]' w/ @# s. z  k; @9 X( b  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW)). Y7 h8 }+ u. t$ H, c- X  k* \
  {
; y5 S- J/ h# Y% D8 ?# g4 q   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
- M$ E) W4 C+ i$ e9 A# m! J% u   // 取得窗口处理过程内存地址! J( Z+ \" M5 t
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);* ]" H; E( L# t7 ]0 r3 N4 J
   if(dwUserData)
4 K7 Q. \! g% U' x8 k   {  h, \9 S" _: v3 }, O/ P3 `
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);( r# n) p+ E6 D* a7 V
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};1 h/ l! E. Z4 u+ h3 x8 ~9 @
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
& p" G; P3 y) W% z: N    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
% _' X" `; b2 N7 X, j    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
- h: s2 C/ J1 B  Q6 S/ k# m& b    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
1 G% t& ^8 Q- c* m) D( n: _/ [    if(stricmp(szUGPath, szModulePath) == 0)
- f3 H1 X$ [/ m! B% f    {3 Y/ f. @6 N  y" A! X) C
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
: f% ]' h, N3 A% g& h     if(_tcslen(lpCBT->lpcs->lpszClass) ==0), |# z0 P- P6 ^1 l- Z) f8 M
     {
3 ^9 S5 H; c7 q3 Y* f$ m! R      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)4 [- i! ^0 l  y/ l" v4 Y
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && : w( w9 M, c6 s4 r& e2 k( I
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
$ W: y6 X! J" r6 O+ {      {9 ^8 v* V: I' Q! b
       // 窗口非本窗口或其子窗口* j4 ~( Z3 Q4 Y6 g/ z
       g_pHsPMEDlg->OnCancel();8 A2 K6 r: z+ l) V
      }
! t2 r7 i( w1 \1 Z8 N2 W1 L     }
; G  N# ^, H/ R% u  v% V9 w    }; S/ _0 [/ s  L- O( I; g5 F( d
   }
/ Q- n! ~! M+ t  C  }# y7 J! j: g4 ~* p  e5 F
}
- f# O$ c4 B# q. R' J5 ^ return CallNextHookEx(NULL, nCode, wParam, lParam);
! A$ H$ ~! h* N4 I8 O. b}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
2 K2 z0 J5 u6 c, J/ s! d0 z{6 J# _% B8 S7 H
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来4 C- K( \% E, j  y. Q

" a  V, L3 }/ w, q( v, B( P% F return CDialog::WindowProc(message, wParam, lParam);
5 v) d& a+ ^$ P5 n, l}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
" V5 {1 n+ n' h: K; I" V3 C0 _+ w{4 o; z! J! {3 O9 L. o

( f0 g/ C- f2 I+ r' {7 h$ B return CDialog::DefWindowProc(message, wParam, lParam);
9 [% L  ~8 k5 o! B$ |}
9 G2 Z4 x* q8 T. l( v8 f
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了