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

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

[复制链接]

2017-8-31 13:24:24 3291 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
9 v. Y, B) ~% L! a  m// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类) e; {) c, \9 h: U3 A
//    该类来自网络,稍作修改,版权归原作者所有
5 r. i  T5 Y2 V9 X( [# ?# Z$ D, T/ Y//-----------------------------------------------------------------------------
9 s$ D) s) W" iclass CHsPMEButton : public CButton
3 [0 O. d9 I3 q! t5 Y( ?{
! j; q1 {/ r; u' U // Construction' Q* \) E" u/ _5 b
public:4 {9 M" f* p  @- y2 ^: {: H
CHsPMEButton();! k; i- j4 i/ _4 J* i5 A6 w$ l

. D" _- A& D  M$ ?7 L3 D  @7 ?6 R // Attributes, x9 `5 ~1 B! T2 ~5 A
public:( v, B$ w" T* ?

9 k3 K8 ?- H3 D8 y // Operations* b7 g" f8 b2 g
public:
( B$ e" f$ N$ f2 F* g- o+ g4 k inline void SetNormalTopColor(COLORREF color)! v" {; J$ j, ?, l- Z- y8 w
{6 Z. e2 N# J5 a1 M! A* e
  m_NormalColorTop = color;2 i0 W1 S& m( y7 h/ {
}9 g) u# [0 l4 p% r4 F' `' O
inline void SetNormalBottomColor(COLORREF color)' }$ |) e# {, w; c
{
% {  S- y# j0 }3 M$ b, _  W, g& s  m_NormalColorBottom = color;
1 ]9 [8 F" j" M# F' ~1 \) p$ i }
9 E, A$ N" s4 ^& m inline void SetActiveTexTColor(COLORREF color)
8 G+ {2 W$ a4 ]8 u8 D) F {- V& ]+ n0 q4 s9 O
  m_ActiveTextColor = color;
- G  r& r! r! O& ]  j2 U( n }
6 E. p! P$ I0 n, p% \ inline void SetNormalTextColor(COLORREF color)
6 ]  W5 Y# Y! [& R/ N5 Q6 f. X+ n {
. I$ U5 x% O" V  m_NormalTextColor = color;) T7 n. ?: ?1 b! r7 F( w5 @
}
) J3 Y9 g4 X" V' Q inline void SetSelectTextColor(COLORREF color)6 T. a. Y- \- q3 S
{9 U  \4 q4 i3 f1 e7 v' F2 J
  m_SelectTextColor = color;
% u9 p; |# X4 q! ? }! W$ f: N9 O( w/ c& `: J, t1 Z" f
inline void SetFrameColor(COLORREF color)7 B- _/ w1 N* ], D
{
/ W: C6 M7 A* Y6 j0 Y  m_FrameColor = color;
# b, {' t) K( d }# r4 y; W* v: l
inline void SetActiveColor(COLORREF color). z* ^" z, G) i3 `  ^# O
{# w2 L+ Z$ X/ v5 C1 @7 l6 H
  m_ActiveColor = color;  q# v4 f, Z! s
}4 k: k8 `/ B6 G4 ?! y
// Overrides/ _# j5 q8 |# I2 a% A
// ClassWizard generated virtual function overrides7 L, D2 E4 D7 J; z$ {- n
//{{AFX_VIRTUAL(CHsPMEButton)* J5 d, Y7 t7 f  L
protected:
7 V& q; Q7 @2 Z' D6 F' j virtual void PreSubclassWindow();8 P' l1 y5 p& R  |- p8 J
//}}AFX_VIRTUAL8 M$ n  L( ?2 O* \' m
- `( x' \/ o' {* B# y+ r0 ~5 c: `
// Implementation
. n) J' u: V# E# z' ~public:
* x$ V6 X9 k# V/ T- u) x) } virtual ~CHsPMEButton();' {% h0 N6 t  a* y6 m& s% k
8 D9 U6 v& d. e1 e! Y' g
// Generated message map functions) A9 r; D! P4 V
protected:
3 E/ N3 I. O# W: b! W. s  Y //{{AFX_MSG(CHsPMEButton)
% Q5 I& q* C1 `1 ?! r6 V7 E: Q- E1 s afx_msg void OnMouseMove(UINT nFlags, CPoint point);& B1 A, y; D' w$ K: M5 V8 Y) R
//}}AFX_MSG
( H0 H: ?& l3 x& M% V8 x3 \* w # N7 C5 y4 A" }# L7 e* `& V
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);4 a: @9 G9 v: H$ a8 I% X. C
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
( z2 n) f* S% E/ B5 ` void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
; [- C9 t2 e8 \" y LONG OnMouseLeave(WPARAM, LPARAM);
9 ~$ l& Y9 u# Y- S' V BOOL m_bIsMouseMove;
4 P: K! Y$ Q% Z: t' I: u ; `& m) G* w& N5 B2 w
COLORREF m_FrameColor;* C  i/ G$ Y: ?. }- O4 H+ C
COLORREF m_ActiveColor;) z* [( M8 D" H/ O
/ o8 u: p; i+ I+ J
COLORREF m_ActiveTextColor;0 ]1 g- z3 c4 z/ `- o# j
COLORREF m_NormalTextColor;9 e) }$ Z1 M' p$ Q, U& {$ T4 s
COLORREF m_SelectTextColor;" x, [1 E' h. t  Q3 E" A1 M; l  k

; b6 v, P: o$ ?# ]' z COLORREF m_FrameHeight;
# j* _) b' D* b& W8 B7 ]8 ] COLORREF m_FrameShadow;
) S( }8 z8 k# [8 b 8 Q, b3 g) w8 Z0 q* i9 c; D8 G
COLORREF m_NormalColorTop;
5 B! @4 Z% N2 B) z  r  M0 } COLORREF m_NormalColorBottom;+ X" X$ ^5 t/ o) d: T
2 k% H* k& s  m( @  i
DECLARE_MESSAGE_MAP()
2 a! q) |$ J% s+ [1 ~5 g; ^7 a};
/////////////////////////////////////////////////////////////////////////////' F2 ]3 ~8 e( _3 n1 Y9 Y1 ^
// CHsPMEButton
CHsPMEButton::CHsPMEButton()
6 Z: W7 @* s! _  Q6 [6 N  ]# W  s2 o{
* g& f' r- S/ H2 E4 s/ V m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);. k. o: L# f1 c& r! J6 i8 B
m_SelectTextColor = RGB(0, 0, 0);: }5 v; r9 U# M# p3 U# I
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
, l/ R$ ?4 b8 k% L! }8 ]* F0 w m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色0 `# y! ^& l7 H. R+ v
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
6 [6 l: K9 f2 i, B m_FrameHeight  = RGB(230, 230, 230);
6 g+ G% ]' M/ g+ j( ~. Z8 G m_FrameShadow  = RGB(128, 128, 128);
. v+ q& r  C/ E9 p) }}
CHsPMEButton::~CHsPMEButton()
% s7 \1 y! Z! c7 L1 r% N: `% q{5 f6 W6 J2 S0 t
}

3 O0 B; q+ j( L2 O) }! u. WBEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
# B& \2 d4 w9 d* {5 z //{{AFX_MSG_MAP(CHsPMEButton)
$ e6 K) ?9 l2 s& X0 l  W0 }0 V1 z ON_WM_MOUSEMOVE()
' l- _# V) C$ G) b5 [: H* T //}}AFX_MSG_MAP+ Q; {- }; D& E, z. M2 U
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)) f  ^6 D1 s$ _# h# I! _
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
# Z* r1 i+ c4 f8 y# h! h0 i! W5 [// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
7 p& G" v/ c3 ]: I* \1 h) k, b{* C6 z) {- w" G& x- f
//*
& \: Q+ y: @1 F CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);" s# m! w1 k3 ]. W: U  {, G
DWORD nState  = lpDrawItemStruct->itemState;
& R6 I, a& u7 R9 i! R* ` DWORD nAction = lpDrawItemStruct->itemAction; 0 j8 R# i( s; r& k. ]
CRect rc   = lpDrawItemStruct->rcItem;
6 J9 w. j; E, V  _4 Q+ m. z UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);  \( }  P8 {2 L8 }4 p
CString strText;1 F) t' P" I) {  Y1 e( n9 _% C
GetWindowText(strText);
if( nState & ODS_SELECTED )+ k2 x% t% f1 a
{
, D( E$ ?5 ~* Y+ p  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
# |2 a6 C5 q5 l' F! S7 A* t' p5 ?& S  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); / h8 R/ n; [6 Y. N
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);! X6 S- N  {& G0 x/ n6 w0 {8 c
}
; i0 I3 a& p& e" X else //Normal
3 O* b( D4 L3 n4 R {' O& A- U5 p4 I5 c, m3 U, D7 K
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
) t2 e& t5 {# K" g, z2 v. W1 W  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
0 {- D& Y4 n/ I; {4 T }
if( m_bIsMouseMove )% o2 m! P. T: g' o" S! B3 U
{, ?2 u; `6 v; a: i9 x* E
  CRect rc2(rc);, Y) u% Q# M7 w* M' i3 N
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
, ^5 A/ ?* o7 k* @' F" y   m_ActiveColor, rc, rc, pDC);: j5 r" I! y' b: B
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
8 V! ?1 Q3 ^7 `! G* @  C. s% W3 l  NullBrush.CreateStockObject(NULL_BRUSH);1 {- i& X% O/ a8 I6 b
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
3 G1 b0 r! k' M/ s+ x+ S  + m% K. y6 o& |! M: X% q2 C  J
  CPen Pen;& D( c& ~9 S8 }% c: c. r4 n
  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
2 R/ v' q, H6 Y+ v7 d4 Z  CPen* pOldPen = pDC->SelectObject(&Pen);
# j1 f+ f$ |! x  rc.InflateRect(1,1,1,1);
4 |1 c6 S$ ^$ L1 i2 Y( v  pDC->RoundRect(rc, CPoint(3, 3));
+ B3 N+ r+ Q$ a  U/ Z$ m1 V+ B& G  //rc.DeflateRect(1, 1, 1, 1); % X; R4 I* K; s6 d
  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
# Y4 L# N" G: p2 x7 M" ?8 c  
. }) `* C4 j2 }; G5 y  pDC->SelectObject(pOldPen);! C% {5 ^6 N( \2 D: V4 J, A! B
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);* ]: y- K' `, g  r( R
}
2 C; ^& ~6 z' W% s 0 i8 H6 Q3 u( z/ Y, A
pDC->DrawText(strText, strText.GetLength(), 7 P) J1 l" S- O+ C9 R  M( o# A
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);# v. m6 {$ l, v: ?  d  W, P
//*///$ K( l" T7 V8 L* N" |" q" x
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
1 |( ~3 A( I8 `# ^) q" V' N$ P{* H- e' I1 I% o' z
// TODO: Add your message handler code here and/or call default6 F! \+ y; C9 J
if( m_bIsMouseMove == 0 )
% F3 P1 ^) a' w# l {1 ]0 o, A8 g5 K, {6 y# {
  m_bIsMouseMove = 1;5 P+ ?+ I/ z$ Y5 M! j
  Invalidate();) Q9 L' v" V# V; ?$ l! Y. _
  - z) h5 T& G! v3 h
  TRACKMOUSEEVENT trackmouseevent;* u, O1 Z$ W6 ~% w  ~
  trackmouseevent.cbSize = sizeof(trackmouseevent);0 j8 i0 w- `8 f; Q
  trackmouseevent.dwFlags = TME_LEAVE;; x6 s. K) S7 x9 n
  trackmouseevent.hwndTrack = GetSafeHwnd();
. L4 J9 C5 t) w4 a& L  trackmouseevent.dwHoverTime = HOVER_DEFAULT;  s/ u0 x6 ?/ n) B0 u: j
  _TrackMouseEvent(&trackmouseevent);
- p# P/ I- W0 H9 O2 \7 V( w }
1 I1 b+ z6 j4 t; u: J5 O; r
4 t- n6 _6 |3 Z/ |0 ? CButton::OnMouseMove(nFlags, point);
( q$ L% P  Q2 T4 O7 H}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
7 K9 A; k# u& V2 G0 G{$ v( l6 N1 R) \' ]
m_bIsMouseMove = 0;8 s! r4 Z* V+ _  J5 O, U. ~
Invalidate();
return 0;+ J+ W4 R0 c; J- b0 e9 T8 z8 w5 q
}
void CHsPMEButton::PreSubclassWindow()
) ^6 b) x+ ]  Z5 k0 g8 \& c{2 R! \2 L) B. k0 [1 N8 R
// TODO: Add your specialized code here and/or call the base class
' f, b1 N' B0 k1 ?2 W UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style% l" e$ g) d+ ~+ P! C/ c
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();+ e2 J4 h( U- G) w; ^, r2 L
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
! R3 R% ]8 H5 a0 f) C# d. d8 g: C{+ j3 H4 A6 L$ o: D/ }9 |
CPen Pen;1 |# L' _" X+ b
CPen* pOldPen = pDC->SelectObject(&Pen);  m% A1 @8 T& k/ w
7 x/ H5 x  Q0 B! D
int R, G, B;
- C6 I+ r1 l, A% ?, }4 ^ R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
4 g, L" x; \/ X G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();- k! Y; P1 d# Q, |3 |9 W0 D
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();& e  W) g: U' l
$ b) H# Q0 h+ r# F4 O& y
//R = R>0 ? R : -R;0 n1 o8 [3 }# M; n) K2 g% O
//G = G>0 ? G : -G;
; T/ L, ]; F& U0 s( P3 J( p //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
, T' q8 r- @0 s: O" C5 L' i4 t$ E* L COLORREF ColMax = Top > Bottom ? Top : Bottom;
' @  `; I$ ]# n1 {& ^* H# h, F COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)0 h( e$ P, x8 W/ o' j6 ]
{" `0 s# u# ]* y1 z1 ~5 Q5 t6 c4 _) a
  ColR -= R;
  Y  \! k- `5 S4 n5 E  R% `  ColG -= G;! i+ b/ T, h# C( W' n* H" p6 w; `
  ColB -= B;
  /** V: ^9 |5 n5 c0 s% e6 c2 \
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||" r0 I/ i5 c  m) ?9 C( v* u
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
/ k6 x' h  h, ]" u& X1 }4 o   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) ); X. X3 u8 X& ?' m& j. B' w8 Q/ {2 ?
  {5 }! F* t+ Q7 l* M: w
   R = G = B = 0;
$ S* I3 y5 r4 ]  q* Q  }///*/

' z' ]$ a- i: `# S  Pen.DeleteObject();
3 z1 }, D. V% F  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));; j) |) m$ u9 ?9 j1 L0 E& w) C+ ?
    0 S1 I9 [8 P* G, \0 q3 G
  pDC->SelectObject(&Pen);- g4 h$ {4 B, @" N$ T! H
  
* V) m. p2 Y/ w* |  pDC->MoveTo(rc.left, rc.top+i);
% O+ c5 s' g4 K% T. M" }  pDC->LineTo(rc.right, rc.top+i);
( ?/ t4 y8 f' A$ q& O9 l' |* E }
pDC->SelectObject(pOldPen);
2 z" u3 P/ G  e  j9 O6 s}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
9 w2 J+ Q. |% x( J' y. r5 m4 Z6 [7 [{
* e) i* r7 h: J/ m7 m2 N# { CBrush NullBrush;
3 R. P$ |' y" P1 l' ~- O4 n NullBrush.CreateStockObject(NULL_BRUSH);6 q7 A% F# @- c$ O
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
6 F9 q/ H+ P; h4 J# F! e# @ Pen.CreatePen(PS_SOLID, 1, FrameColor);
9 e3 D# w" e  G2 y/ E; \ CPen* pOldPen = pDC->SelectObject(&Pen);* ]5 \! u* b6 Q# `# K

2 Z4 t* y6 Q# d7 `, P: z  O pDC->RoundRect(rc, CPoint(3, 3));
' }% v, S. w4 P5 e) G rc.DeflateRect(1, 1, 1, 1); 6 _/ s. D- Q* @, [7 O& c0 D' K  V
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
9 J5 B, m2 Z( q& Y pDC->SelectObject(pOldBrush);
+ K* c: z$ g6 N5 T$ \9 R! d}

, g/ f" g' |9 S/////////////////////////////////////////////////////////////////////////////
2 [5 n* K4 h# V- _1 a// CHsPMEDialog dialog
+ K; H4 D9 o( Y* Z/ X: b//-----------------------------------------------------------------------------
- [  p3 D; j& \1 L) P// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:) b5 {% ^( p+ N
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级# u/ K9 ^$ G( P4 t
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
: V9 |% g1 K. T$ u, h; `0 S//   指针将其显示出来,然后隐藏或销毁自身
3 d5 @; i# v8 y9 N/ Z//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。4 X0 s4 @3 S! u9 z" T
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类# `* e( t# k( w2 @% g6 Q
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
) ^) M1 w- Y1 P5 b" N; J1 F) S//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
1 b% o- i2 E$ X7 L& L$ _1 D4 [+ C//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。5 u( A' M7 p& h
//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
' j, P9 R2 A1 j9 ?7 ^//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。$ j" E+ ?  q) @
//-----------------------------------------------------------------------------3 L- k# _: t* g/ i( v% z4 b5 i
// 注意:+ O; L* E) e- R
// 1、在构造对话框时必须给出其父窗口指针
, }- B1 i/ S) f0 y* _, b3 ^: g5 r2 n3 A// 2、在初始化基类时必须指定对话框资源模板ID, H$ S8 p) X% i& q  ]; x+ L* I- i
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
- a6 q* G7 F  y+ j// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
4 h, y4 K) z! ], v' ]//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog7 N; L$ t) v/ N+ m, O
{
" e$ Q, @3 Q$ ]  A+ R3 W$ k DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
* [  G) L  E+ F! ~" j) C// Construction
" f9 t1 _& f# {# T" |# [) rpublic:
" x4 M8 {3 B6 W# Q CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor2 L% I0 H$ O5 K: R
~CHsPMEDialog();
1 X- w) t- d7 L9 h3 i- A8 f BOOL Create(CWnd *pParent = NULL);
- L0 L2 f+ B1 J2 @/ C. b1 W
# y( ]2 \" i0 [: Q" U+ k// Dialog Data
9 w8 e4 W7 v6 A/ [; E7 j //{{AFX_DATA(CHsPMEDialog)9 l" z# O  d6 Y* G1 f  K
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };
8 }. h6 K( L# N$ V5 C  // NOTE: the ClassWizard will add data members here
8 e: L; {5 ]% u+ c% S8 h //}}AFX_DATA

; G. v3 M, H5 _  S3 V, N// Overrides
! j! y( T* Y* N. R2 y // ClassWizard generated virtual function overrides# p7 E: z: D: s* i" c" {9 i8 H- f
//{{AFX_VIRTUAL(CHsPMEDialog)
5 ^* O4 u! N& s6 g. p3 y  r; x protected:
$ X& S8 s3 I* y' a virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support" i& d+ y, T0 K+ C
virtual void OnOK();0 f/ e& y/ {7 _, F6 E/ C9 k
virtual void OnCancel();- x, U% a9 b% b3 }
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
) {% Y2 w" X1 Q" W virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);0 f9 m0 X' {& \' M3 v
//}}AFX_VIRTUAL
// Implementation
3 t& x% e7 [' ^7 J9 h+ j" \/ i% Dprotected:
// Generated message map functions/ ~# z! p: Q1 r) L
//{{AFX_MSG(CHsPMEDialog)0 j  T0 R* \7 W" U1 A- g+ L$ K
afx_msg void OnBack();
, e6 V1 u. n  g/ K% w virtual BOOL OnInitDialog();5 y0 f4 x9 p/ Y
afx_msg void OnDestroy();' X7 C2 n+ q( U: C. p+ X
//}}AFX_MSG
; e/ F: c( l. l7 m/ U0 H* {2 D6 l- N DECLARE_MESSAGE_MAP()
protected:
4 H# C- R) K9 D! @7 e* ]# A // attributes" H3 f: x0 M: t+ g  p4 D
CWnd   *m_pParent;     // 父窗口指针' d/ a' a( f# `5 T( Y8 Q% o
HICON   m_hIcon;     // 图标; L/ y5 k* Z6 T) u. U% ~2 Z6 @( W
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
. u* C5 f6 i3 B4 {) f- ?4 { CHsPMEButton m_btCancel;9 B1 T" A4 A/ e# p/ ^1 m
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
: ~& }8 C6 r- | HHOOK   m_hkCBT;     // CBT钩子句柄
/ ]7 @$ c6 V5 r+ N& s$ [ 1 F6 Y$ G5 f: }& b. \
//-------------------------------------------------------------------------# x, X' }& y0 F8 V; D' s+ _' i4 f: @
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
4 W$ I  _) Z- R) `- r' | // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为' ?) V0 E- W4 c! [, t$ {  r
// 链表的头及下一个结点的指针
. e; N( d# L2 O4 z static CHsPMEDialog* m_spHead;
& d. m1 V" i# |" Z8 q# i8 e) ? CHsPMEDialog *m_pNext;
// operations' Y  [! \  S& t% _6 Y* B
// 键盘钩子消息的处理函数
1 ^$ ~1 {1 y, O1 R) c; A6 I static LRESULT CALLBACK KeyboardProc(- D* c: i6 C9 J! G* x  A2 H5 Z
  int code,       // hook code
' _- ^  ?! ?0 i. ]6 ?& z# m  WPARAM wParam,  // virtual-key code6 K+ ~! u. e3 ?
  LPARAM lParam   // keystroke-message information5 S8 S4 M) F; m. ?8 ^; x
  );3 ]3 q. Y$ N' V4 Y+ |/ I
// CBT钩子消息处理函数4 L. w* l4 P! A5 w
static LRESULT CALLBACK CBTProc(
. \( X" p3 L' z* I; M  u  int nCode,      // hook code
( X) u  H# k! N7 \) o  WPARAM wParam,  // depends on hook code
: F. `) @% m4 a- ^6 W- P  LPARAM lParam   // depends on hook code. k! j* o. a4 H  |
  );1 p4 C5 C5 r( }7 z5 S0 Z* ?
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口5 V& a6 @" z5 a* t' _, d5 s% A8 d5 V+ m
static BOOL  IsWndKindOfThis(HWND hWnd);. d7 J  \; p' m
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
$ s5 g# m- P* G- W5 [4 [6 ?- t; T8 u static HMODULE ModuleFromAddress(PVOID pv);. t' Y) A* G4 b# W/ g' ]
public:
, b: Z) f. b8 A/ ~# Z, F // attributes
// operations0 V' b% c3 \2 V% K3 |3 p% f
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框9 w& n& _, F; w1 J' R8 v
BOOL CreateChildDialog(CHsPMEDialog *pChild);$ g: {3 |4 W1 L. ^* Y/ z( z7 w
};
! Y+ S. w) N* v$ z3 a5 w: f5 l+ U
CHsPMEDialog* g_pHsPMEDlg = NULL;9 P4 w2 n3 R, S
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;; D/ M, p; p8 F) `- b
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)$ i% _* p' t& h, [
: CDialog(nIDTemplate, pParent)9 a$ T0 a, t, x4 f+ T( m
{
! `. H; O. m0 {2 ?9 G //{{AFX_DATA_INIT(CHsPMEDialog)7 p$ c0 R# p/ g6 @4 c6 r
  // NOTE: the ClassWizard will add member initialization here
! L" P% [$ B  V8 i //}}AFX_DATA_INIT2 x; ]# Z& V$ Z* P' |1 _
m_pParent = pParent;& S. t3 Z& P; c! ~1 J6 e
m_nTemplateID = nIDTemplate;
6 k4 @# B% }, c, d3 n) P8 V m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表" a( C8 `9 c; `* a7 G& {( f9 A
m_pNext = m_spHead;( V$ A; V; X+ O: S# U
m_spHead = this;
* f8 h- `* L. @- ] m_hkCBT = NULL;% Y. A, y. K. C% U; o; q9 J
}
CHsPMEDialog::~CHsPMEDialog()
) Q4 ^, ?0 s2 v{# E) U# A5 _' [0 N
// 从链表中删除本结点0 c9 v5 Z8 B, o; J+ G
CHsPMEDialog *pTemp = m_spHead;
& B( T5 L- J3 a. o- v) c* U if(pTemp == this)( _& T+ G2 V- `4 c- @
{
% K- u! W6 d  P3 t  m_spHead = pTemp->m_pNext;
" ?, p$ m. r7 j' n; H }
* o" S/ y4 U& b else# i$ D- ?% i) I# w0 b
{
+ U3 B0 l# Z+ R. E( p  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)$ M: [4 n* {0 \! e' B
  {
3 c0 p, u# C. R* F   if(pTemp->m_pNext == this)
$ j) B. y9 i5 X1 A   {4 w, K& u/ D- q: u/ d- x7 d
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
1 O( [3 O  k+ P* V) V$ o- r    break;
3 Q+ j) O  c& |% c; O5 c- [/ C   }
: d" T9 E! G. t1 ]0 z  }
2 i* i0 K7 @9 Q+ T/ g! r( ]9 ^ }* o: f3 x! Q/ ^' k7 T
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)8 L5 e/ b$ G! o5 D! F
{
/ \- z5 o, E4 H' z  K CDialog::DoDataExchange(pDX);
! m7 v! P7 W" s( d9 ^% Q //{{AFX_DATA_MAP(CHsPMEDialog)
6 m, M) f* \9 V; o! d9 z DDX_Control(pDX, IDOK, m_btOK);7 b5 c% E: A, @- {# D' k
DDX_Control(pDX, IDCANCEL, m_btCancel);
+ _8 x- ]( @/ T DDX_Control(pDX, IDC_BACK, m_btBack);5 l9 \! \8 X* {; X
//}}AFX_DATA_MAP
" a+ [0 w/ U4 X, ]& I& K}

: D! K4 c5 r/ X3 |0 J1 ZBEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
0 ]9 d8 ~$ ]! d( x* [9 z# E+ _ //{{AFX_MSG_MAP(CHsPMEDialog)0 `& o* V$ V0 d1 {( m: S. b  B
ON_BN_CLICKED(IDC_BACK, OnBack)
* W* l% Z) }2 |# u, \1 u ON_WM_DESTROY()# y: N2 m' F4 Z1 \2 U
//}}AFX_MSG_MAP6 I  a9 A0 M  S# s6 D$ M
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////8 ^2 A0 R; [% n9 }
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
6 P+ i$ n2 i0 u0 F{6 b2 X& `% M  m7 z" ?( [' y
m_pParent = pParent;
5 o' v  E2 P6 O return CDialog::Create(m_nTemplateID, pParent);
# f$ b  N7 N7 ?. C" ^5 x& [7 j}
- p. Q6 C1 q; B6 f5 C9 V
BOOL CHsPMEDialog::OnInitDialog() 8 X* T* M1 M! O- F
{( x3 N+ ]5 d5 y  I
CDialog::OnInitDialog();
// 设置标题栏图标: i5 M4 g- ^7 K4 n7 l# c
SetIcon(m_hIcon, TRUE);
* B0 t1 c) C. ]+ ~# _1 Y SetIcon(m_hIcon, FALSE);  V% k2 _* N! A& w! g9 N
9 `  h, @5 h8 p) J$ j+ |
// UG的对话框的几个标准按钮没有TAPSTOP( |9 `  r' U( H- P" c: W, B
CWnd *pWnd = NULL;
$ M; j% t  b/ S; }! ?/ T% @ pWnd = GetDlgItem(IDOK);
; C$ E4 G- M8 z/ {) j; `7 Q) ]2 k. W if(pWnd)
( b8 g: R( h5 c4 H# ?! A: } {6 V7 Q6 [/ b; I( \- h0 v: N
  pWnd->ModifyStyle(WS_TABSTOP, 0);4 q4 w6 V7 l( c0 _& V
}
6 ]: `) Q6 s+ v pWnd = GetDlgItem(IDC_BACK);. U% E; U7 a$ {0 J' ?
if(pWnd)
% ^0 O7 \  b. V" ^& c) n9 K {
' ~2 M& d1 O, E  pWnd->ModifyStyle(WS_TABSTOP, 0);/ b) V: L, U7 }- C1 k; K
}( y* c5 U0 ~( m, h1 i* M
pWnd = GetDlgItem(IDCANCEL);  d. U( f: l: S$ B. e
if(pWnd)0 P) Y6 Y) i% F9 L6 A( v
{, a# i" d/ j) i3 |- T' e
  pWnd->ModifyStyle(WS_TABSTOP, 0);
6 W7 u" y8 N9 O) i6 P; O. A, N }
: a+ W+ l2 H5 n- t - ?% N1 w; C3 z/ h& j+ g" Y+ B
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子) Z& @7 N& N/ d" c+ G% o$ @
if(m_hkKeyboard == NULL)8 D$ w) ?8 X" K/ D" k
{$ f7 c# i" J# @
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
& I2 R5 C/ |2 p6 b  f: v) t& I }
! [7 [9 g( B2 u5 Q0 b if(m_hkKeyboard == NULL)1 v# y# Z+ A( d
{0 _7 k5 j* Z* E' ?; S8 Y8 e) \
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());
& l1 t5 R8 S5 J! P' m }
if(m_hkCBT == NULL)2 P1 _2 p3 Q, M) b% K4 y" n
{' _$ f" h* J- L" R2 w) A
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
7 N  R. c' n+ T8 } }
* u5 X. \! e, `. j3 Y/ O if(m_hkCBT == NULL)
" l4 R% @2 b: t# J" j0 h {
' u# l5 S% Z3 t2 B' e; \7 ~, W  TRACE("Set CBT Hook Failed: %u/n", GetLastError());
1 O. p5 [1 w  V' d. H }
  B  P: A# G$ |; P' i  { ( W' n3 E3 ~* Q4 A7 h
return TRUE;  // return TRUE unless you set the focus to a control5 u# [2 v' x0 X: f
               // EXCEPTION: OCX Property Pages should return FALSE
- q: z: g  k% z}
void CHsPMEDialog::OnOK()# X9 Z( j3 X2 C: B9 O
{+ n- `+ V1 }9 S/ m3 Y
CDialog::OnOK();% w/ e: \6 T9 g1 q
if(m_pParent)
4 K3 C: p  R8 X7 F3 ?! {" f {' R$ x: V8 ]( U& j
  //m_pParent->DestroyWindow();
& I. i. r5 N& C. C3 ]- Z5 T2 M  //((CDialog*)m_pParent)->EndDialog(IDOK);
% R+ X2 [  n+ c  ((CHsPMEDialog*)m_pParent)->OnOK();
4 k2 @! ^1 b7 Q7 Y }7 E: t" _4 x/ p# j! V4 w* Y# X
}
void CHsPMEDialog::OnCancel(), l' P0 C0 f' c' F& _
{" ]/ A/ Y, w* c. Y5 E5 N+ S8 u
CDialog::OnCancel();
) c( I( [$ U9 E" ]2 r' d if(m_pParent)
5 A, E, [3 e' P9 m, I4 [0 S {/ W# ]$ J$ u8 W2 U/ U) \
  //m_pParent->DestroyWindow();$ `% k8 X6 ^$ u! {+ P% T2 L
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
+ X, ]3 X9 D% B  L- f/ V  ((CHsPMEDialog*)m_pParent)->OnCancel();
2 _! p, c7 R2 X1 q9 ? }
% p/ P1 l9 }1 E  ]; f9 R) X}
void CHsPMEDialog::OnBack()
+ a7 v' G) G# T( X, `{
" p" B# Q% X! V9 z6 M& s if(m_pParent)  G$ k9 U) _) ?# H9 X  N) d
{% [! ?3 z7 ]0 @( _9 R8 _
  m_pParent->ShowWindow(SW_SHOW);3 }1 P, ?, f! ?
}6 I- O- [1 b6 L
CDialog::OnCancel();# v7 \  D: r) u) h. y5 [& A
}

. c, F* A! B5 k( w( X+ N; EBOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
: x9 Y( J) q+ D% Y! d{5 }" C  T) U  Y( @- o* \5 U
BOOL bRet = FALSE;6 D  M# r2 a9 ]9 l. Y
if(pChild->GetSafeHwnd() == NULL)# p* L3 x  K- |5 y( _* e
{
- x# A2 q- |+ z) c# h9 ]  bRet = pChild->Create(this);- j- k/ N5 F+ F4 ~  `
}
& {$ r( J- C- \6 i0 m3 K% Z bRet &= ShowWindow(SW_HIDE);& e% h% h) [, B8 y* n
bRet &= pChild->ShowWindow(SW_SHOW);
$ Y7 a$ h# u8 o return bRet;
3 y0 b8 f* w1 c; E6 {9 ]7 G}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
+ ~. |# [7 m! J{/ `- k/ \- O' m% D& ?
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
( \) U4 U- M  D {
( S$ j. A& j2 {# @4 K! M% Y$ B  //TRACE("Key down/n");% T8 t6 R9 _6 t5 ], T4 g6 j3 t
  CWnd *pTopWnd = CWnd::GetActiveWindow();
* A' g4 F4 K6 f  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))) X8 L$ T. o7 Z( A/ |0 U; y
  {
% n6 s5 v* ~+ k- ~& X   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
+ A9 T+ v3 ^) w( D   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)- ?8 N5 ~: O0 X9 M
   {
2 g! f% e% w$ G- q    // 只截获tab、esc及回车键
5 K  {  f- O: n2 r    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);$ j, t; W, C) v  j; b& V2 O, m
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);+ a! i6 ^+ S( h4 \/ u
   }) ~, |5 [% N+ }6 ^( d/ _& r
   switch(wParam) {  @% d2 I; _' I' p1 O4 i
   case VK_TAB:  J& ?! U+ K1 z; `$ `3 ?* N" \
    {1 @" c2 e; B1 _* q; x9 z" x' u/ f5 w
     CWnd *pWnd = pTopWnd->GetFocus();
  H9 y, g% E9 d0 L6 w$ x/ x     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
' k' V2 x& P. @+ u9 |     if(pNext)- A; Q1 g' d$ A3 U" b6 c
     {
  U: e8 [/ {( A6 u) Q      int nCtrlID = pNext->GetDlgCtrlID();
: \5 y2 U# x- i9 Q      //TRACE("CtrlID = %d/n", nCtrlID);
6 s7 k( e$ N& }' s  x* }      pWnd = pNext;& ]: N. X8 _0 _& \
      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
; O3 Q- `9 a" I" h      {
1 x! L: p* f) e% v7 y" c5 y       // 根据UG对话框的属性,这三个按钮是没有焦点的
! c7 E5 R$ H8 @3 u1 _3 v, ~       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
5 Y8 {0 A! x0 T8 B  e2 q       if(!pNext || pNext == pWnd)$ E8 l' K  \" [& \# a0 K
       {
( B6 ]0 a" N+ a; H! F. v9 B# ^/ l        // 对话框上只有上述三个按钮
; y: K4 D) F4 _/ e6 R+ [( q        return CallNextHookEx(NULL, code, wParam, lParam);; I- a7 ?4 i& v
       }
) \0 z+ w& T5 N8 H1 B       nCtrlID = pNext->GetDlgCtrlID();5 ?$ }) b# t, q7 M9 u- R  Z
       //TRACE("CtrlID = %d/n", nCtrlID);
3 ]; o5 B! x6 v" Y      }
- A& P/ R! C" v- B; Y      pNext->SetFocus();
  F1 U# [0 o( L3 U! {' W, ~! s2 ^8 p     }
& |" F" C# L* O. q     //return TRUE;3 A2 S! i1 w/ z9 l* v! d8 G: T
    }- _: ~; ]; ^% d* D7 @
    break;
0 V7 R) Z) [" K8 p7 E8 A7 [   case VK_ESCAPE:
. v7 h' y! |8 j& l    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);  O6 `0 ^; [) x( t
    //return TRUE;
& \/ m3 U/ w( t4 Q6 H  s4 ^    break;5 y& |, ^6 k$ k: }+ J/ `5 D
   case VK_RETURN:
, V) e: E& W7 u  Z" M2 t    // UG实际上并不处理回车键
5 N6 E) ?6 |; s& a: b$ }( G4 s& I    break;) \. ]  ~" d% ~
   default:( C: R$ Y' ^# Z  _
    break;) ^$ C$ v2 I8 N$ R
   }
% |1 _, l# k8 `3 O7 G  }
' v, w3 c: V5 r& x7 U0 j }
) ?) h" s1 W; z" b return CallNextHookEx(NULL, code, wParam, lParam);! W; t1 F5 E5 {" q6 B& m- ]5 V9 W1 _
}
void CHsPMEDialog::OnDestroy() 8 \& k, T" F' D$ w& Q( U, ~& P
{. o3 o+ y' N# {% k( _: M6 r8 q$ _
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子* }& L) R1 n; U  i1 W! q# ]9 b7 c; N* F3 \
if(m_hkKeyboard)
7 J' Q; w' Y' k {0 }0 D9 ~, t- D; v" V' a5 A$ h7 U
  UnhookWindowsHookEx(m_hkKeyboard); ! n! n, p2 O( o) W
  m_hkKeyboard = NULL;3 X. A& A8 ~: n; k" u; `$ T
}
if(m_hkCBT)
. q. {; r* y: v" k7 n& \ {
" n! }5 q( X: v2 R/ F6 h6 x  UnhookWindowsHookEx(m_hkCBT); : M2 c2 `/ V* _" T) Q' o
  m_hkCBT = NULL;
7 ?% U/ D7 ~& V! U }
& R2 p6 D- l' R}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)* p+ G  j7 K/ T0 E
{
0 S: ]0 {* X: y6 p1 U3 t- v5 y, q CHsPMEDialog *pTemp = m_spHead;
$ [2 F3 V0 `, i. r. f2 E6 `/ @ BOOL bFound = FALSE;
! L5 _0 f- h9 u for(; pTemp != NULL; pTemp = pTemp->m_pNext)% V) Z3 P8 @/ Z' y. `
{  y" G! L  F4 `0 Z
  if(pTemp->m_hWnd == hWnd)" Q) H6 h. Q/ H5 u" I
  {
( e7 H! b2 \  X- q! n3 Q   bFound = TRUE;
# O' Q; t+ K* g   break;6 t& _) p% e9 B' Q4 C3 W6 Z
  }  W" n- X% Z' W" P, _, K1 f5 D4 P
}
: G1 J6 G' W# {2 F* D8 j( K9 r% Z return bFound;
: g* \5 l+ U+ v2 B: L" w1 D; J' v}
// Returns the HMODULE that contains the specified memory address
: Y  ?3 W& w+ Y+ p" D1 [- yHMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
% I/ T& P+ _6 L' i, t{& N/ e  E# B+ s3 k& _  I4 d

  C2 v" W7 g4 i" `, {  i MEMORY_BASIC_INFORMATION mbi;& k2 Z  \) v' s" E
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) 6 g5 Y9 ^) a3 |+ W9 I/ ?/ D8 C
  ? (HMODULE) mbi.AllocationBase : NULL);
( V" r3 }- l: S4 F! L5 f/ h+ _# P1 U}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam). Y8 z8 B# f0 F. R
{
- m3 r8 I% I9 P. } if(nCode == HCBT_CREATEWND)
: ]/ t. n$ \' i: r {
8 e- \7 C+ {( b) w* f  //TRACE("A Window is being created/n");7 ^) F4 G. @9 r* @
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;1 E. [3 u! R; u: u) k: R: L: M
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
4 Y" Z. ~# Q, Y( `! G: u  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
; p) J% B$ G" e0 A" r- m9 J7 p' T  {! g% ^, W" D8 n
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应, }: t5 X* K/ S* r6 K3 j5 T5 h/ s
   // 取得窗口处理过程内存地址
+ x* t( I% t5 Z$ n+ H   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);  M1 f" M1 E" }7 Y% b
   if(dwUserData)
9 `. z) y5 r, |   {1 R7 I0 \8 u" ]; H7 ^' {3 V1 R" J
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);/ ^! Y1 I: c/ L# x0 k
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
+ m; c1 Z$ U6 U4 |+ i' T' l    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
! i" \9 P' T0 L    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
& e; M% l/ I% p    TRACE("CreateWindow Frome Module: %s/n", szModulePath);& h0 _2 D- c2 r) {5 v
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
; L, |- j# Y( A, Q. ~( r    if(stricmp(szUGPath, szModulePath) == 0)
0 n" V: u) v; x" E    {# ?& A, Q  X, Q; I  s* R
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
: t4 }  m/ P  G! y6 a     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)) A7 D$ f; O7 v0 V2 T4 ~
     {
+ t% _9 z- W6 W( h      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)! A2 U( U- ~, j# N! ^+ f; f
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && ( |! ]8 _' e% N# m
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)6 d4 Q1 A$ n1 o
      {( Q/ v! N" Q/ a  L4 U" @
       // 窗口非本窗口或其子窗口( \) T0 v4 U% i, x' N# b, G9 z
       g_pHsPMEDlg->OnCancel();! \& @8 _) p- }3 J8 ?* T/ f
      }
" j' |7 U0 P$ ]7 b9 u     }0 p! G  O5 T* F8 o0 s
    }
) O( J5 p' M5 V# [% |   }
2 i% K& ~+ @6 p  }
% [4 i$ s0 F% m4 \: ]+ ~% V }2 j3 S' |. T8 J6 T5 [+ m
return CallNextHookEx(NULL, nCode, wParam, lParam);
6 L$ {1 \) \2 g}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
/ \5 L  U# z& Q; w6 p! Q{
- c/ |$ H& d) s1 n2 y7 c7 m4 ] // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
5 j4 c' {. w# o* h3 V, O8 E2 W9 h( Y % V6 s  ?. }9 q4 b8 f
return CDialog::WindowProc(message, wParam, lParam);
( x5 ^( P: a: b( [+ Y# }9 X! s}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
; {6 l/ Z5 i1 G! `/ K8 e{
( |' X  j. y4 b8 `3 N4 o : a. J6 o. P0 x5 L  C5 b2 t0 f
return CDialog::DefWindowProc(message, wParam, lParam);
5 t& b' B& W9 V, e/ J1 C}

: v6 V# B1 t2 i) B" ~1 J+ Y' Q
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了