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

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

[复制链接]

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

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

admin 楼主

2017-8-31 13:24:24

请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!

您需要 登录 才可以下载或查看,没有账号?注册

x
做过UG二次开发的都知道,在UG里做二次开发的主要界面就是对话框了,UG自己定义了一套二次开发的界面接口,即所谓的UIStyler,对于我们用惯了MFC及Windows的消息机制来说,它那点简单的事件映射,仅有的几个控件(好像连常用的树控件都没有)让我们没有发挥的余地。于是使用MFC对话框代替UG的对话框是每个从MFC进入UG二次开发的人的首先想法。关于怎么在UG中使用MFC对话框已经有文章讲过了,我这里就不再讲了。但MFC对话框的一个很大的缺点就是与UG对框的风格不统一。UG的对话框都具有统一的风格,首先,按钮都具有自己的风格,比如它的四个角是圆角,鼠标移到上面会显示一个Focus的框。然后它的所有对话框都是一级一级弹出来的,比如点击OK按钮,可能会弹出下一个对话框,而上一级对话框会隐藏掉,按Back按钮会重新返回到上一个对话框。再有,一旦有另外一个对话框弹出,当前的对话框都会隐藏或销毁。
下面就给出我的仿UG对话框风格的对话框类CHsPMEDialog,它除了实现了上面的三点UG风格外,由于UG似乎对键盘消息做了截获,如果是普通的MFC对话框,在UG内使用时一些特殊的功能键就无效了,比如TAB键、回车键、ESC都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
5 }. P, E1 a0 M) W// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
5 y) A. Q6 [2 P. l//    该类来自网络,稍作修改,版权归原作者所有
# ?$ h' g4 N2 G0 N//-----------------------------------------------------------------------------7 ^8 }' ~5 d. a1 O0 a& `( E
class CHsPMEButton : public CButton
2 R8 S# R. k8 b. t* n& m' u- U3 i{
7 c8 m0 r/ P: |9 u3 Q. Q // Construction
4 s5 n0 ^) b3 L0 G. u( L0 z7 Opublic:
7 E' Y3 O) [2 [3 y CHsPMEButton();% @% j/ v+ K& D: {8 Z+ o

* y% ?6 D- U6 u // Attributes
$ ]% I# ^# b# J! apublic:& w/ p- \: V5 m
1 r3 Y0 H0 |7 x8 a
// Operations
9 ^* h! X9 L  p& ypublic:2 v% Z& w! L1 ?5 k( \! @1 N
inline void SetNormalTopColor(COLORREF color)2 l+ U' P0 W" Q8 b5 L5 X1 a# o
{. F' V' ^& T2 v# Y5 N4 K, C6 u
  m_NormalColorTop = color;3 o; ~1 j* K5 e8 Y4 F0 D) A1 t
}
- V( Z6 B( m2 O2 w  L5 O2 q inline void SetNormalBottomColor(COLORREF color)' i4 @9 n' r+ e! v5 |
{; I; u' t; p- p) R! X, L
  m_NormalColorBottom = color;
0 Z& v! j  u7 m: b+ l }  b0 E' [$ F5 [. @5 c6 }
inline void SetActiveTexTColor(COLORREF color)5 R* k- o3 R% R
{4 i' q8 G) F: X# J6 d) A# B
  m_ActiveTextColor = color;
9 U; f8 c# W3 a# m3 N- e }1 z  ]9 q! J0 I
inline void SetNormalTextColor(COLORREF color)6 o3 a  s4 G1 a# l' B2 \8 r
{
$ d7 d: W+ W  T: [  m_NormalTextColor = color;
0 L( h+ d7 q6 ] }
1 t/ g7 b" |+ x inline void SetSelectTextColor(COLORREF color)# x) Q' ^6 J; s3 w
{1 U) V4 V7 s/ y! U" J
  m_SelectTextColor = color;
. B/ V9 m* T- P/ n2 X, Q# \ }* l  s8 V, C8 \$ v) ?
inline void SetFrameColor(COLORREF color)
" }# b( k& b. s+ c8 N6 @' M {# ]8 U6 V  r) E% f
  m_FrameColor = color;4 k( s+ d4 @+ u9 |# H
}4 Y' ^6 ^7 I& t
inline void SetActiveColor(COLORREF color)7 G# z* ^2 Y; v/ O+ S( E1 e+ u
{
+ N, R; @7 r' B4 P  m_ActiveColor = color;3 }+ c+ d2 e! {6 w, P
}: q$ A- \4 r: I8 W
// Overrides% t% p6 H8 z6 e! a
// ClassWizard generated virtual function overrides
8 N1 i' o2 {3 Q //{{AFX_VIRTUAL(CHsPMEButton); c% |+ ^7 Q8 u
protected:
' R( z9 q  q/ n; ~$ y5 ~; A virtual void PreSubclassWindow();
' e* A6 B; U) B$ ^9 e5 N7 C& z //}}AFX_VIRTUAL9 a, {, B0 j& s+ O; x

1 x0 V0 `' j: {9 Y, A, n1 U3 d! V // Implementation
# i6 O- T" T  @6 ipublic:
+ K) s& |# D/ S4 M! n; g virtual ~CHsPMEButton();
! a+ i* `- k3 O- m- ?, k4 w
) S$ F, g8 X. r // Generated message map functions0 W7 U, P6 f- o4 P( Z" L
protected:
+ b: G  ]* y! ]. Q- W //{{AFX_MSG(CHsPMEButton)7 `  S" D2 k9 M; \
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
8 _% |+ v8 @7 S) R! c# `- k //}}AFX_MSG) y1 s7 M1 {; F0 ]9 C: P. g

- @* b! I& X% d' z  Y4 C void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);- A$ N! n/ X% u- g* t7 m# N
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);; x2 F8 G. L" @% h
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );" f) A! Q$ ?6 u) x, L8 v2 H4 S
LONG OnMouseLeave(WPARAM, LPARAM);6 }4 d+ s- ?+ P
BOOL m_bIsMouseMove;
" f( }! M! T& O  T / G; e  X, \! h, Q
COLORREF m_FrameColor;
6 a! x! |; w$ M+ ^2 j- R; e COLORREF m_ActiveColor;6 z  s. p( @+ F5 [2 z/ E
; C! p' O9 P- M, x* |- Z
COLORREF m_ActiveTextColor;
% |( \; M* c3 U7 S COLORREF m_NormalTextColor;* t9 T% P5 h  c5 o1 S2 O$ z
COLORREF m_SelectTextColor;  g+ B/ B/ E3 \; c- L! r8 u. x

1 ~4 H  D, @4 P% X( R  S" v8 t COLORREF m_FrameHeight;) C  k: K  C% l! J+ C
COLORREF m_FrameShadow;
  L' ~/ N4 c. S4 }/ X2 B
4 i7 r+ F: M: m1 z  V! a COLORREF m_NormalColorTop;
% b9 C+ t( r) Y2 S  H COLORREF m_NormalColorBottom;
4 u) ~6 M+ d: z- o  F& q. N
% j' i' f) |4 q- @9 o! l DECLARE_MESSAGE_MAP()( c# w- E! Y8 U7 A" u. Y
};
/////////////////////////////////////////////////////////////////////////////1 O4 T, ?  n* i
// CHsPMEButton
CHsPMEButton::CHsPMEButton()+ e' c, t& l' D) C8 @5 x/ a
{
8 b  E+ d3 f$ Z8 \! H m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
, L; l/ N0 j3 @; W9 B! y m_SelectTextColor = RGB(0, 0, 0);2 \+ h* h) W, f8 }. F
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
/ F6 K8 T  ]  ` m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
1 A. v* r0 I2 A$ F- ` m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
0 \/ ^$ W6 m; M: M* a m_FrameHeight  = RGB(230, 230, 230);
% A0 o5 C% ^$ N" y2 I& {9 w m_FrameShadow  = RGB(128, 128, 128);
" o! [& b5 V' S# R  c}
CHsPMEButton::~CHsPMEButton(): M7 e  L8 A! Y
{3 a- ?. k; [) N6 n8 W2 U. Z, T
}

3 K. n: M+ S$ S8 W3 FBEGIN_MESSAGE_MAP(CHsPMEButton, CButton)' v+ B+ I( e$ \3 N
//{{AFX_MSG_MAP(CHsPMEButton)
, i* t% ^  E- W8 H( Y0 Z7 }$ M ON_WM_MOUSEMOVE()6 @; U8 n' G& _9 m
//}}AFX_MSG_MAP
+ c5 F( a% a$ E6 u ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
0 X3 v( k) G2 V+ H: W* [END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
, ?& k: _( C9 B6 R* G// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )' L, A4 e/ f1 i9 p1 {- G0 T2 i
{
8 `( h: @) m) I, l4 i& K7 l //*
& _* S5 I& o# ?2 ?7 w CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);1 \3 m% f2 ]9 t/ d
DWORD nState  = lpDrawItemStruct->itemState;
/ v) n% b- X- m" ]  l" A) ~$ C9 S2 S DWORD nAction = lpDrawItemStruct->itemAction; 5 W' [! D5 ~: y; W& N
CRect rc   = lpDrawItemStruct->rcItem;
& s( `5 Y8 L2 {0 m UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);- v. E5 S; A1 o. g8 N, M
CString strText;% D9 X0 X# Y' r+ ?& |% a) W
GetWindowText(strText);
if( nState & ODS_SELECTED )8 G- {3 [( `2 R( q7 v+ J
{* ?+ J7 H3 L/ U, s
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);3 E7 _" d) \3 s8 K( `
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); / L( Z) Y( |; ]- {7 ~) Y0 z$ ^
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);$ |5 r9 ?0 g9 w' y
}
9 P" T  ?9 \8 C/ N else //Normal6 |* ^3 P( k+ W# r  ?& Y3 `6 z
{
4 b& V9 D0 U4 |1 E/ z& e( H2 l4 R  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
8 {5 v0 m( w( b5 X  X  n  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);( `7 h* y. ^$ G. W
}
if( m_bIsMouseMove )+ t3 @% [$ v! i5 p
{
5 R8 `+ i( |8 c  _5 [# ^  CRect rc2(rc);
, n! F$ Z9 M4 w# b4 `; @7 m3 E  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
5 {% b: u' O0 g   m_ActiveColor, rc, rc, pDC);2 j& x5 N; e6 ?1 I4 ]" G
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
& j. x+ q3 p0 T- M8 k% ~  NullBrush.CreateStockObject(NULL_BRUSH);
/ q. w2 }: p: p+ `: Z  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);: e- V  i3 j! d. V" b, i9 K" [5 |
  6 _' }8 R4 H( w( C- P7 ]+ P: @
  CPen Pen;
+ T. e4 ~* N' ^' j6 f, e  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);: }3 R9 w5 ^* A( ~/ s4 `! P
  CPen* pOldPen = pDC->SelectObject(&Pen);
* Y$ y* g( m5 E7 V5 H7 l; L  rc.InflateRect(1,1,1,1);
0 Z0 y% }. j9 }( M* U" l  pDC->RoundRect(rc, CPoint(3, 3));( f/ ~$ u9 a1 H) ^8 g9 l5 J
  //rc.DeflateRect(1, 1, 1, 1); ; t7 W% ^' x5 |7 `# u% K6 z7 ^: F3 y
  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
+ [- T" y2 G$ u8 O# k  
+ D. p+ @" x! p- v  pDC->SelectObject(pOldPen);
+ Q1 P3 s: U' S1 z9 ]  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);- A) A$ ^( Q# V$ g; ~! {; e
}1 D, z, l. ^2 T7 ~! \

$ n! Z/ E: G( l) i3 Q# U. _7 o4 ~ pDC->DrawText(strText, strText.GetLength(),
9 [' s' d3 `" Y' ^6 a  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);9 E! c! Q5 M$ m
//*///2 Q/ q- y9 I2 k2 H
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
" T2 ~, W' t, w/ W- P, R3 x9 Q{
- @5 w# u  S  t/ J  ]  s0 p // TODO: Add your message handler code here and/or call default
( l# @7 H5 ]' D if( m_bIsMouseMove == 0 )1 N  e- F+ p; F* T6 R& }) a- d
{0 q4 l: [: b: K+ p3 @8 }1 ^. \
  m_bIsMouseMove = 1;% G2 E; h. k! P
  Invalidate();
  a0 T9 b9 r% N5 n    c/ V, n3 k" @1 D6 ^- w9 N, g
  TRACKMOUSEEVENT trackmouseevent;: _" M% V- B6 i
  trackmouseevent.cbSize = sizeof(trackmouseevent);( |' `7 z& M* B$ o( E
  trackmouseevent.dwFlags = TME_LEAVE;
5 ^+ F& _; b6 T- {" U  trackmouseevent.hwndTrack = GetSafeHwnd();7 j. v8 u9 @" E3 g
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;/ e: b  ?- `) D; h) d- u* @5 J( C5 H
  _TrackMouseEvent(&trackmouseevent);
3 U: @2 V5 I% j, a: J/ ?  v }) P% N. r4 h( {  _
1 V, ^3 ?6 J6 c. {: |7 N) D' F: w
CButton::OnMouseMove(nFlags, point);
$ q0 b2 }5 }- F/ x}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM): U( c2 @5 Y' u6 ]0 b7 T
{
) O  b$ w8 V/ P; n m_bIsMouseMove = 0;
/ a/ s( T8 N  w3 j) Z, }, Q Invalidate();
return 0;
6 C/ l& ^' F  M6 e! Y1 p8 J}
void CHsPMEButton::PreSubclassWindow() 4 U6 ?, k3 C9 \4 M+ h
{5 W8 y( y$ O) _. n  k
// TODO: Add your specialized code here and/or call the base class
0 a: X* Y4 p2 |& \& Z UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style1 Q! I& k! M( @1 L
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();/ a) d! c6 ]2 Z2 q* z$ @6 ~% z& r
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)! m: z5 B3 t/ T) Y
{$ m7 f5 I  i$ D: Z; a
CPen Pen;& X* q( m5 B2 O( r+ n. D/ I# K5 h
CPen* pOldPen = pDC->SelectObject(&Pen);+ K4 u  Y5 ?' P: n) T6 P! O8 x

  B9 X/ {4 L; w+ @ int R, G, B;
7 H' _8 E! ]$ y% N R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();+ y& J7 Q: T( M# J4 Q' Q
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
( q6 O  {) m. k8 K0 Q$ i7 ] B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
/ e" f2 m/ r! c
/ g7 K/ l# L/ R //R = R>0 ? R : -R;
+ W; \+ g$ P; p6 D  v6 E //G = G>0 ? G : -G;
6 ]5 s6 G; I* e3 ?9 u$ n' [ //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
$ U# t' N( H& ~, e; m8 \ COLORREF ColMax = Top > Bottom ? Top : Bottom;
: K# R6 t/ A$ ?1 {/ |+ n% Z0 m COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)- r4 j8 R: O6 N  u" O% v$ m
{
1 N! }" ]) @: j/ P8 k' Z2 Z  ColR -= R;
. \5 ]9 h( J/ R" o; I: [3 D9 |  T  ColG -= G;( q  u! @3 E+ P0 A" M0 o
  ColB -= B;
  /*
+ D5 V3 W3 v0 u/ U2 S! ]  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||* o6 z* k4 M7 p+ i/ A6 b
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
/ q$ e& P4 ]0 e   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
7 _6 E6 q/ @0 u5 L8 F* d. n  {$ r" Z- ~. \+ `4 j4 I9 o
   R = G = B = 0;7 x5 h7 Q* w7 A9 ^+ O' Z
  }///*/
, i$ b* S7 n) l7 b9 Y
  Pen.DeleteObject();
) k2 h0 ]: a3 ?; N) P, ]  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
/ P4 b+ j# Y# m   
2 q+ S9 o* @6 g  pDC->SelectObject(&Pen);
9 O1 s' g( c+ J/ N2 ~, E( X0 Z3 Y  
0 M2 M7 z, e) m6 b+ g( G8 ]  pDC->MoveTo(rc.left, rc.top+i);$ Z# j; n3 z* N1 k  v' X2 \
  pDC->LineTo(rc.right, rc.top+i);( v% m* m& N6 C, S* V, t% P9 s
}
pDC->SelectObject(pOldPen);
9 t% z$ ]7 o$ k1 x, x3 z: z}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
. y) |( `  Z1 e{
9 V# S5 z  S3 q) a  d CBrush NullBrush;
- F" e/ r0 g  ]# d3 n$ X. X1 z4 w, S NullBrush.CreateStockObject(NULL_BRUSH);% r' V& K" p: P/ F. l
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
3 K1 v0 y4 e  ^: |8 T9 O Pen.CreatePen(PS_SOLID, 1, FrameColor);9 ]/ z3 u' x$ s
CPen* pOldPen = pDC->SelectObject(&Pen);
0 _& A! V+ s6 |( Z( h7 K! e! {! v
9 ^4 s. x0 j0 u7 }* ^* W pDC->RoundRect(rc, CPoint(3, 3));* P# L( q( i, ]3 s8 ]
rc.DeflateRect(1, 1, 1, 1);
; j1 H/ ?, e3 c/ W8 P pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);: K0 k+ B' U2 B' s
pDC->SelectObject(pOldBrush);" A& d7 r' {2 n6 o+ Y0 n
}

$ W- z: d% j) v  ?  p/////////////////////////////////////////////////////////////////////////////" j; x: }7 }% M6 V% w# a2 D
// CHsPMEDialog dialog" b$ F8 S* w6 A/ d- o% A$ O- ^
//-----------------------------------------------------------------------------
# e. l8 \0 y5 b) a9 c) \! X// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
- [! ]8 K, `  S* B7 |//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
$ w0 d; M% E# R  J//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口' W- E& x/ G6 U/ q6 W3 `9 p
//   指针将其显示出来,然后隐藏或销毁自身7 q1 U5 M9 o2 I( c
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
7 F- T: V3 D2 p) g" F% c//    采用的方法为使用上面的CHsPMEButton作为按钮的基类5 s: p$ t# ]3 I; A: {* D9 m# u$ k
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
1 d% F/ Z- Z! o) u. G/ j8 A//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
$ L$ }8 h7 g) C$ T& J. P! V//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
2 c" x$ s) s# C1 }$ W2 a' z//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
/ N2 D0 @3 ^  |//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。
/ }0 B3 x7 j9 k- Q  Q* s//-----------------------------------------------------------------------------
6 a& N' D6 @- v( f// 注意:
0 ?7 Z2 A6 s8 ^- s3 S3 j) k// 1、在构造对话框时必须给出其父窗口指针7 z- E1 Z2 D) a( I$ j. _: f" l( a
// 2、在初始化基类时必须指定对话框资源模板ID8 x" u8 N- x" @& c- B' T
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
6 S& \2 f) o9 P$ U6 ^// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel0 u8 I) ]) N) Z$ _6 Q; Z+ k* ~% \0 @
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog' c4 i6 u( z' `% x
{
$ e' T$ ]" v# D/ y5 A DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能2 v& d3 x# ~7 V1 s, X5 e
// Construction
  f1 |! W# |" Y' D4 apublic:
9 O1 b: \( m# S2 D* X( ?* P CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor+ v! d; P8 D1 s: A+ `$ j8 e' w
~CHsPMEDialog();
- F% F3 k/ }" v6 G BOOL Create(CWnd *pParent = NULL);
2 G; n+ R' M0 V% z
7 }, D$ n2 Z: A// Dialog Data  X9 @+ q% f4 s% V7 a2 _
//{{AFX_DATA(CHsPMEDialog)
4 q8 B; [& v, I* f1 @ //enum { IDD = _UNKNOWN_RESOURCE_ID_ };
8 E; ]( B7 v7 t1 o4 U3 U  // NOTE: the ClassWizard will add data members here
* d5 Q6 c% F6 }! O$ |. H+ X5 K //}}AFX_DATA
: L6 {# ?! s% A9 g4 K
// Overrides" |( m; F7 T$ U
// ClassWizard generated virtual function overrides. K# E& Z( W* T5 u' @  e
//{{AFX_VIRTUAL(CHsPMEDialog)
) l) `- V& f4 q  C protected:$ e+ P# C' \: y4 C# O
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
7 M4 D, z# t  ?) e virtual void OnOK();
- D' [% B' l- w# t* Y8 d9 D9 W. n virtual void OnCancel();1 R6 U/ }# \* `8 w; M: G0 T
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);  c/ a% m& D. T. n* l- C8 U9 y- c
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
# r1 k5 f/ `+ _3 o; t //}}AFX_VIRTUAL
// Implementation
& U: n) Y2 D3 h" i5 e0 J3 mprotected:
// Generated message map functions
/ S; d6 U; Q) ~! |/ z! S' R //{{AFX_MSG(CHsPMEDialog)' }+ w0 Z& u+ a# i
afx_msg void OnBack();
7 y9 p0 R7 \1 P3 B/ r virtual BOOL OnInitDialog();7 @" U/ P' e1 \8 W" k* Q1 j! S2 ]
afx_msg void OnDestroy();
  }* M( Q* k( d5 ` //}}AFX_MSG  u1 L2 a0 t) u& X8 m
DECLARE_MESSAGE_MAP()
protected:
) c/ I  e& B$ m4 X- D6 @ // attributes
0 A4 w- R1 i( C, ^5 F& ] CWnd   *m_pParent;     // 父窗口指针
$ I0 ~6 Y% b7 l" D* Y) T! T3 n% } HICON   m_hIcon;     // 图标6 s5 n* n+ W" W( n" Q3 S
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
% V. H0 d: D) P, g CHsPMEButton m_btCancel;
. Q( Y. v' I4 C- [& U CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄+ W  w' L& j+ @
HHOOK   m_hkCBT;     // CBT钩子句柄+ R5 d- L# m/ ~" Z* [

- D( v+ s4 D2 W5 m) s, A //-------------------------------------------------------------------------
( Y, C8 f7 T8 c$ {7 e' n# T) @ // 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
5 \$ l+ @3 b; k+ B) T4 a6 R& H) \ // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为; P$ A7 ?  h/ Q, u0 C% T
// 链表的头及下一个结点的指针) P( p9 P* Z  C0 g
static CHsPMEDialog* m_spHead;0 a. P- S8 |+ ~1 R
CHsPMEDialog *m_pNext;
// operations
% N6 G9 ?/ o4 b9 ~1 z3 A& _ // 键盘钩子消息的处理函数# q  n+ f4 L6 o
static LRESULT CALLBACK KeyboardProc(
* k+ F% S* S! v& d- E4 O2 N  int code,       // hook code
2 A4 X8 M0 P5 S3 N2 {( u; r* I  WPARAM wParam,  // virtual-key code
3 s0 U  X5 _  f. F5 q, |9 B  LPARAM lParam   // keystroke-message information6 ?& k7 x( O" V
  );: n: ~- ~+ C4 u+ @/ O
// CBT钩子消息处理函数
% k0 W! C  v9 ]9 I; F) `1 F, v static LRESULT CALLBACK CBTProc(
4 o4 f, N+ }- s  int nCode,      // hook code
; }$ q& E2 g! V- J3 q! F4 H. P  WPARAM wParam,  // depends on hook code5 h3 W- I! W7 G8 L- v! k
  LPARAM lParam   // depends on hook code; c9 n4 E* r9 a' V& O9 b% {
  );
- b1 I9 u' T$ z' x8 z( D
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口( b2 H9 |' t% \% z  B* M
static BOOL  IsWndKindOfThis(HWND hWnd);
. L" F9 v8 M, \; I // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)$ a" f* @0 t" n6 P
static HMODULE ModuleFromAddress(PVOID pv);
* g( q' Q; \% R) d" `$ I  Y5 }public:
  U  F. X$ A* K8 D$ q) e // attributes
// operations; d+ h) n0 Q% ], ^, U& C* c
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框9 L: A4 H8 F5 j2 N& Q4 I, a
BOOL CreateChildDialog(CHsPMEDialog *pChild);$ V2 k9 {# F- F* i! z8 @
};

! x! g9 a* k, ?4 j3 h1 VCHsPMEDialog* g_pHsPMEDlg = NULL;
* ?# v) g5 u: ]6 R! J+ r9 OCHsPMEDialog* CHsPMEDialog::m_spHead = NULL;9 D9 X8 @" C5 r0 H
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/). D& l8 j2 _4 @
: CDialog(nIDTemplate, pParent)0 Q* z$ M2 y6 C( u4 y4 i9 {) Q
{7 _, c; R# Q) z% E* @
//{{AFX_DATA_INIT(CHsPMEDialog)& O$ b+ z' Z+ D& Q- P* e% a
  // NOTE: the ClassWizard will add member initialization here# e  a* `. ]# T$ X5 @% m
//}}AFX_DATA_INIT9 A% A# O" I2 w+ J4 v
m_pParent = pParent;
: K3 b' H  y2 `0 L m_nTemplateID = nIDTemplate;
0 b4 X/ ^6 Z4 t* {+ n% \) Y( C, t1 [ m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表% M1 |  ~$ f9 i& [% U+ J
m_pNext = m_spHead;5 F0 J: Q+ S$ z: t: S3 N
m_spHead = this;. T. T8 W3 F- ~; R
m_hkCBT = NULL;
4 C* }: z* @+ j4 z+ w! O& I7 E( R}
CHsPMEDialog::~CHsPMEDialog()
2 o# `4 k  ]4 Y{
+ D* s7 \! A, f // 从链表中删除本结点% |; ?: ^  r* {' \' g
CHsPMEDialog *pTemp = m_spHead;
6 a" F6 p( t. N6 z  m7 f' g if(pTemp == this)& S  x5 S5 k1 T$ \: V+ k3 w3 o
{' ?- S$ K  M9 a* X2 c& O
  m_spHead = pTemp->m_pNext;1 e# z5 @. h' @! l7 ~& V: u
}
2 D1 S+ e' j) L! r6 V else% }" |& s* Q* \8 D* \8 K% f
{' U& K% o  o- s8 j# \+ F
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
" \' P0 m8 r( C  {7 O2 |; d9 t" f- n  l1 b6 U' b4 s
   if(pTemp->m_pNext == this)
+ l7 H; a1 n# J) R, w/ m   {
# N, p; D, \/ a0 O9 A. |" Q! f    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
( @- A7 S, N1 F$ `    break;
0 J3 `& R* C5 G4 X' |3 o   }
8 q0 Y8 V3 o; {8 Q- W- y  }
" R- z2 b( k/ w/ o* l+ | }! k. d% ?9 w2 ?" b
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
' V7 F0 v: D- d9 D& j3 \* P3 r{
. a- |  S# p5 N& L7 l, Q CDialog::DoDataExchange(pDX);2 C* ?% f% Y# W4 G: N, s
//{{AFX_DATA_MAP(CHsPMEDialog)
0 }' ~# L3 E, `% L$ G: K- @8 z DDX_Control(pDX, IDOK, m_btOK);1 N# v' ?( d1 d. H' m5 Y! V
DDX_Control(pDX, IDCANCEL, m_btCancel);6 n8 {( T: V7 S3 u, v( f: @) B  ^! k
DDX_Control(pDX, IDC_BACK, m_btBack);& i8 S' I+ G- o% s
//}}AFX_DATA_MAP
! x2 L' Q6 i# N' ]" M8 }8 r}
0 m3 e% R% F: z
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)1 r9 t* L& ?: n4 D2 G) O' E
//{{AFX_MSG_MAP(CHsPMEDialog)
, n$ U: ~  ]$ A; H2 h ON_BN_CLICKED(IDC_BACK, OnBack)4 @8 e2 L$ q" R$ O
ON_WM_DESTROY()
/ g& I4 x6 t. e- b //}}AFX_MSG_MAP' J7 E1 G  p' t
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////' x3 i; v; N9 w7 k8 J, m0 T
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
% [5 ]0 T6 }1 W4 {5 ?{, c, [2 n. E0 t# ~7 o3 f, q% q1 Z
m_pParent = pParent;: [  H9 G' p+ J
return CDialog::Create(m_nTemplateID, pParent);
% r' o8 R$ ~; T9 [  b' D}

  ^) T( o; w$ J7 g  B; ?8 d0 qBOOL CHsPMEDialog::OnInitDialog()
" q. e- z% r( g0 T9 l7 O# V3 W{
1 ^! G  F- a9 V7 D CDialog::OnInitDialog();
// 设置标题栏图标; y' A! f+ l9 w2 e7 h6 `
SetIcon(m_hIcon, TRUE);* y1 Y% _4 g" s
SetIcon(m_hIcon, FALSE);
* J) W. Y- y9 p. O5 R' Y% K; q ! q$ d# S: k  Y. \1 @1 K3 I
// UG的对话框的几个标准按钮没有TAPSTOP& i/ q& m$ m7 \  ~4 G. w" y, l" o
CWnd *pWnd = NULL;
  i+ I! J4 _% {: d pWnd = GetDlgItem(IDOK);! U0 F9 L9 W( t( ]5 m2 G8 s
if(pWnd)
9 M' {& L2 w. q- V- H4 e {
) V$ o7 c4 B6 T2 d4 Z  pWnd->ModifyStyle(WS_TABSTOP, 0);* _' u' a$ t8 j5 d. h# q
}( `8 Q9 x' ?5 U3 m  U
pWnd = GetDlgItem(IDC_BACK);4 r- h6 q2 ]) q
if(pWnd)
* k* g: `% J* f) ^4 `3 r {
5 J8 k! c/ E; b7 L  pWnd->ModifyStyle(WS_TABSTOP, 0);+ z" p( e, h' h. E
}
( E; G; H1 d4 [* T& J pWnd = GetDlgItem(IDCANCEL);
) D0 X9 X3 o+ R( t. z( B if(pWnd)
* ^  b6 Q7 d+ O; ?- f' k& x {
- n; J) y  u4 u9 K  pWnd->ModifyStyle(WS_TABSTOP, 0);
7 Q9 T; _/ [' a- ?3 y$ V }
' ?2 P- _/ ^0 t0 @# e5 U# e
: M$ U* o! V% `" R g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
0 L0 r3 M1 b% I- t; d if(m_hkKeyboard == NULL)
( S* s* k" r4 O {
9 ?7 H. q' l. M8 C0 N7 ]  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
* ^+ p7 x7 M9 z, c2 h2 R }
" t- c) ~' z3 z7 X% v% Z if(m_hkKeyboard == NULL)* I7 e( i/ X+ n( Y
{
+ _" a) N& l9 |, k  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());8 P8 h" q& ^( M9 F- X0 S% j
}
if(m_hkCBT == NULL)1 s' |5 G1 D. w
{* Y6 S) p3 z; S4 v4 G  a
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
  P) n/ J1 B- S: M+ l/ Q }' V" }( D6 C6 y/ J3 E+ w
if(m_hkCBT == NULL)
% U) k7 Q$ _4 { {% i5 e; h+ r2 {4 O; B
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());- l) ?2 l7 V. v: ]7 Y0 t! j% C
}) s5 W: B# n- {+ K: U* [4 P) Q
4 H5 B1 H$ q  ^, a7 L
return TRUE;  // return TRUE unless you set the focus to a control6 c: p8 I8 S+ }
               // EXCEPTION: OCX Property Pages should return FALSE
7 A- H& ^: |7 B7 D2 V}
void CHsPMEDialog::OnOK(): O5 V5 o  [% z5 |2 F, ^
{( G* w0 k) F" l7 m) ~# N
CDialog::OnOK();
. h7 J6 u5 x( W: H, J# z$ ^ if(m_pParent)/ S5 L- A5 ~6 ~( D- m1 @9 h
{
% N+ b2 E  s' x% V: M  //m_pParent->DestroyWindow();7 h- D3 n' ~" H. @; Y
  //((CDialog*)m_pParent)->EndDialog(IDOK);
* p1 D: X% t0 G! L6 a' z  ((CHsPMEDialog*)m_pParent)->OnOK();
) f- K$ Z! `6 Y# z3 u- a }
0 ^  K1 T5 R( d0 V0 p  H}
void CHsPMEDialog::OnCancel()2 X5 {& ~3 q9 N( E) O% \# `
{
! w; G$ W) [; a$ Q6 e" z6 Q  ? CDialog::OnCancel();
7 W$ T0 @% L% b( c& C if(m_pParent)4 F! c$ k7 A! c; j$ A" b
{
1 u6 k3 t0 [/ M5 F7 V3 `- l  //m_pParent->DestroyWindow();, C6 ]! h/ @0 E# L) }
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
( X9 c3 B9 w  s5 ?4 K: J3 O; q  Q6 ^  ((CHsPMEDialog*)m_pParent)->OnCancel();
/ e( v/ Y# d3 d- b+ P7 D }4 |8 K6 U5 Q! Y. N2 `
}
void CHsPMEDialog::OnBack()) k5 N4 j8 z+ p
{* L5 o  h( h8 W. a& z% Z" `  C& P
if(m_pParent)
6 I+ g% [' i2 V* k! j {( K' g8 W2 m2 H
  m_pParent->ShowWindow(SW_SHOW);) S6 p% {3 t: V, G& Z6 R8 y
}2 d  h5 T& j! E5 e  F
CDialog::OnCancel();$ V2 ^; u: N2 y% M9 _- k
}

1 n" o5 F% A" |- y) rBOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)7 u5 N# z% x0 T. ?/ b9 E! f& U
{  r& i$ C" Y  }
BOOL bRet = FALSE;6 _' x) a" \& K# o3 D5 w" B
if(pChild->GetSafeHwnd() == NULL)" C5 p$ H1 \# `8 f
{, \2 }6 [& s* O; n7 X! [( f: e
  bRet = pChild->Create(this);
9 C$ [' [. O  x) k8 }6 ? }
7 c/ p+ x+ F# S7 i7 e5 I. ^* ? bRet &= ShowWindow(SW_HIDE);
6 P2 V7 l9 F: X+ H- @ bRet &= pChild->ShowWindow(SW_SHOW);
% z, `5 ~  g# h5 \* Q return bRet;
* |! `& E7 f3 I. O1 X6 c' S' a' M}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)* n7 n- U6 ^  i' k$ C
{8 G* }6 n& B# r8 K+ L0 t9 J
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup( j1 o% ?7 Z9 W; v; R, X
{
4 w0 \: U, t8 {9 K6 X  //TRACE("Key down/n");! z$ L, j, L8 I6 \
  CWnd *pTopWnd = CWnd::GetActiveWindow();' A# q0 r% A8 L% K& c
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
% c  M" B( d1 \. _2 Q/ M, Y  {- h& }( D" X+ u/ P2 C. O0 s
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
& y5 \9 k  q' F4 a8 r1 G   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)# L' e+ |- k& K& {! |* K
   {
* E% k% |+ V' P4 \- q    // 只截获tab、esc及回车键  ]' y' n2 F. m$ Y1 [- x2 R
    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
2 O+ u5 {3 V" w  v    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);# U0 m, t( V$ x. s0 F; B3 u( b7 o
   }8 M8 D5 C1 E4 J
   switch(wParam) {
9 k$ s2 N  K: y+ o   case VK_TAB:' [9 ~5 P! S' n* Z* `
    {- P: ^; \4 ^- e; k9 S2 T, ~0 h' W
     CWnd *pWnd = pTopWnd->GetFocus();+ j& i9 Y! S( [) g" _9 {( Y% a. X; D
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);1 v; X" p+ x/ R% z5 k3 j( X
     if(pNext)
9 V7 u* J$ A2 _1 O" N     {
5 Y9 W1 m9 A3 X4 X6 l+ o      int nCtrlID = pNext->GetDlgCtrlID();5 L/ O' g2 N) z0 u$ D* y3 W; T
      //TRACE("CtrlID = %d/n", nCtrlID);1 d  c; Y( v$ k' r7 U% z
      pWnd = pNext;% z2 [8 H3 W; j* O3 N
      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
, p* O2 D; i+ ]" I  N      {
9 h, d; M. p) ^* _. w& [       // 根据UG对话框的属性,这三个按钮是没有焦点的
1 q% B% U; i% S" y" c8 P, H       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);% L, U' q# A7 ?+ E5 R! x% C
       if(!pNext || pNext == pWnd)
  i+ T' {1 \6 l: u% V# t       {( C1 p! k" m" T6 W: I2 _
        // 对话框上只有上述三个按钮
0 V8 g6 ~3 h2 W+ T( X7 \        return CallNextHookEx(NULL, code, wParam, lParam);
: V* O( q% |+ ^# v       }
& u7 N# i  M' W/ L0 p       nCtrlID = pNext->GetDlgCtrlID();
" r, ]7 y" t4 @( u: B: I4 e7 _' O7 d  t       //TRACE("CtrlID = %d/n", nCtrlID);
; Y- G- f$ W" c0 S      }0 h3 w, E% O& O
      pNext->SetFocus();$ T7 G0 Q8 g2 d5 k! R+ n  e
     }% I; w$ m  h' y# v
     //return TRUE;% O! v' S/ ^8 c; t
    }
5 V( c; G$ U. D4 C; ~' K' n    break;
- R4 t' k+ t- L/ e* g7 H5 M! w   case VK_ESCAPE:  v2 i  [/ z' m: k! E
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
4 Y! {" s7 G7 P( e  ~    //return TRUE;
# C" _4 E! V! N& m    break;( V0 @9 F, ]; ]2 Y2 P
   case VK_RETURN:; r" s0 D9 w' K0 G  d
    // UG实际上并不处理回车键' m- H; A' w6 X% Q% h* y: ?) f+ V/ _
    break;* @0 |- m5 A) T8 l7 t2 Q
   default:
/ g5 k( C) T: F$ o    break;
, p9 K, C# h3 ~+ ~+ L* d0 j4 _$ u   }
- X- r- Y. ~; x: Q6 f( A! b0 n7 ~  }6 X6 ]/ d: ~( C0 H) {7 g" l  f/ \* N
}
2 Z' I  G$ C) |; g/ N: e return CallNextHookEx(NULL, code, wParam, lParam);
& \0 a3 L/ ?, n}
void CHsPMEDialog::OnDestroy() 1 h1 k  Q. e( Y, A, z% F5 \" ]
{
( b& {  v9 B3 k  p5 s, p CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
7 U0 R. [+ b) X: z; J! U# y) o if(m_hkKeyboard)
" [# R# G5 ^) \9 a0 {8 m( l" {# ] {
0 [4 a1 e; h5 m2 P  UnhookWindowsHookEx(m_hkKeyboard); ( z5 F: l9 \) w7 Z: |& D' J( D: s
  m_hkKeyboard = NULL;3 Y% R/ f. C; H( }- F4 S
}
if(m_hkCBT)
* P1 x$ C2 @2 d7 d {
1 n8 e% J& g* i1 [  UnhookWindowsHookEx(m_hkCBT);
6 A3 e" d/ Y: l7 K  m_hkCBT = NULL;
0 w* _6 u! N  v6 s }3 K3 P8 }) D6 z7 U  @$ ?. d3 Y6 W
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
3 p* s; E+ r9 W* M, A8 G( Y{3 C$ G$ O! L8 F; A  W9 d5 o
CHsPMEDialog *pTemp = m_spHead;& ]( m0 E/ F6 H1 J
BOOL bFound = FALSE;! D6 O' g9 J$ g  M+ v
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
# f7 T5 Y9 T! e  n+ r {, h9 T5 \8 `2 R
  if(pTemp->m_hWnd == hWnd)9 N4 i6 C" b( I0 {' O
  {( ^# J' @. o8 c, L- N
   bFound = TRUE;
1 V* y. v( l2 }$ H( Z& K5 m$ s; `   break;
4 M  f7 I+ e" h4 @" y% |: \8 |3 _  }
" g3 L* _7 y5 x }
1 Z7 o+ F/ g' M: y# ]( U' \ return bFound;  u! ^% K4 t1 [; F9 ?$ h
}
// Returns the HMODULE that contains the specified memory address
1 f* W/ S5 q: V2 G- @" ~& [HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
+ p$ T" N+ P" m  F3 |& K{
! `2 [3 c: q, y7 [3 Q: F: }
# \# O9 g" V* M6 L$ U$ p MEMORY_BASIC_INFORMATION mbi;/ q* i% W/ W5 ~  l) P
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) 7 ~1 g* R* D3 M9 y4 o1 N' d
  ? (HMODULE) mbi.AllocationBase : NULL);; C. a) i( Z  ~
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)3 w4 U: N2 u; H. @
{
5 e, ^5 p' q  J% z$ { if(nCode == HCBT_CREATEWND)) Z& {3 u- K, Y  W. O7 s
{
* e' Y6 A/ E& B, U+ z# r$ _5 U8 z  //TRACE("A Window is being created/n");
+ N2 j1 j. A- k: p  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;
9 u1 M% Y! y% L6 U8 a/ _  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);5 r/ n* E* ^  L) Z! D% A% O
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))+ G3 R% U; Z/ |4 r1 R+ ^2 e( |( u
  {
% C/ T+ w4 I2 ]% U   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
6 E2 A/ p5 X  v  Q   // 取得窗口处理过程内存地址
2 b# G% S2 m$ u$ }7 e% u" {   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
3 M) F4 i& h" [. V; H$ f& Q   if(dwUserData)& V4 e% Z( R$ N8 ]  j* L" Z& r/ y3 _
   {8 u* |  M8 c, S5 s9 r1 {* e
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
+ K5 f& L0 `+ v0 e# i( d    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};0 @. n) `( h7 g* U, e! g* W
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);" P" ^% h& i2 t3 w
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
' S/ S6 o  k4 ?    TRACE("CreateWindow Frome Module: %s/n", szModulePath);/ T; A' q) t8 l& P: x
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
5 O+ l/ z% T' N' ?* n    if(stricmp(szUGPath, szModulePath) == 0)
2 X/ a9 z+ X8 ^! @    {
0 m# Q( N: P9 Z6 m     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类): c2 y' K+ K) c: g9 X
     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)% V$ o% I) `! X( Z2 m. ~
     {+ i8 |. m  i, a" C2 G  }
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
' T. H+ c$ O; T5 H% J; E. ?2 i# r      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && / y2 I% H' s+ \- W- h8 A; y- \$ E8 N0 s
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
9 l  x! i( k( N; q9 ~      {( ]% t% c  ^5 u: n2 A$ a
       // 窗口非本窗口或其子窗口
' E% B8 Q3 _- F& ^       g_pHsPMEDlg->OnCancel();+ ~; I1 ~: h# o, n; ]2 U% P2 M% J
      }2 ^6 F+ b6 j) Z/ ~* Q
     }  Q& z* W, X4 [
    }
4 \) d/ s! V- ?! |9 V   }' Y4 |( P  G) N. q7 p6 k6 x
  }/ n; l5 y+ G4 W
}
  J' X1 a6 ?. W- }1 X return CallNextHookEx(NULL, nCode, wParam, lParam);
# J  W4 C! B# v  E* A}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 2 R3 m2 }# q. g/ y8 X; ^. s0 G+ L
{4 w+ B) q1 y% j% w3 ^& I
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
* h1 D0 z$ |6 l$ U1 S
8 d% B( o( b7 f) V+ A return CDialog::WindowProc(message, wParam, lParam);; Z  n4 J# I) I) P
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) ) C; T1 n( O( N+ X
{0 O3 g2 M6 i4 f7 E5 |

1 t6 K/ Y, k- c3 ^6 x return CDialog::DefWindowProc(message, wParam, lParam);8 q" E. G3 F) F( w  M
}
6 y1 M4 `5 L3 v- }$ B8 N; Z  T
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了