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

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

[复制链接]

2017-8-31 13:24:24 3337 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
* v6 E9 t  h+ y8 I// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类9 l8 T$ c3 }3 S5 R& Z2 q% O# b1 I
//    该类来自网络,稍作修改,版权归原作者所有
9 ]: F% \4 Z4 s, X% S$ E//-----------------------------------------------------------------------------
+ C3 }- V0 I. [0 V! }class CHsPMEButton : public CButton
3 g- Q% q- j9 j' t6 F{
7 V6 X3 d7 V: O$ h // Construction2 y* [2 X* ~& @* U0 R4 k* q" M
public:
; M: K- m$ ^- H) `: t# b CHsPMEButton();
4 }0 Z- n# T& M* d# H! A: F7 k
% ~& y1 \- n* n1 Y  k* u! R; d' j // Attributes' R' k1 s: v# ?
public:& Q4 l& `& V) H' h

6 b2 y; v$ k5 H2 G# W/ |. e // Operations8 g1 X- Y9 ~" \) V3 e! c6 K
public:* |( {( d6 J7 ?, p  C7 ?
inline void SetNormalTopColor(COLORREF color)( G2 [, }: F! I& S7 D' [( `8 H
{
7 P+ z* a0 B9 m  m_NormalColorTop = color;
- Q" ?8 I6 i; M. M) F7 W  s% ^: i }
; |" P: K0 W* v2 R inline void SetNormalBottomColor(COLORREF color)
6 H6 G( t" e1 C% q% i {
8 Z+ P1 J9 Y5 M2 g6 v0 S  m_NormalColorBottom = color;. `, z2 E$ N/ ^$ V: I2 z' Z% D2 k
}
- r5 ]" W: ~# g& X% H inline void SetActiveTexTColor(COLORREF color)
; `% A! I2 j8 |/ F) C! c. D {
) Y5 G( v. D- c) M  m_ActiveTextColor = color;
+ F  F6 j) o+ S( y/ x' G }7 q0 Q: M+ o# G1 T% k
inline void SetNormalTextColor(COLORREF color)- j( E% c4 n# [  G; p
{
* F: K- @5 U# n9 R  ]$ w* L/ n  m_NormalTextColor = color;) E4 c# i1 y$ T. K: _4 y
}
% I/ k& h$ _( B" P8 {! l inline void SetSelectTextColor(COLORREF color)
- T+ S5 s$ o! Z {
8 Q# p: J' b0 ~9 d* A# @2 u8 O- C# f  m_SelectTextColor = color;2 F' ?7 V5 C' R$ R! D
}# [# g) z  S) v) X' q/ a1 u
inline void SetFrameColor(COLORREF color)# y) a3 Z) P/ N# C6 s6 A3 [8 n1 S
{
% g1 N6 `4 t& m% [1 C( J% p6 N  m_FrameColor = color;
$ n8 |) Z8 I! G8 B0 U }3 @4 K4 h! c0 n. G  l' ]
inline void SetActiveColor(COLORREF color)
& W2 G1 N' ~2 G/ d, S {+ e6 G$ F8 U/ c, @3 \& ~& b1 o
  m_ActiveColor = color;
% E- V; I+ F: x( [  o: m& _ }, _; k& Z/ z2 Z) m+ Z: w
// Overrides
- {2 o; o" F8 _" U  g0 M( O( f // ClassWizard generated virtual function overrides6 L' g, X! e* _6 E) u5 A+ U  j
//{{AFX_VIRTUAL(CHsPMEButton), B5 t8 x. d' r1 K( t
protected:4 H( B4 W' K! K2 R# a
virtual void PreSubclassWindow();/ Y4 u8 T7 O, _* ]# k# Q
//}}AFX_VIRTUAL
1 R$ `6 I' z2 j) j6 X! Z ' i6 f: p+ m0 ~2 [- K5 c1 X  H
// Implementation: l2 E1 u1 X3 C9 Q3 G
public:! Q$ q# w1 `8 @' A; H+ T/ X9 O1 [
virtual ~CHsPMEButton();( e- W3 q$ P9 A9 G1 @" `, H5 Z

+ C5 M' c$ g  U // Generated message map functions  Z! `- ^1 `% v$ ]* h9 D- K* t
protected:; F/ h9 X7 ~& @  {
//{{AFX_MSG(CHsPMEButton)
! M$ P, d+ D: a! w afx_msg void OnMouseMove(UINT nFlags, CPoint point);- k3 P3 x9 Y! R+ k. \! f
//}}AFX_MSG2 X. G2 p' v/ J$ o
1 I7 H2 j6 T/ d0 X' f: |
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
) V  m2 B. U# f0 t1 G) r void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
$ T$ U: H7 P( ` void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
7 Y1 w/ y, I7 z5 H LONG OnMouseLeave(WPARAM, LPARAM);
( `) d& @, o) L0 N! ^' R3 S* K6 \" { BOOL m_bIsMouseMove;
! l- G8 k4 c/ j: V% e * r' K7 Q) C5 A, X$ e: V& u
COLORREF m_FrameColor;# |6 @, Z4 Y! L
COLORREF m_ActiveColor;
+ d/ b0 |: o/ i' W
0 o3 R" \; e- ]0 o# T4 G COLORREF m_ActiveTextColor;: H0 h: w7 i8 h% ]) S. w& Z9 R
COLORREF m_NormalTextColor;
6 Z4 I+ _0 F. u: k5 s  [ COLORREF m_SelectTextColor;
3 b& \8 K3 \6 Z3 A' v& G4 U. I
* D+ R4 a- Z5 K/ I, G COLORREF m_FrameHeight;
0 i3 h2 K3 e/ s. w  q8 R, X9 G COLORREF m_FrameShadow;
2 \! }: L4 h9 c . U9 w1 e4 n. \8 @' M
COLORREF m_NormalColorTop;
4 B9 h# i# R! p' {9 y8 R4 c# O' V# j COLORREF m_NormalColorBottom;
5 g$ x3 b3 m( v2 U5 h, a: q1 C - O1 B' t2 \3 q' |, K
DECLARE_MESSAGE_MAP()
$ @( I4 `' @- \0 q! W};
/////////////////////////////////////////////////////////////////////////////4 @5 \( E# G) ?" i( f* k/ r. ~9 G
// CHsPMEButton
CHsPMEButton::CHsPMEButton()
& Y% ]1 w8 I, K' \+ Y{
( f# V+ [$ Z  M& L: Q9 E+ m m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);' P# `$ i4 D2 ?1 O3 q- I. Z
m_SelectTextColor = RGB(0, 0, 0);
, ?/ \- z5 b; I* i2 ^ m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);& {1 U" F9 l: G  z% ?4 b
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
! |: k9 ^% Y) p! S9 O/ \ m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);' b/ v3 `8 Y3 v
m_FrameHeight  = RGB(230, 230, 230);
5 G& j* D3 t: P2 j m_FrameShadow  = RGB(128, 128, 128);
& D2 h- s: |' p( n8 [}
CHsPMEButton::~CHsPMEButton()
% T3 N* ~- T- e% M{
- e" s. U" I/ v}

( }( h- B, r9 U* [BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
. y% L& `( B& T2 y8 i7 y& T! z/ N //{{AFX_MSG_MAP(CHsPMEButton)+ }6 v4 x. N: W  p) P1 X* F
ON_WM_MOUSEMOVE()" S2 W( m, R' D* Z& {3 M
//}}AFX_MSG_MAP
+ V% s8 ^. p7 Z6 x3 T2 O3 q ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
' @! Y8 c4 H% l+ [7 `END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////' x. e7 w  ]2 v8 Y  I$ `
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
4 S6 h6 E6 F. _) H{
8 I7 \9 o# D0 U# _: ~ //*! s% |) Y+ ]% i$ [
CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);" {& Q) u" i9 S8 }: |/ A4 y
DWORD nState  = lpDrawItemStruct->itemState;& `/ R3 M6 |9 P. c8 M  N
DWORD nAction = lpDrawItemStruct->itemAction; . h3 K4 `; q' U- n, W( L- K
CRect rc   = lpDrawItemStruct->rcItem;
# P$ l/ y" C# T, l UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);' K, n& b4 o6 X1 Q
CString strText;$ f3 k5 y9 H/ x+ q& Q# r2 r
GetWindowText(strText);
if( nState & ODS_SELECTED ). s, x/ ~6 M4 L4 Y
{/ ^) e2 ?0 Q4 W; N; z
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
6 C5 g1 P; O2 [; |! F  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
: O  r% E3 I4 A  F, d  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);5 N& O. R# T6 J( x+ b4 {1 a/ w" \
}5 t5 u/ F  h% w, `2 ~3 O. P
else //Normal7 S( ~( Y! d* f: i# k
{
- v: ^6 Z' v0 Y$ S2 R  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
" j0 G: L3 b) u& q  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);7 a/ E7 b0 S. r$ c" V& i* K7 d
}
if( m_bIsMouseMove )
. M( ?; Z/ s: L. U, V0 g {
8 ~5 ~1 B! y7 ]9 G  CRect rc2(rc);
4 v9 \( x" U5 g( [$ O5 d$ ]$ F  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),% e4 e) Y# R! o  K/ \  B) Q8 f
   m_ActiveColor, rc, rc, pDC);
5 M4 K% k5 x. D& a" U0 j  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
0 V" G8 D) _/ i  NullBrush.CreateStockObject(NULL_BRUSH);$ ]' r. z' i4 R5 [8 ~! F
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
9 l4 Y$ S5 q( J/ I3 M: {  
" r( ?: j! d* @5 m8 d" n" g5 l9 s0 {  CPen Pen;
  ~4 E4 g) p# l$ K3 z  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
9 k0 k  I# `$ L9 b0 W' i( E. m8 N  CPen* pOldPen = pDC->SelectObject(&Pen);
  A6 ^) i+ e. W  rc.InflateRect(1,1,1,1);
- M1 f* I, {% ^% Q. A0 g  pDC->RoundRect(rc, CPoint(3, 3));) @" n6 u5 w3 f6 k# Z+ e
  //rc.DeflateRect(1, 1, 1, 1); * ?5 G" }" N7 u# _- V5 q( W2 D/ C
  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
' [: B0 P7 E! S3 @; I2 m6 i  
/ }: X7 B/ i0 a0 Y- q  pDC->SelectObject(pOldPen);
$ Z$ ~$ D; E" i$ W4 b6 i% T  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
. H2 e1 R& l$ V5 E; N7 q) @' q }- }1 S, Y& @1 X1 }4 W3 ?
0 ]( _! s/ S* K# d' o
pDC->DrawText(strText, strText.GetLength(), ( g  ^: V! c- Z$ G4 p! R
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);) X5 b& U7 e8 q) p) s4 U. h0 g. \
//*///# m! d: I  l$ S6 s; A
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) & \2 M: w; p$ T$ N5 [8 ^
{* r0 F( h  ~! H. S& l# M; N( s1 m
// TODO: Add your message handler code here and/or call default! Q4 e$ g8 N* m# c- p" U$ d% {& y
if( m_bIsMouseMove == 0 )
4 R+ K9 i; J- t# n8 F, ^* |/ O; T {# s8 p% R8 r6 l( ^- v  t( i7 K
  m_bIsMouseMove = 1;2 G4 V  S4 m: a$ g# b$ G+ z) d
  Invalidate();: S9 C4 r( F# V
  ) p* s, d1 C  ~& h3 }* @* v
  TRACKMOUSEEVENT trackmouseevent;* I4 @7 g+ t: w, ^. G9 B
  trackmouseevent.cbSize = sizeof(trackmouseevent);
% e/ X# \( l) A# f! ]" S5 e* N  trackmouseevent.dwFlags = TME_LEAVE;
5 g5 b) k3 W4 I) _, `  trackmouseevent.hwndTrack = GetSafeHwnd();
, \( x! r+ S8 s  g  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
' Q- m1 v: I( o6 ]9 q: b  _TrackMouseEvent(&trackmouseevent);! R# S3 w1 Z9 w- w
}
) k  u( u4 M. ]% k
# K; }) U* q6 |  J CButton::OnMouseMove(nFlags, point);
1 C6 `0 g( M) t+ B% f- ~}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)* I0 v* ]( G0 u7 f( u6 W
{& ?9 x7 Q& B# ?0 j' m% K8 I
m_bIsMouseMove = 0;  P2 P1 O# ~( t/ x" w
Invalidate();
return 0;
8 ~% f- V/ t& y}
void CHsPMEButton::PreSubclassWindow()
' E5 t- }) u% ?7 ^6 d" N* p4 p4 |{
% H( z& n. E" B# S- c' s // TODO: Add your specialized code here and/or call the base class
- c' U8 a" c# f+ I5 G+ l% n UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style7 i& M' V. n" X# Z
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
/ U' q0 G( y4 |, S% p! I* |4 J}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
* b4 i; U) Z, p% H& p9 J" ^{* G, K, Y* P4 Z
CPen Pen;3 f/ D$ ?6 F! c5 \/ \
CPen* pOldPen = pDC->SelectObject(&Pen);; X% W2 A) y) N

* }- s! G2 g! _2 s int R, G, B;
1 E  O' g1 V- k* } R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();) j/ s& \: c+ Y% y1 a
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();# \1 _2 e9 g' f; Z4 B4 p
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();) @' C+ l* n7 Z/ A" n

8 i/ ^7 V: l7 K+ N //R = R>0 ? R : -R;
! a7 _- a2 g+ K3 _+ \* n- ] //G = G>0 ? G : -G;. |* O5 U3 T3 d8 e
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
! E+ T" S, t0 q8 w! S: P1 Q COLORREF ColMax = Top > Bottom ? Top : Bottom;. f; y9 N  Z2 T7 K0 k' O
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
' e# w% p; S9 }; A" s {
7 f; A; s5 O# a; m3 B  ColR -= R;
4 t) s' r5 _5 i0 P8 ~  ColG -= G;/ \- s' ?( @+ P/ g* a) c
  ColB -= B;
  /*
: o+ g, S- p6 X/ u+ G$ b6 L6 F  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||% e( w. c/ X, O2 }* t
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||+ F8 _! s2 r3 s! {0 ?0 H
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
0 y! c0 h- V8 ~' o$ g, ]! H* o  {
8 W# O. _* U# m   R = G = B = 0;) _7 G  k' S9 ^8 X4 r! }, w
  }///*/
) B7 g- S9 W6 v+ T
  Pen.DeleteObject();
  ]: B5 ^3 y1 [& r. d  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
& k* `2 ^0 t2 I7 A) d+ {5 |) G3 t    - ?' W/ ^# Z8 M" i% s1 Y) J
  pDC->SelectObject(&Pen);
& S) V. _8 H* |4 Y2 n" H! k- S4 ^  
' w9 w1 s9 P* @$ Z2 z. _" L' g8 U  pDC->MoveTo(rc.left, rc.top+i);! w* s1 N9 Y4 J& v5 x
  pDC->LineTo(rc.right, rc.top+i);; M; C! K1 k; S
}
pDC->SelectObject(pOldPen);2 W7 D7 N1 f7 j" e% O- K1 M
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)4 _0 h) z( L8 S: ]; G4 K: ]2 S5 n
{# ]) Y4 e: F9 x4 p/ H# v; ?3 u
CBrush NullBrush;
- q! D, g2 s/ f, |" }: g0 A+ p/ y1 i NullBrush.CreateStockObject(NULL_BRUSH);) [- t2 p7 @) F5 T) R
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
' X: L  @- C7 t, u6 \& o8 H, |1 G Pen.CreatePen(PS_SOLID, 1, FrameColor);
9 U2 b" S: R2 A2 N  g/ @ CPen* pOldPen = pDC->SelectObject(&Pen);1 \- ]- l/ Q) L# _
6 S. C& t9 C, ~. I8 L& {# H* H) p
pDC->RoundRect(rc, CPoint(3, 3));
% Y0 P3 p( ~. f- ~ rc.DeflateRect(1, 1, 1, 1);
( Z* q4 u. ?4 C* ?6 f* I* I4 h* x7 R pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);+ @  C( ?4 u" j- c5 _% ^
pDC->SelectObject(pOldBrush);
0 T' I2 d/ Y) L}
  F) t2 ?: V5 w* |/ M' o# v: x% j
/////////////////////////////////////////////////////////////////////////////3 j  t/ v* }+ m/ @/ g1 n
// CHsPMEDialog dialog! N1 Y; K7 Z! G2 a
//-----------------------------------------------------------------------------
. s* {- d3 M3 M// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:/ D% A9 M. A0 i9 z7 D
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级+ d2 J( l+ f$ Q5 q
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口3 S; Z5 G9 I5 |7 s# X) }
//   指针将其显示出来,然后隐藏或销毁自身
) r( m' w# A+ G( n2 Q+ j- R7 j0 ~//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。  W4 C  Q- M( y- l5 x  m
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类/ I: n) k$ I) m
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
5 R9 u$ X; |. m4 D8 |# Z+ f//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
9 T) Z8 f8 c1 n7 W% _6 a) B//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。9 D8 R' i/ K7 ~( a+ t4 @
//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框0 |% H) q  o8 K! F1 X  ]+ W, F
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。# y! V  M& x# N2 w5 I9 ?
//-----------------------------------------------------------------------------
" v5 U& n) R' ^. h' c+ y- A/ j// 注意:
# g1 `! y% O6 o+ d// 1、在构造对话框时必须给出其父窗口指针6 S  M2 D; q! f' h2 ^9 R
// 2、在初始化基类时必须指定对话框资源模板ID  A% g2 |2 {3 W8 G
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
  e, i/ n, U3 k: F& `. j// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel: M% R$ n' K; Z% Z: m6 z' _, Z1 m
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog1 U: M, v9 {9 x
{0 Q- [; _) k( C  f! l* A' Q
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
3 d2 A9 Z0 y5 [' S3 t1 m9 h// Construction7 I4 _) X3 D6 S6 X
public:0 V0 S1 Y7 s% D# s0 \  G0 p0 d
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor0 s4 w4 B7 b: L$ a. _! a3 {
~CHsPMEDialog();
0 {( W& v- ?+ V, w$ r; \ BOOL Create(CWnd *pParent = NULL);$ L7 x  e7 h- P& u0 k; H. I
) f4 }  [& v8 z
// Dialog Data
- a; h3 r( ]6 J+ J. W' A: e //{{AFX_DATA(CHsPMEDialog)1 A0 G: X& {; s) r# ^  z% x3 k% n
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };1 [( ^* N. o* k4 N: Y& o  w+ u# U
  // NOTE: the ClassWizard will add data members here7 i: }/ `# Y6 g4 s# ]
//}}AFX_DATA

9 [% O  t0 h! k6 B; T$ t( P// Overrides
9 [' ~: M; J$ Q8 s% J // ClassWizard generated virtual function overrides
- W. F( s1 [  O$ A* a& ` //{{AFX_VIRTUAL(CHsPMEDialog)& d  l  p( Z5 a1 x
protected:" b1 K0 W1 n3 R+ k
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
: ~) e& R* l  o0 o. L$ a( ? virtual void OnOK();! n& o- \4 w, X. N) ?# x
virtual void OnCancel();
5 u$ ]9 \5 l1 J  o# T virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);( }+ L+ q6 U$ y+ n2 n7 \; {* \
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
' M  Z6 V  h0 o) W: e //}}AFX_VIRTUAL
// Implementation
+ }- d' N! ^- i9 B1 b9 d( y4 a/ Bprotected:
// Generated message map functions
- ^( k/ {% m" D! v' z2 i2 C$ J //{{AFX_MSG(CHsPMEDialog)
/ L/ z$ x' l0 R, j afx_msg void OnBack();  V% P+ o) S# f
virtual BOOL OnInitDialog();
3 B) ?% p& d5 ^( Y6 {0 x" C, t. v afx_msg void OnDestroy();$ V# U* [% y5 c' m
//}}AFX_MSG6 [* N! [( @/ W8 m/ v0 I
DECLARE_MESSAGE_MAP()
protected:# G- l% X4 x( i- Y+ i5 x
// attributes
( A6 F. k9 k3 z: ` CWnd   *m_pParent;     // 父窗口指针
' ~  x/ Z7 l( Z& o7 S0 i% O# n HICON   m_hIcon;     // 图标: b& w6 C: b  K; u5 z  Y- A
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
6 }, N( M: {# ?# j" H7 z CHsPMEButton m_btCancel;
8 J) W' M9 W+ X% z CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄% Z6 R7 u1 {1 t1 W
HHOOK   m_hkCBT;     // CBT钩子句柄
& K. O" @# z3 q' f
& J4 u0 d: R% j% H2 i6 O/ F* O" N5 n //-------------------------------------------------------------------------% d- k0 M2 ~% m9 f% v& G, f
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog& J* ^5 }% V, k8 r
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
$ L$ N# h, {7 F // 链表的头及下一个结点的指针- j' @% _! \) v" ^$ U2 H
static CHsPMEDialog* m_spHead;0 [4 ]* R" ]7 L4 H1 ~; y
CHsPMEDialog *m_pNext;
// operations
8 L$ E3 X8 C5 h2 _" i // 键盘钩子消息的处理函数; }: y6 m/ ^% P  S( n" X
static LRESULT CALLBACK KeyboardProc(! ~; H2 x: H. k5 ~9 V8 n
  int code,       // hook code. G8 A, k" q3 M$ M3 E7 i4 A- c4 {
  WPARAM wParam,  // virtual-key code, \' J9 Y* v/ g; Z
  LPARAM lParam   // keystroke-message information; |8 @  S( s$ x. A/ B6 i
  );
( x6 f" v- T$ K: P. j! D  t // CBT钩子消息处理函数9 S: J8 h$ |; j- `$ t
static LRESULT CALLBACK CBTProc() ?- S' y$ A% j* F5 [1 I0 s
  int nCode,      // hook code
# c+ ^2 S+ j0 ~+ L  WPARAM wParam,  // depends on hook code+ M$ H) E, V9 W# S" p( `
  LPARAM lParam   // depends on hook code8 \% L  c' O5 i, y# e1 X: A5 r% H" F
  );
1 o" x5 N0 _0 v
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口& u$ P) o! @0 p$ t$ t1 y3 K
static BOOL  IsWndKindOfThis(HWND hWnd);& `; c+ H# d0 w+ Y$ H6 d8 T8 E
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)% }+ Y3 Q& \' r# d' N
static HMODULE ModuleFromAddress(PVOID pv);( x# k$ }: h' W2 X( x( z: X
public:
9 }5 D3 E$ G* D) {& H' E7 ?1 P // attributes
// operations! W' Q5 X) R/ e1 o" f* a
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框
" t) b, I/ J$ K BOOL CreateChildDialog(CHsPMEDialog *pChild);, f1 k/ C1 D- r# n: v+ f
};

! H+ L( M* z" V9 @1 vCHsPMEDialog* g_pHsPMEDlg = NULL;; s' n( `. a: s6 m: n
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;% s! L8 F4 p2 u; Z: F* p; p
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)( l3 f7 H* u. s: R7 R/ e
: CDialog(nIDTemplate, pParent)
  j- g0 c' W  `( k4 g: T7 M* Y0 J+ m{
3 s) ]9 K' |: O0 u  \  _  t$ P //{{AFX_DATA_INIT(CHsPMEDialog)
% X4 j5 \- r% S  // NOTE: the ClassWizard will add member initialization here5 y. a* r( }* T# i) Q4 x
//}}AFX_DATA_INIT" i* D0 Q1 j; t8 \- t
m_pParent = pParent;
; D  Q& q( K( t2 z0 g3 E9 i6 u m_nTemplateID = nIDTemplate;  v) ]- `+ ^- ~, N  ^
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表$ l+ {( W' z0 C; ?9 J
m_pNext = m_spHead;
9 E8 j8 Y. h7 i: N8 Y6 O$ K0 [ m_spHead = this;, E, ?  }6 D) B- B- I, O& X
m_hkCBT = NULL;
/ W6 w# F1 w  ^( Z1 y4 Q( a}
CHsPMEDialog::~CHsPMEDialog()
! J/ a9 @; V2 L7 r{. r+ w, `0 h( O' q7 }/ h5 @9 m" A
// 从链表中删除本结点) ]4 }+ ]/ i7 W
CHsPMEDialog *pTemp = m_spHead;
4 E( B9 ]0 M6 b8 c6 B# ? if(pTemp == this)+ X/ `) K4 |9 N# o: ~* `
{4 ^9 p/ n+ Q9 W7 H8 u9 S" w( q
  m_spHead = pTemp->m_pNext;
2 f- c/ j3 a" b3 [/ ~1 M }) G( r# [' y/ H$ y% q" F% h  O
else# ?  X0 Y" ~- z3 K$ J' o
{
! y: I7 g  k( w& z; k  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)" U& x, F0 n2 v% a5 T2 y  _
  {
9 `4 b3 f- ]  S# @" S0 c   if(pTemp->m_pNext == this)2 U, D4 Z+ E4 g$ v+ ~( w' x
   {0 D5 Y& j+ P8 S4 L8 q# r2 Z6 g' K7 \
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
3 i; @" @- E$ x: n$ ]) E    break;
, O. Y4 b- p) c5 W! u; C   }
. E6 |# o1 f( {) |$ n/ \- @  }
( e, B, m3 J+ X: h* N5 J: h" | }
' n  o. S% n4 A" _}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)9 v$ M  Y  p! v! Y
{$ F7 o: j! y5 h1 N
CDialog::DoDataExchange(pDX);
) N2 G: Y8 F8 H! H# f( A' | //{{AFX_DATA_MAP(CHsPMEDialog): t9 D" G+ N0 Y. m
DDX_Control(pDX, IDOK, m_btOK);! D; D( O2 c4 r6 M
DDX_Control(pDX, IDCANCEL, m_btCancel);
/ E5 c0 R( y% ^: E, G DDX_Control(pDX, IDC_BACK, m_btBack);5 S8 K' C( S: l  Y, L$ Z0 ]$ v* X
//}}AFX_DATA_MAP0 V$ X. @& Z. |& t
}
( X- I& e! ]3 x% K/ O
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
& x0 }+ g' L# P. ?" ]" c+ [ //{{AFX_MSG_MAP(CHsPMEDialog)9 g) `$ \& ?& b& }
ON_BN_CLICKED(IDC_BACK, OnBack)
1 Q! a1 ~0 o0 y/ d: l ON_WM_DESTROY()3 K/ @' T' ~9 R. k
//}}AFX_MSG_MAP
; b5 i% u# a1 t+ Q; {END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
' W+ _1 D  h9 D+ j/ a4 a6 M, Q/ X) n// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
# s+ @' \. i, D4 C" G* T{5 K  X% y# ]7 L# Z1 U5 Q" X, d
m_pParent = pParent;5 B. ~# _/ m7 ]; W: d
return CDialog::Create(m_nTemplateID, pParent);' W+ {2 P0 M2 x- f- F
}
8 l0 o3 g8 v# c5 C) T
BOOL CHsPMEDialog::OnInitDialog() $ L3 r  u' Q( C/ g# i1 q9 t  O
{
5 M5 w  Y; H# U) [ CDialog::OnInitDialog();
// 设置标题栏图标+ z  I' U" L% q3 Q: N% w% W
SetIcon(m_hIcon, TRUE);' G$ X3 w% n8 T2 U
SetIcon(m_hIcon, FALSE);
1 z$ P. n% ]0 ^& W' t/ r* P& p
/ ~  B! s8 E3 N: i; y3 e# n // UG的对话框的几个标准按钮没有TAPSTOP) ]6 |1 d/ E& Z- Z1 E# U! ?6 c. W
CWnd *pWnd = NULL;4 _4 A7 ?2 D+ U  U! [
pWnd = GetDlgItem(IDOK);3 f, L; M: x: i4 u) P' {
if(pWnd)
3 g" y6 }& B  D1 R& u/ h {
( Y6 \" N7 J) K6 Y" V: P  pWnd->ModifyStyle(WS_TABSTOP, 0);
8 g- u  g2 n- x }
6 {6 r, i! e7 L pWnd = GetDlgItem(IDC_BACK);) R" O) G& C! v2 N6 M
if(pWnd)& ~* a1 D: U& V9 g
{
1 ~4 g8 ^. o9 e% [3 t* j  pWnd->ModifyStyle(WS_TABSTOP, 0);
4 D# i1 r2 r9 B, [; m# t }
2 l- H6 v! z% n4 N8 k; T) i! n: V pWnd = GetDlgItem(IDCANCEL);/ H: L4 j" \" K# H$ v
if(pWnd); i0 Z; ^) Y2 E6 b% ?$ u
{
  o: D* f( g; ]  v3 E' I5 \- E  pWnd->ModifyStyle(WS_TABSTOP, 0);
7 t( {# X, c" ~! ]) Z: P2 t }, w5 D5 V8 L" }7 W+ k% k
6 Y1 I0 M% d3 P! T
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
# [% L* R% |* O/ d& c, X if(m_hkKeyboard == NULL)
5 Q( R: C1 D* b! V4 H {! s0 |1 H& x. K% P
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
2 d1 u+ n, [4 p9 X9 O# k- N% S) G }
! w- e; ?$ `! r3 s1 h if(m_hkKeyboard == NULL)
. y: \8 p& p. Z, x9 G+ b5 k+ w {4 P5 D* n  c9 \7 n5 V
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());5 [5 e) \$ R) y% e: r: G6 _
}
if(m_hkCBT == NULL)- F. U6 f6 S9 O- I4 C
{+ N& z% u% e, p, a2 M8 _0 K* X) c
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());) n* [3 Q' n  b9 n- h6 e$ n
}  Z+ |# P" Q5 a7 ~2 J  |( V
if(m_hkCBT == NULL)6 T) F1 Q- d* G) ^. }
{* K/ F9 I; S; e* b  R3 ]& Z
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());$ e/ p1 D' A6 d8 h" v
}+ B8 W' ?7 q/ O2 @% y5 @! W  i" s
; Y9 _4 X' w5 x( |7 K/ ^+ e
return TRUE;  // return TRUE unless you set the focus to a control
# o: i  L; q+ H9 y1 L0 v! {               // EXCEPTION: OCX Property Pages should return FALSE' o+ L" [" b) B% X, {' x/ t) x' _$ k, P
}
void CHsPMEDialog::OnOK()( t: r( V6 b& V( b. p/ x8 ~
{
3 R* [9 R5 `8 Y. M' \ CDialog::OnOK();
( r, B# \8 N$ Q; L) h7 D9 A* e. z if(m_pParent)0 y$ U! O& p( ~1 _3 i$ {5 ~. C
{! e0 G; j7 Z: w$ Y) L0 {8 W
  //m_pParent->DestroyWindow();
- h, i- d- r+ j7 A6 S, f  //((CDialog*)m_pParent)->EndDialog(IDOK);$ ?+ p$ I; z% g$ H" {4 v+ L
  ((CHsPMEDialog*)m_pParent)->OnOK();
4 k- f5 C  C) x# A/ I }
% Y1 m# z% [' X9 L. C5 k}
void CHsPMEDialog::OnCancel()/ ]! T1 H3 ]7 c: p
{. R9 f* B1 h0 j0 p5 ~/ ?
CDialog::OnCancel();
8 \# H  u3 o& t! R if(m_pParent)
4 g8 w: D( c+ `& z& S {
- U2 K$ a3 @( N, }5 ~* P+ n2 {! `  //m_pParent->DestroyWindow();" s2 N# H4 U) A4 _/ y4 u
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
1 x$ T& @0 t4 I" D' j5 }5 F: R  ((CHsPMEDialog*)m_pParent)->OnCancel();
6 ?8 o0 k9 @% P }9 n1 l0 c% w7 v+ x4 G
}
void CHsPMEDialog::OnBack()7 C0 A1 t  Y2 Y# L- L" C$ x
{& Y9 o: h- q' ^2 A! T/ `* l% R
if(m_pParent)$ u. k& b1 O$ d8 t% i+ `" p
{8 [0 Q% `  D) H, o
  m_pParent->ShowWindow(SW_SHOW);# ~, k+ j  d$ H6 B( Q7 f3 \
}* A1 X4 `5 y0 {# f
CDialog::OnCancel();
1 C; ]. ~. U/ W; t5 v0 o: [* ]) ~}
1 B% F/ @( @2 m; {& y- U
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)% h! T& H7 q* Z( D- `4 j
{7 |3 z& e( q5 R% Z
BOOL bRet = FALSE;: \$ t( A" S9 w6 M. ?) w' Y
if(pChild->GetSafeHwnd() == NULL)9 F. M8 L3 {) i" @- D
{
! f3 W- V. U; l) T  bRet = pChild->Create(this);# |9 b: n) ]# a& m5 i/ j. a5 G
}
- C4 h5 D8 o4 b; j) w* ] bRet &= ShowWindow(SW_HIDE);
) Q5 T& X+ H' S' D* j2 W0 U5 S bRet &= pChild->ShowWindow(SW_SHOW);8 s" ?8 J0 X/ J: n
return bRet;9 L3 a( s; X- H/ g* k# X0 B
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)5 k$ K" o$ f* }, n& f$ P- N
{3 J/ M5 M% T) P2 e, B
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
6 Z, O, v% ~3 ^7 m {7 z; F% b* @2 |) Q3 A
  //TRACE("Key down/n");: U3 U2 _# w$ O- l
  CWnd *pTopWnd = CWnd::GetActiveWindow();
# h  d( D# r& s/ L8 Y$ Z0 L/ \2 v8 E  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd)), Y2 {. {2 a! F/ V) G4 g
  {7 S# j3 V0 C# H& v  ~
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息1 Q3 i5 J/ U' u! N
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN), ~  P% _3 p0 \4 J3 c$ }, F
   {
" p" b5 [$ r3 O' E6 Y: F$ w    // 只截获tab、esc及回车键
; _; h, i. i' Y# M! x! D    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
% ^" V# v  ]. u+ B8 l8 P    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);- o- V5 ^* Z7 B6 {! ~6 G  M. G5 F
   }
3 ~/ ?/ A- Q  o2 W5 l, G  X. R' t   switch(wParam) {6 D; U9 W$ l% S4 S& }
   case VK_TAB:
) G) @5 e" J+ h# D: f    {0 V) w/ F7 v  p$ R5 G
     CWnd *pWnd = pTopWnd->GetFocus();
2 P$ v1 w: j4 E6 @8 V4 e5 Z     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
! G' o; ~7 o% o  c8 j* r$ A$ P3 L     if(pNext)3 F! w# o! @! {- K$ V
     {. a/ s2 ?& d0 \8 T7 k" ~8 M1 o
      int nCtrlID = pNext->GetDlgCtrlID();
6 Q0 W! Z5 ~6 v! d. s      //TRACE("CtrlID = %d/n", nCtrlID);
: u8 L1 V: \; V, |- I, h* m      pWnd = pNext;
4 r% a& p3 E/ b      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
% I5 u" v. H2 E, \7 T' R' v; H" G      {
; j  n5 ?, S% w( l0 z       // 根据UG对话框的属性,这三个按钮是没有焦点的8 G2 [6 b- D+ ~) w, [8 H
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
1 o6 |7 [8 J3 M# _* n. B       if(!pNext || pNext == pWnd)
) n7 J) E: x) Q$ G       {9 P5 b( [7 v! ~2 }5 _5 ~( ~/ J+ L
        // 对话框上只有上述三个按钮
3 i: A3 f2 @, p$ C( Z- X  G        return CallNextHookEx(NULL, code, wParam, lParam);$ r) V: }; C: c' {
       }/ G& b0 `4 O# K; J3 C  r) {
       nCtrlID = pNext->GetDlgCtrlID();) V" |" M' t/ b( M9 Y
       //TRACE("CtrlID = %d/n", nCtrlID);' S" Z! H! g1 I4 x  [! N
      }' o& t: Y$ P' B: w0 [; Q
      pNext->SetFocus();
4 g- h  I3 G1 u     }) X8 L% o# R  a6 j! b
     //return TRUE;
+ z) _! r5 U" i0 O! ~    }7 T' G3 U! O' P8 @
    break;
% F8 O* O7 u& R/ M/ v   case VK_ESCAPE:
: r# }" e6 U" t/ \' [5 `    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);& o* ~6 i4 a7 E/ S
    //return TRUE;9 S9 @" e0 r- B; w- ~3 E
    break;
& n+ j# |: C5 G! I7 m4 m7 u4 N) ~" J   case VK_RETURN:- k1 d9 D9 Q, N9 a1 k+ d; J. r
    // UG实际上并不处理回车键; ^; i" x0 i+ y1 ^; u6 H- _
    break;( F& z6 N' c9 u! D! b7 `
   default:; E+ w. J; c9 o
    break;. ^1 @1 ^2 B1 n# O: t  w- q
   }
# A+ w0 ^8 f1 [/ {! m4 l, Q  }
1 j' m6 u3 }4 w/ `; T  _: ? }
" W7 {- N" W* ]( z1 b return CallNextHookEx(NULL, code, wParam, lParam);& x; G) v8 g# @1 ?( {
}
void CHsPMEDialog::OnDestroy() $ A: `  l. D& ]* `0 `( u2 }
{
# U1 Q$ ~* X: }$ R$ {) L' P CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
% s2 G8 x( c0 ^ if(m_hkKeyboard)
+ m* j1 T, R* p {
7 ^; A4 j4 p: K2 r' X* C  UnhookWindowsHookEx(m_hkKeyboard);
/ `! Q/ j" L. E( z. ~  m_hkKeyboard = NULL;
) Z$ [/ e; z9 P% S  ]$ o+ R }
if(m_hkCBT)
/ u' p3 o' h* w! X1 W {, l$ M! F, m* B: E5 H9 j
  UnhookWindowsHookEx(m_hkCBT);
* l/ H$ |; T) |6 T. t  m_hkCBT = NULL;% J/ S* Y5 |8 ~
}
4 E" ^- R: K. Q" H! \}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)5 b6 S$ z, G5 G: A  |/ F
{, {6 P3 i1 `! F! {- C* R
CHsPMEDialog *pTemp = m_spHead;) |" d! t2 p" P6 K
BOOL bFound = FALSE;& `9 z& T' K+ D+ Q' o
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
- ^! [* t, |, ?4 A. ?+ R {* j& @4 g8 a+ w  Q, g5 g0 X1 A
  if(pTemp->m_hWnd == hWnd); F- D( p% m7 l+ r1 g, [
  {1 w7 w" x- ^5 j9 n0 _6 v/ R
   bFound = TRUE;  B+ p4 V( _+ M) z' s
   break;
. m$ Z2 q0 ?5 C& O9 R) C1 X. W# @3 b7 f3 E  }
2 O7 J" {: c4 a& v5 s; o  S }
: @* _% l+ e* L& ^, x+ Z# ~ return bFound;
- b: T) H- C! R}
// Returns the HMODULE that contains the specified memory address
4 [9 {1 P  h7 S' x$ ?HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
, T: x& g8 F0 \  ]4 R{3 G8 U; M; A2 S$ Q) u
7 V7 w( D, Y0 u
MEMORY_BASIC_INFORMATION mbi;  G* G, m9 g" x- c" \& q
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
& X& R! |8 L$ Q  y& s7 H9 R- N- ?  ? (HMODULE) mbi.AllocationBase : NULL);
2 r5 z2 _1 J8 ?+ C}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
$ {; n- W% J2 _$ i" [{% S( }5 d. h6 f6 l' z' `; ?$ N
if(nCode == HCBT_CREATEWND)9 F3 P+ a5 l4 ~" w  A' {( E% N
{+ D' p% O& T$ c  M& x! K  O4 h
  //TRACE("A Window is being created/n");
3 X4 |# W: ~% |  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;; t# ?: a% v% P6 U2 h3 `2 Y- t
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);& E, [: q, Y& J5 V
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))6 p& {/ ^) v9 u4 a
  {  n( v5 b" K' Z9 L* J; c' H$ R2 d
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应3 N2 s  ?' r8 V3 ]3 ^0 o3 I4 U' @
   // 取得窗口处理过程内存地址7 i* S" O2 k. }' D* i" [
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
1 V1 v- M2 B9 f2 I0 g- O9 X   if(dwUserData)
/ i6 ~; G0 [" v   {
$ l! x9 i2 R  ?( {8 D5 s" q    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);( E+ K( U" B+ F
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
9 A$ a$ u7 x! I; Z: H4 t; g    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);) c2 `* ?7 K  S; ^' _. U1 w8 J
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
0 K! z6 s9 y% X6 N    TRACE("CreateWindow Frome Module: %s/n", szModulePath);9 N/ c- q5 H) T( a7 u* z; q: M; q3 P( K
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
8 W3 h+ m8 H- ~/ F) h5 {. W& s    if(stricmp(szUGPath, szModulePath) == 0)
+ K* f$ X' |/ n8 x6 B    {7 w- }$ Z% }1 x* D9 S4 A/ ], t! C9 ~
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)( o1 x5 A8 f( X" s2 c: ?+ A2 S
     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)6 p/ v5 S& l3 `1 J6 O
     {" O; e$ i- Y( t/ [& s1 i
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
4 E, x# s" M, e1 q7 p% }! J      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
( H. t& d4 p, B; L& x/ B8 Z; M       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
& A! i$ {, A. S' ]6 b/ \      {( S3 h3 }: a9 z9 {. m; ~
       // 窗口非本窗口或其子窗口
+ v6 f  G! u. G1 u( p; n; S% Q2 Z0 R1 ?       g_pHsPMEDlg->OnCancel();( T2 o* o4 N- S: m
      }5 R  C9 K4 T" W. i2 F  ^
     }+ e) x+ p# r9 [& q6 l
    }
% {4 p" y: F5 {- Z+ i   }& H$ B- f0 ^, ^) u
  }; g' p# g- k1 x7 E9 J5 E
}: D8 ?3 V0 d; G( }9 ~
return CallNextHookEx(NULL, nCode, wParam, lParam);6 }8 ]- y, z, `
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
- A* w: k: F3 h0 N' x{$ Z. y% L- v) s6 ^" z$ l
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来( o5 Q( S! G, _1 e0 p1 W
$ X( G2 F; }8 ]6 g
return CDialog::WindowProc(message, wParam, lParam);1 P7 l. Q0 ]% k
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) , |/ m1 t3 O9 Y7 B3 T
{
6 }- t$ r& v9 G6 z0 |3 e% j
% P* f! I* k, R) ^3 R4 x) X return CDialog::DefWindowProc(message, wParam, lParam);  L* \9 t4 r5 w
}
$ j9 X' [8 z3 _. u, X+ M5 s
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了