PLM之家PLMHome-工业软件践行者

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

[复制链接]

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

2470

主题

1275

回帖

8万

积分

管理员

PLM之家站长

积分
82170
QQ
发表于 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
# c: K, e5 T( u/ H2 q" A( c// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
8 B. }- u7 [- v$ c//    该类来自网络,稍作修改,版权归原作者所有+ h. n4 {$ c: u
//-----------------------------------------------------------------------------
; q6 ~' I0 |1 j& n& dclass CHsPMEButton : public CButton
# Q( c2 J: o0 n) C3 {) \{2 y  G9 M& S. ^! _* p& i3 G$ H& O
// Construction
1 v9 r' }1 F+ u  v' zpublic:
" o+ \$ `5 ?( }5 E CHsPMEButton();
0 n% G" h2 s6 t( M , L; a/ \1 O) m
// Attributes
1 I& Y$ L1 y, |+ N$ Hpublic:9 O4 e6 [1 v' \  g

$ y0 T0 \6 f0 E! L5 ~3 N // Operations
5 C9 I; Z0 v, E+ upublic:
& @% s9 _2 a) {" `( n inline void SetNormalTopColor(COLORREF color)- E( J+ i& T: d2 R
{
# J0 M1 d1 }4 _7 A, l3 V0 Z  m_NormalColorTop = color;1 v2 H* `* h$ a9 e
}  W" j( \1 M1 ?  h3 C' O
inline void SetNormalBottomColor(COLORREF color)( R* B) K6 w' U
{
; v, G4 J3 y' s5 u2 K% ^  m_NormalColorBottom = color;
' [; ]8 f6 U: _& I }
% G  J7 ]; ?6 k" k" P' s1 a inline void SetActiveTexTColor(COLORREF color): _* `5 v9 S1 f7 u) B8 A8 E. _3 K
{; T4 \4 G( l5 z; s7 Y1 [4 b
  m_ActiveTextColor = color;; C0 l$ U& t# R3 e; H
}
+ H  Z1 V7 ~+ r1 N inline void SetNormalTextColor(COLORREF color)
3 Q/ n0 s8 e: _5 ^7 n {
2 e% F* n9 v, e/ c4 {' T  ~  m_NormalTextColor = color;- G) W1 \% t9 L+ q2 a+ U: U, s9 X1 Y
}
" ?9 L5 l; P- T7 X1 D inline void SetSelectTextColor(COLORREF color)5 ]0 b3 x+ ?; F6 ?3 D- N: v
{
, p" G9 E% g1 ?! l/ T  m_SelectTextColor = color;; B  A' E; b7 V# q1 e& u
}
6 c+ j) g& [" t& p* Y inline void SetFrameColor(COLORREF color). F; g3 V% Y6 P1 h! Q
{
) {2 i- X: u+ e0 S5 J9 B. m: N+ Z  m_FrameColor = color;
" m' ]- Z$ I+ L& E }$ a: W2 e$ P  R0 |; S- r
inline void SetActiveColor(COLORREF color)0 V7 r! a+ E/ b% t* _
{
* t& h1 u4 i8 t; U4 _  m_ActiveColor = color;/ S1 p1 i1 q( y  Z" B5 u
}( P" k8 e5 R. H
// Overrides
: f- a8 D: q4 K0 l. E( z5 @( Z // ClassWizard generated virtual function overrides, w: s. B) y  n1 Z: l
//{{AFX_VIRTUAL(CHsPMEButton); Y; _4 t) j5 _9 L
protected:
/ P& }+ }- {1 b4 Q virtual void PreSubclassWindow();
1 [$ B# w; @1 d2 C$ Z //}}AFX_VIRTUAL! o/ e/ }' x' M: t

+ Z$ Q8 ?) G$ P. Q; ?" @6 W6 E // Implementation
; Y$ \5 n, ^, q* d& gpublic:2 e' x# A- r5 t( ~& i5 K" a
virtual ~CHsPMEButton();
6 e# s( S, n/ ]+ e4 \) _6 ]0 d6 _ & a: E7 d4 W7 S$ [
// Generated message map functions+ B/ }: a# w3 F* T- L, x: T
protected:' ^5 O" O! A. m) n0 Q2 \7 e2 t7 `7 f
//{{AFX_MSG(CHsPMEButton)( x1 H% R+ ?6 l+ k0 P
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
4 w, r$ X) r! E$ s+ E  D% u //}}AFX_MSG: C. H- v2 v4 b  B8 _, v  d

# w5 Y  P, V' E void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);5 Z5 U3 W3 f. a0 q7 d" m
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);2 `& X, ]9 y$ S) I) D8 H! K
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
3 \8 L5 e  T0 c) n. P LONG OnMouseLeave(WPARAM, LPARAM);
* X% i+ h% h$ \ BOOL m_bIsMouseMove;
" D1 d: v, _: O# F1 i0 t" x
. }8 X7 \9 S# N. o) x$ F& b COLORREF m_FrameColor;5 G5 C! g) r7 B
COLORREF m_ActiveColor;& i& F8 ^& v5 I1 X7 \0 h% g6 r+ _
( y% J4 P: i# S" Y; {' S3 R; O
COLORREF m_ActiveTextColor;+ C  }% I/ Y! o5 @
COLORREF m_NormalTextColor;7 t- M. E# U) U( ?0 L, i
COLORREF m_SelectTextColor;
+ h8 a1 i# r: s7 c
$ n, ?% x  d$ p  U% V# B6 b COLORREF m_FrameHeight;$ x7 N/ \( z8 L; ~2 d* w
COLORREF m_FrameShadow;8 g4 d4 J# _4 b0 T
* [4 z6 |! c) M1 l) |1 `
COLORREF m_NormalColorTop;
. Y( ^. @0 A' | COLORREF m_NormalColorBottom;
. G8 H5 b$ h" ?8 _: N  j
0 p2 J- c/ a/ M9 M7 @% H( q DECLARE_MESSAGE_MAP()
9 J) [' D! c8 y4 m* B- Q};
/////////////////////////////////////////////////////////////////////////////
2 A( \6 f% O& w// CHsPMEButton
CHsPMEButton::CHsPMEButton()
# V8 r- @' m- p6 T4 s# a{; ]& _' t* M& J7 w( s9 h6 e
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
$ H  P9 A, V9 J7 n; |& f$ f' f. |4 Z m_SelectTextColor = RGB(0, 0, 0);
( K& I* g0 d+ y m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
! S" S# w9 F& `, T& |, Y% ~ m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色6 k/ W1 {0 |. h. V5 @+ x' I0 u4 Q: ]
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);+ [! L4 e5 K. h  [/ ?( m, n/ ~
m_FrameHeight  = RGB(230, 230, 230);8 M1 w3 b$ p' b
m_FrameShadow  = RGB(128, 128, 128);2 S; W8 O/ \5 x- D
}
CHsPMEButton::~CHsPMEButton()
: b+ w4 f' h  G- N6 A{, N  u/ x& @7 O( t
}
( g' |9 v- K5 C
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)1 J! ^; z, D" ^$ Y
//{{AFX_MSG_MAP(CHsPMEButton)
% x) L2 T( B0 Q. D4 @) @ ON_WM_MOUSEMOVE()
+ S, O. ?* ^7 d$ t+ { //}}AFX_MSG_MAP
# O/ ^1 I1 j! b: { ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)7 I$ o# A) g4 N, w# [5 V9 P
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
6 ~3 T9 c" C) ^$ x4 C6 T  O// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )* S# }! e& _0 D! I" f1 U
{
1 F, @4 i5 f$ @; o //*+ m8 c( |' x+ {5 s) O: x
CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
- T" N; h' h2 E4 `, \, D9 y" | DWORD nState  = lpDrawItemStruct->itemState;
0 }# I, j1 d1 `! ?' } DWORD nAction = lpDrawItemStruct->itemAction; - N3 F& ?6 ^" X1 e" s
CRect rc   = lpDrawItemStruct->rcItem;
# t- U$ o7 ^6 W* \. R  T UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);
3 S* J3 w. T. W% S! T9 p CString strText;
  A! x5 K' _$ y5 P- ^4 ` GetWindowText(strText);
if( nState & ODS_SELECTED )
5 c+ b/ _& Q5 k7 i' F {4 h6 U5 |8 a" i5 t, {' k
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);( I, U3 t1 Y8 ?5 m+ V  Q6 u% D" {* z; t9 C
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); ! a+ a( a: o. Y
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);, [( U2 ]) r0 U8 p$ @0 h$ M5 h* s
}
9 T6 \" a0 b4 b3 ~: W* h3 Y* k else //Normal
5 D2 }. \' W9 y {
4 Y' D3 ^$ E2 {' p5 R9 a1 \9 j7 ^  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);  W# \) s2 Y, x# ~9 G
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
3 \1 R; X0 L- T6 m8 F0 n/ P* w1 E }
if( m_bIsMouseMove )
$ ]$ Y2 |/ C) ]! B) w7 C, T$ n, y, b% V {
1 c- S$ l6 H, e( P! \7 c  CRect rc2(rc);
6 H; @+ V; Q: M7 {8 P9 Y  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),; f$ A& i( P/ A) |
   m_ActiveColor, rc, rc, pDC);
7 u7 C; R; Z1 \1 }" }; s  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;. _' H9 z# x" `% M* `1 e' X
  NullBrush.CreateStockObject(NULL_BRUSH);  m/ f$ H9 |" Y  u+ y
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);( o& U8 _' P- r$ @- g% L1 ~% ^
  
% p1 H; y9 b3 w7 A# J- X  CPen Pen;
% r6 m2 m+ F3 p- T8 }. i, A  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);- d- H5 ^& }$ R. ?/ Y' W
  CPen* pOldPen = pDC->SelectObject(&Pen);
% P3 Y+ E8 d- b3 b! R2 U2 b  rc.InflateRect(1,1,1,1);3 f9 h7 o8 S, Y1 T8 x! k  r
  pDC->RoundRect(rc, CPoint(3, 3));# ?$ w1 g& h& t' N- m
  //rc.DeflateRect(1, 1, 1, 1); % m* ~  f- p* j4 K# `4 Z; t
  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
$ m' u9 V" s" ^8 n  N  `  
2 L/ G. B3 m! E2 X  pDC->SelectObject(pOldPen);4 q* d0 j( F! t7 Z' |
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
8 \8 a) @# x5 q7 Z }
" Q+ G7 v  R1 ~$ v! W$ M+ Z 3 M2 h: \! ]8 V0 @# r; d
pDC->DrawText(strText, strText.GetLength(),
6 ?* b$ ^% k+ p4 t& X  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
7 S2 o' S/ G/ d3 p //*///
, W7 H5 K) S" S6 v5 w7 b$ i, B$ }}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) 0 w! |% S, H% R8 M
{* i+ A: Z- d( Q6 U: r# p
// TODO: Add your message handler code here and/or call default
2 ?5 m/ L5 N0 H" @* Y  H: ?% R; K# G if( m_bIsMouseMove == 0 )
9 k' {. C6 T3 u {0 P5 r+ E$ p3 A) A. U/ C
  m_bIsMouseMove = 1;- M3 L8 z9 H1 l6 `$ n
  Invalidate();
( G# |2 c# y6 I0 y6 o  
/ G" P: I3 a: V- v0 K  TRACKMOUSEEVENT trackmouseevent;( w7 y. k+ `$ k2 T: R7 t
  trackmouseevent.cbSize = sizeof(trackmouseevent);! K+ S$ B" L$ K0 ^" K7 D% a) r1 ]' f
  trackmouseevent.dwFlags = TME_LEAVE;
! @6 A3 w# K9 q, T  trackmouseevent.hwndTrack = GetSafeHwnd();6 ?8 j, _+ U: \2 `2 f
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
$ e8 i1 h; E' b! m  _TrackMouseEvent(&trackmouseevent);' l4 _0 c: }5 r5 P& N: ^- D
}1 b& A8 e9 W" f+ W+ w: ~* s" k+ S0 I
) U$ m+ H, ^) d
CButton::OnMouseMove(nFlags, point);
$ @( Z8 O4 x  Y}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
: D/ K# i  q" K" a8 b# U{6 r3 ~2 U3 [) ~4 k+ n3 o0 m
m_bIsMouseMove = 0;
3 ~1 J# O8 `3 I9 \0 y7 L( H4 Y Invalidate();
return 0;" U, D9 |9 W  _) s8 E
}
void CHsPMEButton::PreSubclassWindow()
# R6 H+ ], L8 [) v{: Y: C$ C3 N3 g& x
// TODO: Add your specialized code here and/or call the base class
5 e+ b6 E( |+ v! y9 o/ z UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
2 x* W  q$ i' ]- C. @$ S: @ SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();* x# T. Y% i" H2 l+ X
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
% w5 o2 F$ q- {* v' O{
$ F4 h( o9 c7 }$ v CPen Pen;' Y) H( ]+ `! z% t- z4 B# m, [6 R
CPen* pOldPen = pDC->SelectObject(&Pen);
6 A, ~, v  n; k/ {, Y
5 f5 t1 D! w$ u; ^/ X int R, G, B;# K! M# b, Z7 d+ o
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
8 E- P6 ^2 F8 C, N9 k G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();% H8 m) H. _2 ?/ d, W
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();9 r9 q# @& L' E* P
4 s0 q, Q( C, G1 y# S0 W
//R = R>0 ? R : -R;
: Q) y  Y' i% u  I: _3 x) } //G = G>0 ? G : -G;# X& a* F" L# K. D3 d2 \: V
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);0 l, H" x+ w- ?8 K2 a" n
COLORREF ColMax = Top > Bottom ? Top : Bottom;
. t) m1 g( a: U# i$ {& {) y% k COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
; j% M: Q' l' p+ ^$ Z3 G& Y {! N# S5 f- N( u* R. P
  ColR -= R;1 `8 w/ A+ \) r9 @; A
  ColG -= G;
7 W: ?4 K/ u* J0 r, s  ColB -= B;
  /*
; m6 @# v+ [7 N6 y# |  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
9 z5 {/ ?3 p( R' H& v4 O5 r2 @   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
/ x( p' \  n* e, `/ v   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )- t: w  A# f0 y
  {
2 |. k3 n3 m9 `& H  C6 x   R = G = B = 0;
; N) q$ E) }8 T/ C- u# u  }///*/

" T( Q% q: D5 i, @0 m) E: Z+ _  Pen.DeleteObject();
8 J: V( o$ r  m# G  a  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
6 T7 l& O' P8 F% L4 n% D; E. m6 B    7 _' m: L3 o3 X" D
  pDC->SelectObject(&Pen);
( x# C! s0 j) Z  `  
! R# k+ J1 a/ z  pDC->MoveTo(rc.left, rc.top+i);; `+ t$ T- k0 j
  pDC->LineTo(rc.right, rc.top+i);
  q" ]- w+ X4 K5 v& ` }
pDC->SelectObject(pOldPen);# W8 t# B% a) @3 J% [8 W# G
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)5 J) N, h* i! h, M4 Q, P
{
* I" z: X+ b' n- h CBrush NullBrush;
, [/ T. f( ~# B: X; E9 `. G* y" l( z/ b NullBrush.CreateStockObject(NULL_BRUSH);
  [( \$ k$ T2 D" d: w/ z CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;  o# }( a- T: o# X8 a$ u: t5 b! a: f
Pen.CreatePen(PS_SOLID, 1, FrameColor);4 q  w/ J3 j6 z% H2 w
CPen* pOldPen = pDC->SelectObject(&Pen);
( P4 Y( Y$ f" X8 z
* ?. x) I: e) S5 d$ b3 ?6 L pDC->RoundRect(rc, CPoint(3, 3));/ V7 G: [! J3 }8 s7 X  y  y
rc.DeflateRect(1, 1, 1, 1); ; N& A2 i7 O. A) U
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
6 l4 L" k) D, ]: U6 a! Y- {% q. N pDC->SelectObject(pOldBrush);, `+ l" G( O# X; L& r
}

" \0 s( ~7 {, I3 ^3 c: v/////////////////////////////////////////////////////////////////////////////
; u& j; @& P5 r1 {: ]: `& x// CHsPMEDialog dialog) w( h4 |  j: J; K" Z: r
//-----------------------------------------------------------------------------
3 ]* b+ D9 l/ A' W1 f8 X1 x: F- m* {// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
5 I0 i, c: `: E5 T- B5 W" m//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
9 Q1 _: O& P5 n5 n& Z. S//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口% t8 w. X: Q. V" a" @+ Z
//   指针将其显示出来,然后隐藏或销毁自身% E) [$ b6 |' m: Z3 o
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
1 j% y; ]* N- q) ]//    采用的方法为使用上面的CHsPMEButton作为按钮的基类" e4 i, I" @+ e- Z$ h
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
7 C, z2 }& b+ }) h//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
' ]  e  a+ I0 w: `% f% a5 O//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
1 X4 h" L! I+ X4 n. E0 I: e//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框; @! `, B: J6 ^( o% s
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。4 q0 K: p; ~) @- _9 T# j
//-----------------------------------------------------------------------------
  L: U# W6 o+ `3 {3 _// 注意:
9 x8 v+ {: D- D" F  V! H1 U// 1、在构造对话框时必须给出其父窗口指针
( u( }/ c6 g& y: j) Y' _// 2、在初始化基类时必须指定对话框资源模板ID; n" V6 p. ~3 g+ w4 h9 d  T6 {0 G
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
9 V0 e5 O0 G4 c; z// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
; d. d  L' ~, g. l//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
6 ?6 W& i) D9 B. S: \. z{
' P( Q/ n5 Z. |' y DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
" W2 i  A2 e% y$ S7 h// Construction7 s3 t9 K( |8 q3 ~% Q9 p9 L& ?$ \* Y, ~
public:& L6 _4 ?" q; F
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
" I! ~* k9 S5 D2 f( D# C) e ~CHsPMEDialog();* @% u2 a+ E" R) Q; ?
BOOL Create(CWnd *pParent = NULL);& e6 q1 l" J% n' d" r7 r! S
3 y7 T# x9 w; x
// Dialog Data) a, l  j0 @. g6 t% y. D
//{{AFX_DATA(CHsPMEDialog)4 G1 R- @; }- v8 K, U
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };
2 N' Y3 g, |6 a) ]  // NOTE: the ClassWizard will add data members here
$ @. a2 |4 C) Y, K //}}AFX_DATA
! v3 ^( Q, q# j* ]" M. f4 C
// Overrides
5 Y# F* J# p* f$ S8 ]6 u" S; j+ z // ClassWizard generated virtual function overrides3 Y% s0 m: \. v! d6 e
//{{AFX_VIRTUAL(CHsPMEDialog). `3 N! z, ^! X% D: g9 n& j2 y" n
protected:
) s% r2 M3 z$ A% z virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support) o  J8 Q& C* j4 b9 a- ?% D
virtual void OnOK();0 W' @: k! p2 }# N+ `* B4 K/ v
virtual void OnCancel();
' _( O- X- Q. { virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
/ o$ N4 a2 m6 D" s: A% X virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);; V, {1 r' m0 ?
//}}AFX_VIRTUAL
// Implementation
1 r, _! g* A7 m1 T! [4 p8 Dprotected:
// Generated message map functions
% Z$ v) h/ D# M7 z" g9 |6 p, \$ o //{{AFX_MSG(CHsPMEDialog)
/ K  B6 n/ \$ }) S) { afx_msg void OnBack();
. E, z# r( E0 n& C, m0 h virtual BOOL OnInitDialog();
5 I- t/ X7 V9 B1 L' _% t( P afx_msg void OnDestroy();
) z2 y) J0 o, e) `$ M$ A9 x( ~, } //}}AFX_MSG9 T6 g1 Q6 M  ?' e! Q& @1 Z
DECLARE_MESSAGE_MAP()
protected:
" n7 K1 C7 m1 D/ X% M // attributes  h8 U; }. J. L5 E8 p
CWnd   *m_pParent;     // 父窗口指针
/ c1 r( }, g$ K' x HICON   m_hIcon;     // 图标
0 g6 w: L4 g/ m3 i0 i5 w UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;1 c+ H9 S, Z+ s, o8 w8 m
CHsPMEButton m_btCancel;
. w) n& s9 y" |) q# L7 W+ U+ T CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
$ O' s" }( r) W HHOOK   m_hkCBT;     // CBT钩子句柄; J7 G; n! O" b' R
2 `0 c, b) A8 l3 d9 d! n8 B
//-------------------------------------------------------------------------  D7 V' m* E3 S* g, S7 {4 {
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog- I. f5 h% t, \5 D0 M9 C( i; Q
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
/ @! ]/ ]' J9 Q. A( W8 t // 链表的头及下一个结点的指针( e+ g8 m# a0 s
static CHsPMEDialog* m_spHead;. n1 q9 N2 A* D$ Q$ z
CHsPMEDialog *m_pNext;
// operations
" u+ b: u: q1 `$ S+ e1 W7 T // 键盘钩子消息的处理函数: t& A# l4 v; w& {( ~. P$ t5 @8 n  Q3 |
static LRESULT CALLBACK KeyboardProc(
1 x6 y, F$ h2 N( P2 ~3 r& Q  int code,       // hook code
" j5 ^- ^6 j9 _! l" `, [  WPARAM wParam,  // virtual-key code
9 W7 @9 L  H' R) D% w, R, V  LPARAM lParam   // keystroke-message information
4 Z: t& F1 b! u  o9 T  );# F+ \  e  r" J) r( z* e
// CBT钩子消息处理函数! F5 R% _. c9 X& N9 G: A- [
static LRESULT CALLBACK CBTProc(. V4 p+ `8 Q, p
  int nCode,      // hook code
# _0 c" l; i" l3 u" @: `  WPARAM wParam,  // depends on hook code
* F, G+ c' u6 I0 _4 h/ F9 W  LPARAM lParam   // depends on hook code
- C/ n3 P3 b2 L! `1 h/ W6 ^  );
) @8 k- K, p& g. t1 o
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
1 n$ ^+ b" [0 h7 D4 H( k: E2 B5 X static BOOL  IsWndKindOfThis(HWND hWnd);" }, z( u) k& Q% F, n
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
# P+ ?( U% K* G/ D$ r% [4 b" F static HMODULE ModuleFromAddress(PVOID pv);3 M* g* i5 Y, `  X
public:. X- A1 J3 D2 J0 i0 f
// attributes
// operations" s' R7 t/ _$ S4 n, J
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框
3 j: _+ g6 W5 c1 Y BOOL CreateChildDialog(CHsPMEDialog *pChild);
) V- z6 k8 ~* E( K8 r* H* @( E};
1 X* x* Y6 l6 \
CHsPMEDialog* g_pHsPMEDlg = NULL;
7 s- ?/ i- N' T  W& wCHsPMEDialog* CHsPMEDialog::m_spHead = NULL;6 Z" r5 ~# ^6 U$ m! r
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
, o; ^4 L9 C( k* \: ?  a : CDialog(nIDTemplate, pParent)
. p2 i& C9 {* C7 P! C# Q7 g{
$ ?2 X) [4 Q3 ^9 b2 t$ N //{{AFX_DATA_INIT(CHsPMEDialog)2 y& U1 F# z3 P* s2 K8 W# I( `( [
  // NOTE: the ClassWizard will add member initialization here% y( g( x, s. V7 g. M
//}}AFX_DATA_INIT5 }  E- j1 G8 H# c$ B  a( R
m_pParent = pParent;
( B2 V- l- k1 h; x8 H m_nTemplateID = nIDTemplate;
: X5 K! h" W4 h, C! q2 b3 M$ g m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
8 c% p4 U, |8 }$ r- \ m_pNext = m_spHead;: t# s/ ]% A- v1 O/ G/ L: h
m_spHead = this;
/ p) p# r' h! m  g* O m_hkCBT = NULL;
6 R6 o! v9 X7 m3 _- r7 @' [: F}
CHsPMEDialog::~CHsPMEDialog()
, q" f7 F; @9 X1 j+ [$ F; K7 f{3 y3 W+ x# z* h" L2 M+ L3 R0 G! k
// 从链表中删除本结点
+ f6 D# g- ]  @# k) Q CHsPMEDialog *pTemp = m_spHead;- r! q* Q4 }7 p
if(pTemp == this): L( ]* |7 B1 H) q. ^
{; B  o  A4 q* E6 `
  m_spHead = pTemp->m_pNext;
+ f- N& S8 U) D0 K4 g }! R, \. E- }7 K/ j& M
else
) {/ ~. R: z3 R  _/ C, \ {2 k& j/ D1 F- M8 ~4 q4 R
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)6 Y9 ~4 g! y9 o8 J  l/ H
  {
$ @: n* ?  _; v' g   if(pTemp->m_pNext == this)4 G  k7 E7 ~  _4 b: C; S5 P- Z
   {
  ?9 w) l* U1 ^) ~6 ]: ^0 Q    pTemp->m_pNext = pTemp->m_pNext->m_pNext;" l6 P- v; ?5 c& F. d
    break;
; ~$ A, K, |% W' k3 O$ g   }) e3 ]( q, e' }  R
  }
/ B6 g/ h9 c9 n( B5 `9 P& u }# H% s- E% d9 a. r" D2 O$ D
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
$ N1 i* Z6 F" x* K$ d{
8 F; T( G6 f$ t8 W1 X4 o CDialog::DoDataExchange(pDX);2 t- E7 s. x2 W* V! [' x
//{{AFX_DATA_MAP(CHsPMEDialog)% k0 x) V5 E: G4 d4 q/ c, d) }
DDX_Control(pDX, IDOK, m_btOK);
/ k& b* H% y2 l7 y: m5 ] DDX_Control(pDX, IDCANCEL, m_btCancel);5 A! l- N- S2 s- R7 I% X8 v) f
DDX_Control(pDX, IDC_BACK, m_btBack);9 E8 U( {/ T9 ~" I, |9 e
//}}AFX_DATA_MAP. o& U' E7 v! J5 s
}
: v9 p" H4 e2 B/ b4 R6 ~: M0 b; y
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
' [* o. U; }3 @$ k) H! M5 i, l //{{AFX_MSG_MAP(CHsPMEDialog)1 K( K/ W  U/ m
ON_BN_CLICKED(IDC_BACK, OnBack)
2 k- X6 y: j7 \" q$ ?0 Z0 l ON_WM_DESTROY()
2 F8 U% g4 T+ ` //}}AFX_MSG_MAP
2 u, I/ o; d/ {1 JEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
5 d) T. i( A6 t9 N// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
& o9 B  v  i: u4 a{
7 C/ T) O0 Z" I% w m_pParent = pParent;
% H1 w  V" h* k return CDialog::Create(m_nTemplateID, pParent);
7 O( Y2 x. V) L; w9 G( f% X! p}

7 J8 ?! i" I3 HBOOL CHsPMEDialog::OnInitDialog()
0 Z% X7 t7 g  H5 |1 r1 o{
5 m+ f9 m$ n0 i; S% U: N: i CDialog::OnInitDialog();
// 设置标题栏图标  J7 Y6 h' i, K' \3 T, n
SetIcon(m_hIcon, TRUE);1 Q# q) e3 t; x% D/ |% h' r
SetIcon(m_hIcon, FALSE);6 [8 C* K  j, G2 [/ F6 c
- [; ~  m/ Z# b) @8 J/ u
// UG的对话框的几个标准按钮没有TAPSTOP$ @! A, h7 N9 R, B) e
CWnd *pWnd = NULL;& H3 t, ?/ l: G' U4 |8 l
pWnd = GetDlgItem(IDOK);
: T- `' c4 q8 y; v; k9 j- v1 a if(pWnd)7 a; J8 Z" `! R( O, S9 `0 ^* l" _
{
, t( Q7 E; O& M- u6 V# `8 G8 u  pWnd->ModifyStyle(WS_TABSTOP, 0);9 {0 I4 d7 l! R, n4 j& H
}
6 I3 j7 c: P/ u9 e# {8 o( l pWnd = GetDlgItem(IDC_BACK);
# X# q! C8 f* m/ Q* u+ w if(pWnd)
0 Z8 U4 k- d& q3 i {
  o, K1 M) P1 T! Y3 |* U7 P* D  pWnd->ModifyStyle(WS_TABSTOP, 0);
/ R( @! f* x& q& j# a }
4 K; ?$ ]/ }! W pWnd = GetDlgItem(IDCANCEL);7 ~% ^6 l- n, U
if(pWnd)0 {/ ?$ A7 O3 u, ^9 O$ C6 P6 x
{
4 `. y4 o" |1 K  pWnd->ModifyStyle(WS_TABSTOP, 0);( w- t7 t. `7 H( a4 P$ T* ~- j
}
& H3 I, Q% I" G! i( V3 t# J8 V/ o* u % B0 P4 ?$ }; b9 O$ ^3 T
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
: a1 [1 c2 |% J' o( a if(m_hkKeyboard == NULL)
0 o+ q* _5 \$ T, N# J {
% J4 p  ^! ]2 G5 d' V! e/ H6 ~3 B7 _  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());" l& e$ A$ h: q/ z# h* c( W
}
6 L. t- n  D- s' ]9 e. z+ |7 ^ if(m_hkKeyboard == NULL)
) P3 q- y. Q# z" C {) u3 V* M4 o6 K/ b- ~( @
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());/ ~! d# B- ^& }
}
if(m_hkCBT == NULL)
: a' N  C' g9 v, J0 c/ t {5 s" |5 E3 x5 n+ E  N  _, u% F
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());9 p2 U& M+ S6 J/ \# }4 J4 _8 A
}
3 b4 V; o3 n% U7 ^ if(m_hkCBT == NULL)
- V% X' h( a- w9 k  T- I {7 j1 z' T9 d( _1 o' n/ r0 i' {
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());* n! u% k% w3 e( |
}
: f( S5 l$ n7 S9 i: t ( I% A3 ]3 R+ Z- z4 {
return TRUE;  // return TRUE unless you set the focus to a control
8 |8 ^0 W8 Q* Y- T               // EXCEPTION: OCX Property Pages should return FALSE
- Y# b  t. o8 W. T4 \}
void CHsPMEDialog::OnOK()+ I4 }8 b0 g9 x1 m! L2 t  t
{0 H" A: F! g+ H# B$ q$ o6 f* \7 c
CDialog::OnOK();( t; \; W& [3 v6 F
if(m_pParent), G. h+ [" r% c) R, @6 Z
{
4 S' p0 {8 h  W2 R" {3 G" Z  //m_pParent->DestroyWindow();$ d) g* `( ]: ~$ R: ?
  //((CDialog*)m_pParent)->EndDialog(IDOK);2 o# F: u( {) ?' |/ D
  ((CHsPMEDialog*)m_pParent)->OnOK();
2 t( H' E4 Q5 s& X5 F }. t8 N" z: Z3 E; ?/ q) y. S
}
void CHsPMEDialog::OnCancel()+ w) }) r1 }! b0 O
{, Q# x: x! E8 g: L6 P- i8 M
CDialog::OnCancel();
/ ]; r; N! Y0 {6 e/ O$ p8 H if(m_pParent)+ l/ m& p+ m! y  \# Q9 v) C
{6 r6 @% g" g9 B. D! |
  //m_pParent->DestroyWindow();
" n% _+ T" i4 G8 [' J2 y/ B  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
/ I( t4 p- i" T* ]- L* c4 u2 e  ((CHsPMEDialog*)m_pParent)->OnCancel();1 A. p  }0 N% ^9 Q, H6 Z0 y
}
: b" W* n/ v2 W# v+ i" U}
void CHsPMEDialog::OnBack()1 s- F( w) W+ i
{
. Z- B: K; e4 c$ B4 \& T if(m_pParent)
# y1 X! N9 M0 N# X {! M1 R! R% f' {& o
  m_pParent->ShowWindow(SW_SHOW);# U+ g- l3 I+ U
}
+ i9 p1 i3 f4 j6 c+ T  { CDialog::OnCancel();7 U0 B+ s) _8 i
}
" |  \- T4 P+ }- a9 @: U5 E! v
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
4 {$ m: t7 `& q) S' p{
$ ]  k. b( B" V  T2 h) a- g  G1 ^/ q BOOL bRet = FALSE;" w% ~: d- x  |2 x' O4 M9 _
if(pChild->GetSafeHwnd() == NULL)
: W- J/ I" R, y% \; T4 E4 o {" E; t, Q0 }% N: y% r
  bRet = pChild->Create(this);
& n  S& P8 p+ P }5 F( c  g) ?- t% l3 [) @/ V2 D
bRet &= ShowWindow(SW_HIDE);
/ [! ^# Y/ X7 H$ l bRet &= pChild->ShowWindow(SW_SHOW);: |+ r* I6 B; J6 e1 p: f4 g. Q& @
return bRet;
0 R  h  J+ [' k8 n- l}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
# U0 f1 A+ Q2 {/ a' [, K, A+ g. a1 U) M{3 f8 Z" m' p1 D9 l
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup% u: _' I( X& [, m3 [& H, o/ g
{
; p% H8 `9 P2 l2 L* R  //TRACE("Key down/n");) T3 t0 b, i! M9 l
  CWnd *pTopWnd = CWnd::GetActiveWindow();
: A1 S( `$ _% s  ]$ q+ f4 V( Z+ F  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))# e) O. T& _/ J$ N/ V! M: E% x
  {
8 N1 L, @* Q3 j3 Z& p* t1 d1 o   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
0 N; W. x- y$ E0 x   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)
+ }$ Z2 U1 Q- w1 Y& B   {, W- E# h5 y2 v0 x& L  l
    // 只截获tab、esc及回车键- }3 ^* z* Q- ]) ]
    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
0 x, I% b% o3 u: C( ]/ e, R    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);1 j% w% p  W$ r8 J3 D- X
   }
9 o' Q  c8 x( V, ]8 z   switch(wParam) {
- `. J( S( R4 z; q5 P0 e0 e7 o" M) c   case VK_TAB:
! j) i+ ]# i( C( T9 q    {
! X; C; W9 d- I5 [0 c4 ^9 M     CWnd *pWnd = pTopWnd->GetFocus();
5 j+ S* e) L% C# q& ?- Z  l4 A     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);, `: k& u: J; U3 T8 V0 r" J
     if(pNext)# l) y3 C, L/ `+ K5 @
     {2 c' M" M2 u# a, I# {5 _! s4 P9 U
      int nCtrlID = pNext->GetDlgCtrlID();
: u) O  b2 M4 L9 v      //TRACE("CtrlID = %d/n", nCtrlID);2 q" i9 ~6 n3 [6 {1 _3 {" g- k
      pWnd = pNext;
6 z6 x  Z9 e- E( R0 l9 P% ^# l: E+ X      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
/ ~! {( x" d. R* ~      {
) b, P0 C9 b$ O& r       // 根据UG对话框的属性,这三个按钮是没有焦点的* J' J! `$ v! E6 k" S9 U1 y3 P: {% g
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);: I! E# N$ s% {2 t$ \
       if(!pNext || pNext == pWnd): p  ]9 {8 I6 \1 [7 Y1 Q0 y
       {# [* n+ H9 a* @1 |* P
        // 对话框上只有上述三个按钮
1 V% T3 o" K' n6 Q& {( q1 `5 s" ?& @        return CallNextHookEx(NULL, code, wParam, lParam);
( I1 _; f& o! F9 p" [0 X& Z       }
. }) o, }' ^8 W! _+ W% R       nCtrlID = pNext->GetDlgCtrlID();$ b1 w% e+ M# X0 D
       //TRACE("CtrlID = %d/n", nCtrlID);
9 O# Y$ p# n# h, r8 r) E      }2 z: O# a5 j7 e% c
      pNext->SetFocus();
2 f0 {; P$ k8 @     }7 g0 h8 u: ~( i+ f% R- }
     //return TRUE;, b+ O. P7 Z% T- N$ l
    }
6 V7 [) m- j  s& H0 M    break;) f7 h( G! ?) b
   case VK_ESCAPE:5 c: J" ^* S! N8 I* |
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
3 N' D5 j. v( X4 f9 l    //return TRUE;
7 ]1 X/ O# `- j& q" p    break;9 s+ w9 [. l# c
   case VK_RETURN:- R  |  q$ ^+ i5 o3 T/ U
    // UG实际上并不处理回车键2 @: s( j. L' I: q& ?# R3 _3 d6 p, H/ A
    break;
+ n. }) I9 z9 N& ~6 e$ g   default:5 p. N/ V4 a- R; t
    break;- f7 I: \7 U, |  o& I: d
   }
" [- n0 U+ }9 n8 g  }# a: M& ^$ _  ]5 v; B. }2 E% B7 I
}
* O. H' H( t* A return CallNextHookEx(NULL, code, wParam, lParam);
- j6 j; r' b# D2 ?, @# A  `}
void CHsPMEDialog::OnDestroy() : K" a% _. Y  F" D. c
{- g  L9 T* d9 _+ @
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子! U0 b1 O9 T4 V' Y5 P$ B$ Q. L8 ]  h3 g
if(m_hkKeyboard)
. n8 U) j" h- {: I8 J {4 @+ L/ e0 n8 t8 l9 c' g0 r
  UnhookWindowsHookEx(m_hkKeyboard);
" A* v! a  U" ^  m_hkKeyboard = NULL;
& [0 H$ l0 _' v) | }
if(m_hkCBT)
' e$ h- w3 c% O& L1 Y' [; W/ Y {
: A' F- n3 m7 j5 J1 X$ r$ @) s# e) z  UnhookWindowsHookEx(m_hkCBT); ' m3 ?% W  [, h; ?- k; G
  m_hkCBT = NULL;
$ S5 c6 j5 i- H2 J$ ] }
' c" R8 f. Y- b: c, x: f}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)2 ^; v, j# A# v; M5 e/ R
{2 `( B( s* c& ^$ e% |) N6 v, w
CHsPMEDialog *pTemp = m_spHead;
/ l! q+ L- n7 [  Q BOOL bFound = FALSE;
  }" S: E9 x  N# @$ W4 L for(; pTemp != NULL; pTemp = pTemp->m_pNext)
, ?5 }5 R1 N6 z( s* i2 _ {
7 t+ k+ y, ~3 ]* X  if(pTemp->m_hWnd == hWnd)4 L" }, T8 b/ v# a& V
  {
  P+ o! w# x) ~) h# U2 z   bFound = TRUE;8 A9 e8 P( y, v: w8 O4 @+ O2 t- a
   break;3 A) ]  i, ~& C# U0 _
  }
& m' L' T4 B; Z+ o' d: e& e8 s }
" `5 p3 N8 C4 w return bFound;( a; @6 z5 _0 A0 ]' o4 B6 K" U3 m
}
// Returns the HMODULE that contains the specified memory address" y/ A" u" S" K5 \, v' i
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
5 c  u# y4 T7 y! g6 N- h) ~{0 ^* S2 J: ?% _- L
4 K5 K, t0 @+ j1 h' n
MEMORY_BASIC_INFORMATION mbi;
0 R; ~$ p& _- z0 [' ?% K: x return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) + Y7 a5 @* f/ ?( D
  ? (HMODULE) mbi.AllocationBase : NULL);  g9 z( U0 N3 F. h
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
5 v8 ]( z* O" D{
( v2 v* c/ [7 A if(nCode == HCBT_CREATEWND)1 u; V' e0 f9 B
{
! H+ \+ |- F" x5 `/ ~1 z' R! W6 Q0 G  //TRACE("A Window is being created/n");7 H% t; o+ R% B
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;
- j8 b2 j+ p& L# o$ {( w  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);3 e3 M; z8 i# C1 b9 @5 Q
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))8 m2 O+ a! I: I, v1 t. v
  {
% h6 j  F* `7 w0 W, J. Z   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
$ Z# O7 l( ?. n   // 取得窗口处理过程内存地址, p4 @& ^3 C, n! j, d
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);; s0 o  R& C8 N2 Z" }
   if(dwUserData)$ k1 T3 L3 h- T9 i+ O! q4 ^( \2 y
   {; q. \; g" d( ~. H4 f0 K6 ^
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
2 F, s% j+ R; w- S: @* O    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
) }; r1 s: @2 p( R6 p9 U    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
5 i7 v% m4 m; ^5 q6 E    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);* N; E* w* `5 W9 B/ \5 x
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);9 v$ O; i0 y9 H
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);$ N* h+ u0 B8 p$ |8 l
    if(stricmp(szUGPath, szModulePath) == 0)
( i! U+ o# `9 W9 v, S: d" e/ V! B; n    {5 V. u- P: b% b4 H
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
' e& X1 _6 @! _8 A4 `1 a$ c" c. r     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)' z  H$ j8 }6 ~- \7 F7 a$ _$ @5 G
     {3 }/ X: U  t5 z# u8 [- G4 z  v
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)" S& f( {7 Z6 K3 G6 D% y9 H1 Q6 G
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && + ^( P3 d* D8 U4 q6 H
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)- g1 y8 k1 D' q/ C: w
      {2 i1 ]1 w9 {' x% D
       // 窗口非本窗口或其子窗口
. K5 Y9 L  p: R8 k! C1 K       g_pHsPMEDlg->OnCancel();
2 t+ A  w! ~, p/ H+ _; z: j; Q4 F$ J+ S      }
; t2 g7 [3 h/ M0 w- B     }7 H0 N! w7 l2 M4 @) O0 Z- a
    }
9 A3 }5 Q3 N$ \5 f! ?   }9 `8 A( g5 i. Q) z+ N% V
  }
1 U9 |- \- D4 t1 P }
" i( S  H' X9 c, F return CallNextHookEx(NULL, nCode, wParam, lParam);3 j$ [5 E5 k; m
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 5 ?+ _! i* Q- {1 Z5 k
{
+ D+ N# A$ `1 K+ ^8 `2 f* { // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来& g* y) N$ C7 U' K! s& E1 O0 \

& y2 ~/ Y: Z, R. @2 \. ^4 t, s return CDialog::WindowProc(message, wParam, lParam);
, c# U8 B: }- V}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) ; d+ ~4 w5 o& b# r9 h. z( o
{$ R% Z/ |. L* E9 o8 y' W! [% w

' w8 W1 M3 P1 t8 G% Y0 G3 Z return CDialog::DefWindowProc(message, wParam, lParam);1 l/ K4 j( l! u' Z- e# w& }
}

3 p6 f' P  w9 b2 V. D" b$ O, O6 c$ x
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了