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

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

[复制链接]

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

请使用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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------! C4 Y: D# p. a) [
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
, G% E) x/ A( Y" }; q- W0 e0 I//    该类来自网络,稍作修改,版权归原作者所有
4 ^7 X& ?0 x9 {) N: M5 [! _//-----------------------------------------------------------------------------. u& T6 b( x3 _' l$ p
class CHsPMEButton : public CButton
# f5 Q9 ^' O  B. Y# g{
6 s' B6 Q( Q" V5 }3 j1 h // Construction
& j; i' _/ v- t; L: |% Npublic:0 f6 l, }3 k) h. `5 u. w+ r
CHsPMEButton();& o( r1 i9 `, {5 L
6 N; K1 P+ r9 r' B( a5 G
// Attributes# W& D$ y) t* w7 L9 b0 |  i8 M9 X
public:
# ^9 {9 D7 e5 U$ u: \
, Z' S6 P$ l) w8 q5 o // Operations! N; J. Q* A2 L4 ^9 I6 @
public:* h6 _  e4 S4 b
inline void SetNormalTopColor(COLORREF color)
% I3 c$ ?8 ~2 I6 @6 r {% Q: q4 R$ w6 T3 v3 R/ @6 i
  m_NormalColorTop = color;1 L" F: E" F; D* w4 a7 u- G
}
! a4 X8 L% b) R% X1 h+ S inline void SetNormalBottomColor(COLORREF color)
0 I- ^6 w9 z2 g+ w' q4 D# @4 B  f2 h {
! S8 H& C5 }$ g( ?3 k8 v  m_NormalColorBottom = color;
  g! q3 |  M, s% N }
+ J& h/ R  F8 \) s/ g inline void SetActiveTexTColor(COLORREF color)
" S5 Y5 M6 A. x9 e2 t! D& }# F {/ _# c- E( D6 U% W
  m_ActiveTextColor = color;
4 D. \4 h& I) O }
( W4 T) A9 r- k* L' L. ] inline void SetNormalTextColor(COLORREF color)
' n: D" @0 w) d0 t$ I4 ?' c& u {: u, M' [' q3 g3 c
  m_NormalTextColor = color;
! I7 \' _' Q- ~/ y4 `0 n }1 \, _+ N( s! R+ k! [% |
inline void SetSelectTextColor(COLORREF color)
* }  l- K, v" i$ y' L {) A1 I# M, S% n" R. o) ?
  m_SelectTextColor = color;# a( J# f! H8 y( h% H
}
9 \5 C6 F% o8 \/ r inline void SetFrameColor(COLORREF color)
  u* F7 k, k9 V8 R {
) h& @1 ?+ V; r  m_FrameColor = color;
6 v+ m% p$ t7 s/ M" ~& I! l' ]3 `2 J }' h) e3 Y- l- Z0 @; w2 a. M# Q
inline void SetActiveColor(COLORREF color)
( x+ c- {; h8 v" I5 s( \: g' _: m {0 Y' {5 E$ P) j7 O
  m_ActiveColor = color;( Y  I& L% q" l" N
}2 W6 b* u# y5 K8 a
// Overrides
. ?  y# i. G1 d- s( B // ClassWizard generated virtual function overrides
3 @$ m% l/ N" d* C3 H //{{AFX_VIRTUAL(CHsPMEButton)
9 c# ^1 M; i# o& R0 k6 b- e1 E  Tprotected:) ^) ^$ f! S& I) M9 q
virtual void PreSubclassWindow();
/ o+ U$ b' ~& }, N6 f8 T5 o7 ? //}}AFX_VIRTUAL" H& |* Q; ~6 ^& j/ R" X9 }
: e5 Q; v. V# W% l& U, P: J
// Implementation
% W; A; h0 X# S- f; p, ?2 kpublic:1 o" p" t- n' `
virtual ~CHsPMEButton();& G2 S( W$ ^* ~) C5 o

. b4 y8 M' G8 V' J // Generated message map functions
1 @& J9 |5 }* A; |# v7 Y8 qprotected:
' D% ]1 s; z. S5 S6 i7 P //{{AFX_MSG(CHsPMEButton)( M' k, l" {; F* X# r! D' L/ n
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ V5 W9 \* i  T0 B! j //}}AFX_MSG
* p6 Y9 b0 F" \. K ) |! W# u+ B4 P
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);$ n) E+ H+ A0 p* ]* q1 P7 ^0 R: F
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);6 n/ Y1 O# ^5 ?# o# N
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );9 W5 I0 }& a) L0 ]1 e9 g# h& o  \0 @2 D6 w
LONG OnMouseLeave(WPARAM, LPARAM);
5 P4 P) {3 s- T BOOL m_bIsMouseMove;- {8 @+ J4 V0 W+ u0 I4 V

/ i: @! w$ e, H" s( V2 w( e# \ COLORREF m_FrameColor;/ c, z# M9 @0 H- D, {+ E
COLORREF m_ActiveColor;; G9 c: n( {! @& h  w- W& E

5 `8 }4 g7 r. r* S8 N: [/ h8 x COLORREF m_ActiveTextColor;2 z/ |) J7 g4 Y/ I: b) X1 \
COLORREF m_NormalTextColor;
" f7 y: C) I+ e' a; Q7 h COLORREF m_SelectTextColor;7 e" A8 F/ ]9 m5 B1 z

( C4 `" @/ F) z' \# f3 Y5 ? COLORREF m_FrameHeight;
; K: L: I. g, J" T- b COLORREF m_FrameShadow;
& t' G; F1 e6 ?" a " P; c4 O' M% B
COLORREF m_NormalColorTop;; v* Q# @( a' }5 C' q; _
COLORREF m_NormalColorBottom;
- F% C6 w, z& V8 _% j  n
) g4 P5 u  `8 N  O0 _. u# a% U DECLARE_MESSAGE_MAP()9 ]/ q7 g$ F; [  P- N" V
};
/////////////////////////////////////////////////////////////////////////////3 @# C7 i# g1 t: Q+ s( i4 M, S/ @
// CHsPMEButton
CHsPMEButton::CHsPMEButton()
: c5 H$ `8 ]. c: {* \9 \) `{3 D( A$ M/ u6 _) ~8 }) Q
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);5 ?$ X3 j+ I7 X7 `
m_SelectTextColor = RGB(0, 0, 0);
, \; n, I7 Z. P2 K% ~6 T: w0 d  R m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);% p: m9 C1 y1 f7 E
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色1 \4 B# Q" E& |/ m
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
) t4 Y; P/ m4 i& D m_FrameHeight  = RGB(230, 230, 230);, e! A2 @' h1 r/ g0 i
m_FrameShadow  = RGB(128, 128, 128);# X7 n# H1 N, [8 d+ g1 |! m
}
CHsPMEButton::~CHsPMEButton()3 ~! X, I( ]& R8 q+ U
{  H3 B  {# O- `2 z7 D
}

- s2 w# n2 _& y+ p5 kBEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
" |) a* @" r9 ~% [8 Q& k5 i //{{AFX_MSG_MAP(CHsPMEButton)
2 v) }) E+ o  L# h& ? ON_WM_MOUSEMOVE()3 X/ Y  I$ i/ e8 k9 S/ A/ O
//}}AFX_MSG_MAP% J( i1 {3 K5 s* [- L
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
6 \+ f1 D- k, v  v( IEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
: {' p7 _# l# N- G# h// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )( W1 G+ X. J: p5 M+ W, N. Z' ~
{) n0 N  `" {4 z. q
//*
3 _$ m# y' }" @' [4 |# K CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
' k+ T. m% U0 ` DWORD nState  = lpDrawItemStruct->itemState;  p( Y5 J# }) |( P' F
DWORD nAction = lpDrawItemStruct->itemAction;
7 L. G6 g$ W% Y* n3 c6 c- T CRect rc   = lpDrawItemStruct->rcItem;3 K# P! w1 Z- U3 d. P
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);4 [, j; u" t: Q9 o& P9 a7 T
CString strText;
$ k; B; }0 H6 f" Z" ? GetWindowText(strText);
if( nState & ODS_SELECTED )
1 C5 r! v3 O$ O; [ {; @: A$ W7 |+ C4 _
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
1 o) S$ m" i7 ~' |- s' L  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
" T: r% o& T# U- D  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
! {; G6 ~' |" w. H+ u }
+ q+ N7 H. o2 \" D1 P else //Normal
# s7 A0 |3 j4 b& v# g {( V# E# E' E# M) y" g8 `
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
% {2 i$ v8 Z# Z; {) _  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);& B6 g) w( C3 X: u! I
}
if( m_bIsMouseMove )
$ O; t8 R$ M3 D" r& T' v {5 N' p8 R( U" ]& a/ g+ {" J9 D
  CRect rc2(rc);- |2 L, f3 ]' G5 [& z
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),% L' r, h/ D* j, K* Q8 X8 r! F! R% z
   m_ActiveColor, rc, rc, pDC);
1 k) A, }+ D0 m! y  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
, [6 J4 Z8 B  Q" X, w  NullBrush.CreateStockObject(NULL_BRUSH);7 _) A3 V. K$ z7 z. ]7 V, X
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
" N% W% B8 P# A& _$ K  9 m4 p  b. _0 o" y
  CPen Pen;- M0 @. a$ Z2 s8 W& m
  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);2 I8 B, ^4 T& \# w! C2 t
  CPen* pOldPen = pDC->SelectObject(&Pen);; Q" J  G5 D. z5 d' N8 r7 G
  rc.InflateRect(1,1,1,1);% Z) o/ n! {7 E/ L$ T0 \, Y
  pDC->RoundRect(rc, CPoint(3, 3));
+ U6 V) d) g+ ~7 x  //rc.DeflateRect(1, 1, 1, 1);
! N( R# z; K- w1 I) b' U" D  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
* |) p& M. O8 q  \  
8 M* X/ ?5 U, l0 z! @  s/ d; K  M& j" X- D  pDC->SelectObject(pOldPen);& J% W( b  G; l+ z
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);  C5 V: J$ I0 O  _
}
) z8 j5 v; B: j+ E7 G' Q ( T3 Y* P, }, n# P
pDC->DrawText(strText, strText.GetLength(),
/ A8 }0 J* u6 b2 M+ }5 V  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
. m  W7 d9 ^$ Z& Y. h3 Y //*///
+ l- d. W1 X3 M% O}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) + a! `, o6 R: ?" {: O
{
: Y$ o" w& \9 Q; d3 I% p+ ]% o // TODO: Add your message handler code here and/or call default
( {# g$ H8 _4 F$ l if( m_bIsMouseMove == 0 )7 `# d6 {( `" j6 h7 _( |
{8 _/ V% Q9 b6 Q( U
  m_bIsMouseMove = 1;
  p, X/ _1 g: O( o8 b7 l  Invalidate();% N  x  g; C- t1 M- p9 q
  8 R2 T' [6 i4 ~9 A/ E. r- [+ ^
  TRACKMOUSEEVENT trackmouseevent;
7 }7 i0 H$ a% p  Q" u3 G& L  trackmouseevent.cbSize = sizeof(trackmouseevent);
. Y7 q) [8 V$ \: F7 G% p. [  \  trackmouseevent.dwFlags = TME_LEAVE;
* Z" w0 ?; g/ {% z  trackmouseevent.hwndTrack = GetSafeHwnd();
* k3 S  c3 p) ]# }) q3 {  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
) Q0 ^$ \! C6 Z# l: f  _TrackMouseEvent(&trackmouseevent);2 l8 t; a1 n9 r2 V6 ~4 m+ ^
}/ P0 t$ h4 I: M" o5 t, d

0 s: P  M  f8 s/ Q, @ CButton::OnMouseMove(nFlags, point);
4 H3 r1 x7 ^; @8 V3 m8 r}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
/ U# A+ }* }$ W4 u+ u{
* L! o$ T+ o- Z; h% M3 A# l m_bIsMouseMove = 0;. ?3 M* d6 ?* k- |# l2 S
Invalidate();
return 0;8 J0 d4 C; l: v
}
void CHsPMEButton::PreSubclassWindow()
- }. W# x  K! V. {9 b* o/ Y{
3 b7 E$ L$ B) v% y! u% U9 F6 i // TODO: Add your specialized code here and/or call the base class5 {% ^  @. q' x
UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
- t3 P- U9 V) q5 h# d. k SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
& l' ~! {/ j0 P- O" {' s, q}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
/ U5 v. R% z/ q" }2 \{9 Q; O' A" d) L
CPen Pen;  w- h% b4 M2 p/ @' V+ G+ o
CPen* pOldPen = pDC->SelectObject(&Pen);
) `4 v1 L9 F) e! r
/ G$ Y, l% q" o/ H+ }% `" O int R, G, B;4 n3 m( B+ c7 e: M# c
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();! W$ \" {# t  s" U2 d* B2 @/ Q, x
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
1 K. `" [8 M+ b6 ~" _ B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
. M8 Z5 \! U' n; g6 E  w ) m4 B' M0 q$ E0 l& X! O
//R = R>0 ? R : -R;
; h  o2 z' U* L6 p //G = G>0 ? G : -G;5 g9 W* q2 p0 A) b6 J
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);" b. n: Z: t# I
COLORREF ColMax = Top > Bottom ? Top : Bottom;5 ~% W+ O6 S4 Z# w5 C" ^' z9 T
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
% v# d5 K  \" ]% f0 z {% e4 R- X- D& k; k: Q
  ColR -= R;# V) v, H7 J# q; L
  ColG -= G;% D+ @% v) Z% J  E% H
  ColB -= B;
  /*1 h7 |2 P- u, h9 S% P2 G
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
1 p; Q. H9 q' Y" B1 `6 G! X/ {5 M( L   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
, p- f( y8 v4 e  k- {   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )2 u: S6 k% j0 B
  {/ [  }# K: r  |* C9 R  N4 o
   R = G = B = 0;
- O7 c1 R# A' j  }///*/

2 A$ O0 n; M9 A+ U& C  Pen.DeleteObject();) s- M8 O6 `! O. m/ m0 Z9 o
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
0 |9 ?$ E3 y% {   
  p. P# y1 w; O* q( E  pDC->SelectObject(&Pen);  ?4 f3 O7 h2 Z& b& G
  
  ^4 R# j) W) R9 G  pDC->MoveTo(rc.left, rc.top+i);- ~6 Z' {# c( e2 h
  pDC->LineTo(rc.right, rc.top+i);
$ m  d, L7 x1 O$ R2 ~6 e+ X$ j. O }
pDC->SelectObject(pOldPen);2 k' E/ E7 `! G3 I
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
3 G0 X, {( f  g4 a% T{
9 s8 d/ ^1 I  j# \# l+ P* t CBrush NullBrush;
2 A: t% u/ Y" b6 {3 o1 n NullBrush.CreateStockObject(NULL_BRUSH);
1 A# {/ i, `/ V% o4 m CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
) m5 i8 b' H6 N7 c5 _ Pen.CreatePen(PS_SOLID, 1, FrameColor);1 w* S: {6 [* m$ M
CPen* pOldPen = pDC->SelectObject(&Pen);
% z% y9 A; a3 L , {# l! m; ]1 k
pDC->RoundRect(rc, CPoint(3, 3));" L8 [- T) W9 n/ O& H2 H6 u( {
rc.DeflateRect(1, 1, 1, 1);
8 L1 H) Y8 r: w) d3 N- ] pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);* s0 W: I0 M1 W9 S& T0 ^+ X
pDC->SelectObject(pOldBrush);+ v* h+ N! ]/ l: x' ^4 y3 T
}

+ d! @' O- X4 [7 `/////////////////////////////////////////////////////////////////////////////
5 p$ _+ O+ r5 R8 P2 o// CHsPMEDialog dialog
* D. Q0 L: o5 `  }3 l//-----------------------------------------------------------------------------, r9 A% V# }$ ~1 }1 s, m
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
) K5 U/ E8 a  T3 E' N! |  e//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级* i$ O5 Q: M3 m: o5 |
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
5 C2 q+ [& t) y4 i4 g% ?1 L/ \//   指针将其显示出来,然后隐藏或销毁自身
2 O( L# V( b/ K6 H* v3 T//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。* {& r2 d( K( d$ v! _/ Q5 p& J% C
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类/ Q5 M  K* V& Z9 w$ P9 I% @
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
- r& T, o7 Y8 W% H5 T//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
2 x+ }4 A$ ?0 F: f) p& [//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
% T0 |+ @9 e9 j- w/ P  n//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
3 f/ N/ f7 J% u8 G6 z% i//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。) c" H$ T0 M$ P6 U1 r- l8 q: ?
//-----------------------------------------------------------------------------% d7 N6 O  e- m& d1 D6 `
// 注意:1 {8 L; s! ~& n7 q; G
// 1、在构造对话框时必须给出其父窗口指针, O' I+ n" M; t( [: N
// 2、在初始化基类时必须指定对话框资源模板ID1 g( \, b: J0 ]
// 3、对话框资源中必须提供ID为IDC_BACK的按钮* T% \8 A! \5 P" Z8 w* E
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
6 `6 \4 W* l- H! _7 }4 v  z, D- z//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog* H+ k" ^' A7 c6 d$ u1 m6 S2 O- ]
{( h9 K5 i+ X" t& C% o5 u
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能- o; v% Q6 O' p# `( O; v
// Construction$ _7 V% p8 U: Q! A- g
public:, s3 x& T/ X# G6 o( M& r, K& r
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
5 X( R* i2 n/ L  L ~CHsPMEDialog();: x! u5 r- ~9 d) b3 ~" x
BOOL Create(CWnd *pParent = NULL);
0 W/ @2 z$ P, P0 X' \7 a7 S
1 M9 j6 c/ }- b. t% F! I// Dialog Data
' O: c5 W) T* p! R) K( w" n. E7 J //{{AFX_DATA(CHsPMEDialog)& Y# ?& `- K% f$ l4 y
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };
, |. Q4 J: ~4 N3 t. B: z; Y  // NOTE: the ClassWizard will add data members here: d! I0 Y! G0 j' J  Q2 [
//}}AFX_DATA

5 K. Y# j. T, _// Overrides
# `3 Q; V% c  b4 {$ `9 D. M4 H // ClassWizard generated virtual function overrides5 M6 m2 f2 L$ A" F
//{{AFX_VIRTUAL(CHsPMEDialog)
) |/ q( m$ g& d; {& i  U' d% A protected:+ R; E+ l8 Z* v
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support. Z  P) Z- i' f5 a
virtual void OnOK();0 J5 u! ^/ t( K% j% M; o
virtual void OnCancel();; p# v; K6 d* n/ \0 O4 Y9 S; J
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);6 W) n) z5 E9 N$ k4 U* {
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
6 z0 |, E# q3 o9 |; x //}}AFX_VIRTUAL
// Implementation
0 X+ T4 v" o0 Pprotected:
// Generated message map functions
( Y/ l  s2 n* o; v //{{AFX_MSG(CHsPMEDialog)
( ~( q  s0 P8 L! s; U% t afx_msg void OnBack();
" s7 o6 O1 L% d1 `$ _( \- D  b virtual BOOL OnInitDialog();" v+ u  A3 ?, W4 B! M6 P5 v& s8 J- i7 a2 c
afx_msg void OnDestroy();) X: @! |- R; b, b3 H  M
//}}AFX_MSG
& ]0 S* X* D& J7 |  S DECLARE_MESSAGE_MAP()
protected:4 H  |  I- N0 X2 v) B
// attributes
2 L" i9 A& ~8 k CWnd   *m_pParent;     // 父窗口指针
  s6 P$ Y* o% k! ]* o3 E; K. p HICON   m_hIcon;     // 图标( o" |- \, \( D( |/ C6 }0 K
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
( b+ f  Q% O7 {4 d CHsPMEButton m_btCancel;2 v6 O+ z( k1 ~. Z0 S
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄0 k' O/ N& H3 E. j0 G; j
HHOOK   m_hkCBT;     // CBT钩子句柄
! c' C+ X/ f$ h. v" n6 T7 C   c# ?" a" A( x; z# Z2 T' E9 ~
//-------------------------------------------------------------------------
, I' H& V- T9 l+ c // 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
; _9 y9 e* b; U/ v // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为) _8 z. t7 W2 `$ d2 P7 F% q) u1 X% M
// 链表的头及下一个结点的指针
0 ~0 m# o; e  O* j" | static CHsPMEDialog* m_spHead;& b: a. ?, S% s. p
CHsPMEDialog *m_pNext;
// operations9 _# h/ B$ K$ c% w
// 键盘钩子消息的处理函数2 P* H. l* \" E0 m8 m* n
static LRESULT CALLBACK KeyboardProc(5 V( j' }' m: I: K3 U2 [
  int code,       // hook code& H( d+ p2 m* {2 v" w- G; N: ^$ l7 j
  WPARAM wParam,  // virtual-key code. u5 o$ `1 k( [) G: ]* D4 _8 v: [
  LPARAM lParam   // keystroke-message information
; z+ [2 i6 G: n& Z5 G  );6 f1 t8 h. F4 x# [$ u, q
// CBT钩子消息处理函数0 Q+ x8 @* F+ i$ v
static LRESULT CALLBACK CBTProc(
& o1 }9 p, o# e1 s# y3 X0 L9 I  int nCode,      // hook code& ?( c! x: F0 B0 b  {0 e8 d$ C( u
  WPARAM wParam,  // depends on hook code
* P& Q5 z9 N" N; F$ w4 e  LPARAM lParam   // depends on hook code
" ]' L; l0 K/ n$ O/ M% s8 I# Y! ?  );
- m- f: n1 _% r* k0 \1 S$ p
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
2 |4 {* N: D! V1 H2 k0 y, G static BOOL  IsWndKindOfThis(HWND hWnd);
% l# e2 e6 w2 a# Z // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)* F6 E( J5 @8 o: U
static HMODULE ModuleFromAddress(PVOID pv);
6 K/ {* ~+ h1 k4 ~public:1 ]. x3 n+ G2 F
// attributes
// operations& x6 \7 \; E" {
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框! V% [. A3 ~  M5 r! `
BOOL CreateChildDialog(CHsPMEDialog *pChild);
  I3 S; ?. Y* G# k  ?+ x# T};

# R* E' N% G6 {- S( S. QCHsPMEDialog* g_pHsPMEDlg = NULL;2 Z: Z6 }7 \) R% w* `
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
, x1 f  f5 K, H+ Y' n/ |7 D) rHHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)9 g% L/ n5 `! D& d
: CDialog(nIDTemplate, pParent)& b# A4 I  N5 U1 |
{
3 x6 R1 N, Q$ r //{{AFX_DATA_INIT(CHsPMEDialog)4 d3 K' u! o/ V
  // NOTE: the ClassWizard will add member initialization here
7 X- _( q  J/ b9 G //}}AFX_DATA_INIT
0 m" f8 w6 i: _8 Y! B3 W7 B m_pParent = pParent;% [' U7 V/ g) @- F  w( }
m_nTemplateID = nIDTemplate;# o4 U$ l. s/ y
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表' z# Z4 h- z( `9 J$ W# l5 v
m_pNext = m_spHead;
' I! R% `/ N' K( k/ R- i m_spHead = this;% L# j$ Y& e* d3 J( _. F4 a
m_hkCBT = NULL;2 @6 d- Z& u. p9 a7 E- R) e# @
}
CHsPMEDialog::~CHsPMEDialog()2 L8 J: @2 c6 }: c
{
' ?3 Z9 k8 B& u8 H4 t& x; }) ` // 从链表中删除本结点
& q( e  H/ i1 m4 P CHsPMEDialog *pTemp = m_spHead;. c# W- T8 V2 {4 X8 A
if(pTemp == this)
7 a% U3 `) i3 _# {( Z; B {2 b+ t$ t! H$ X$ n* S" a
  m_spHead = pTemp->m_pNext;) O2 `* T6 K+ ~: Y
}; p* a* u" d' M* Y3 C" p( e
else
, Z* d' q% k. {' J% D {# q, R: \- x# I2 g
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
, H$ w& S. `) P4 Y  {2 L- I! I& c& l( K2 C7 A! L$ G
   if(pTemp->m_pNext == this)( G+ a0 b0 `+ L. U6 [7 F% C
   {3 f4 ^$ k* K. a5 k
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
+ P% h' m) h, t6 o) B9 v& j6 v    break;
. M$ w/ n! \- b- l   }) m; T3 j/ l: A8 v/ \
  }
: Z: |0 o9 C& _: F/ O  C" C9 s }1 V9 J" ^  Q  z1 _+ |. ~
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)  J& b, l5 Q% C
{! |. \& m9 r2 o; ~9 [, g
CDialog::DoDataExchange(pDX);
! B0 h3 j, s) a! [7 w* x6 i4 o% l //{{AFX_DATA_MAP(CHsPMEDialog)
* u3 k- V5 ^* ]" T4 _, k DDX_Control(pDX, IDOK, m_btOK);
. M' F: G! `+ f: j- |$ J  @* x( k DDX_Control(pDX, IDCANCEL, m_btCancel);
; ^. X, X( o5 N) x0 Q9 } DDX_Control(pDX, IDC_BACK, m_btBack);
, }0 p- f: Z: d! |! V //}}AFX_DATA_MAP. e9 Q' Q! r+ d- j7 K. Y+ _4 l6 C- o
}
1 T. g" E( O% t6 h7 z% x) C# ]
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
% n# Z5 v, i  B) D' N //{{AFX_MSG_MAP(CHsPMEDialog)
0 g* F4 N$ N: W: `+ g ON_BN_CLICKED(IDC_BACK, OnBack)7 G/ W' I  `$ w6 w5 Y
ON_WM_DESTROY()! w! z8 {! v' R% `7 o
//}}AFX_MSG_MAP$ p3 E1 X! o- d4 I4 _
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////1 D, s4 Q2 j( z- x) s' g; E
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)" u+ T0 i  u* t8 U: R
{+ _* w' m" j) Q- k# S
m_pParent = pParent;' K! ?7 l1 n( Q0 X9 u3 `/ h4 l
return CDialog::Create(m_nTemplateID, pParent);6 z- S1 P9 X9 K. v; S/ m
}
. {3 q+ S$ C+ O5 U5 d
BOOL CHsPMEDialog::OnInitDialog()
0 b, k/ t  X# e; k( ]* O{
3 l3 b! M3 A, q, @5 R. K CDialog::OnInitDialog();
// 设置标题栏图标, o; A) N1 ]& @9 b% ]
SetIcon(m_hIcon, TRUE);$ B' c, I# ~# y& m3 S
SetIcon(m_hIcon, FALSE);, r, Q: V. {# O; _) }2 a

% y+ j% d; e4 Y/ R- H' ]5 A4 c# L // UG的对话框的几个标准按钮没有TAPSTOP
# @( e9 V& x6 A4 c+ G6 [$ x% _) } CWnd *pWnd = NULL;
8 z8 E3 A8 K' N/ w( p pWnd = GetDlgItem(IDOK);9 u+ [* a( g% ]3 W+ R% v: y
if(pWnd)3 U# f$ C& @0 c: s0 |0 x
{
% P& u! g9 ~( q8 X  pWnd->ModifyStyle(WS_TABSTOP, 0);
# v5 {: k/ I5 `- r  F! T4 t }0 _0 A3 B0 e2 b
pWnd = GetDlgItem(IDC_BACK);
" ?# a& g* Q5 W, G if(pWnd)! j6 s7 f, \6 M  l
{
2 y1 u: |3 X2 N8 e* s9 L  pWnd->ModifyStyle(WS_TABSTOP, 0);$ `' Y+ p2 A+ |+ d7 _: r3 \8 T
}) X8 G" t5 C* d1 B1 _# j: X+ m4 x
pWnd = GetDlgItem(IDCANCEL);
5 D% ]/ B. N7 Y$ b8 ?6 b0 J7 c- O# _ if(pWnd)
# L# E3 S8 S* s9 D {4 ~  V5 o2 t# {
  pWnd->ModifyStyle(WS_TABSTOP, 0);: n3 X- O( ]6 q( \9 D( d: Z
}
6 h7 q% v5 a7 e! t8 H 4 n1 [, i/ _, i8 K! \, o; W
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子2 {. n5 b' _& E
if(m_hkKeyboard == NULL)+ j4 B. ^- }6 c; A
{7 y$ `  p, p5 e8 S. F- c
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
2 j- a- b7 B' y9 L }& L. F$ e0 j# [
if(m_hkKeyboard == NULL)" m0 z$ @/ w/ \5 M+ N0 ~
{$ N  m/ k9 H5 x) T0 T
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());0 K. Y. S' W- o3 K
}
if(m_hkCBT == NULL)3 T5 Y( E0 H: ~
{
- w8 b6 O7 ?% ?# A9 t0 _6 v8 R  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
6 U$ J4 e  [4 t% x  V2 _3 _ }
$ q+ U# D. T) A$ }' Y) x if(m_hkCBT == NULL)1 i- J! f' ?5 M' m& X
{  N7 v' P3 p1 M$ V/ a" Z+ g# b  _* R
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());
5 k- e. V. x0 W) ^$ P$ F }1 B2 l6 f5 W: t, ]& X
4 q3 ]) C: w+ k
return TRUE;  // return TRUE unless you set the focus to a control
  x: N3 K' a* x" E4 p4 t" T8 t' \% I               // EXCEPTION: OCX Property Pages should return FALSE. d  |( b' m5 h+ h8 a, a' L: U6 ~
}
void CHsPMEDialog::OnOK()
* h1 J8 A! ]. S, ^0 M) A- D" e& g{* z, X2 _- s& }4 V
CDialog::OnOK();
) ?* P! U' _2 } if(m_pParent)5 }* D# r- c/ R9 |% o/ w
{
- m0 e( r4 I" [' C- _5 E8 s8 z  //m_pParent->DestroyWindow();
  M; |( h! `- {  //((CDialog*)m_pParent)->EndDialog(IDOK);
3 p$ L, @$ g+ c  ((CHsPMEDialog*)m_pParent)->OnOK();
) R8 U2 S/ I  d- Y( f! ]  H7 r' H8 y }
/ s6 {$ O- @0 M" o! y}
void CHsPMEDialog::OnCancel()$ G% G. B( M! c+ Y
{
! D. C; T, V' q% ^. Y) q. r CDialog::OnCancel();
, A; G4 N: Y1 X" ^8 X% J if(m_pParent)3 L' l- L- U( {: ?) l: H
{
' `4 E* m/ w9 `; X& h  //m_pParent->DestroyWindow();
5 n5 K3 ?& X) V8 J  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);6 U* j& k5 w3 ]  u: l
  ((CHsPMEDialog*)m_pParent)->OnCancel();7 r! I( E( v6 I, k2 }' @/ Z' i
}
' Y- N9 D2 X& X2 ?' v}
void CHsPMEDialog::OnBack()* \* ?( @  r, l( Y! N
{
+ E" {' G3 ^9 a4 O if(m_pParent)" T0 A7 h- |* z4 g* a$ w! J
{8 L- E7 w( B4 A1 y
  m_pParent->ShowWindow(SW_SHOW);
: x5 E% W) k  ]. j }: A" e+ |7 T9 V7 x
CDialog::OnCancel();
3 V8 w* |! `  `; {: r$ h}

2 v, {9 Y2 [6 Z: zBOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
& _6 Z0 U( Q% ]{2 L. w1 V+ j4 C# b' ?
BOOL bRet = FALSE;
- Y, v/ S0 z& o0 n if(pChild->GetSafeHwnd() == NULL)( d* z0 Z! M, }% I" T9 f
{( W8 O  G+ G0 R  c$ A# W, L
  bRet = pChild->Create(this);$ Z# ?4 u' P/ ?. @4 H' Y! d* j4 s
}
+ w5 o! R- o4 u/ t) w' A bRet &= ShowWindow(SW_HIDE);
' c, P/ o9 P8 r' o$ _ bRet &= pChild->ShowWindow(SW_SHOW);4 W) Z- \2 r* ?3 z( w
return bRet;0 F  ^% I. P6 R: O) e
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)5 x5 c/ m: g8 s; W; c
{
, {% C' }$ \, s* g if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup+ C! E" j- m4 y1 i, `
{% {5 Q1 ^' |: k8 V4 t8 {
  //TRACE("Key down/n");8 W1 z- x# w- {9 h9 M+ y
  CWnd *pTopWnd = CWnd::GetActiveWindow();$ u- l3 R0 U3 r$ e5 c
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))1 z4 t& T+ |' D2 |- ]
  {( F8 y# d- s3 ~' d/ d8 L" i
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
$ j' V9 y/ T3 p/ R! i4 K7 K3 c   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)' P. y- b- k# G
   {
* o( f0 s: J1 J    // 只截获tab、esc及回车键
3 w* `7 Y; D. G: M    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);5 z' N9 [- u) i6 Y2 S# `
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
' @/ F. K! v2 e9 ?$ q6 `   }: X  w) ~+ G% B; o. o3 |% U
   switch(wParam) {
" \) v6 j3 i) Y6 K   case VK_TAB:7 k% T3 t* a. u' ^
    {
; B& N& s' |: k3 s8 f: i     CWnd *pWnd = pTopWnd->GetFocus();
( u# m7 N" G4 E7 P# Z( u     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);$ p& n+ O0 d( n; Y- d5 B0 k9 U
     if(pNext)
9 W. [( M, r' }& Y8 P* D2 R9 Z     {2 E3 u1 c4 `  l& b
      int nCtrlID = pNext->GetDlgCtrlID();" f8 H; R9 U% }4 l. U1 K" l' l  j( o5 v
      //TRACE("CtrlID = %d/n", nCtrlID);8 S5 n2 }2 ~3 T* T3 D
      pWnd = pNext;  |! p! F2 ^) a  j. |. p
      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
/ W8 K4 U% {1 U- a1 o) ]! x      {4 ]7 }$ ~" W* S% X
       // 根据UG对话框的属性,这三个按钮是没有焦点的
( B1 m1 x3 D! t  z       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
1 W# S% y/ [% I" ^5 d0 r9 e       if(!pNext || pNext == pWnd)) j' s7 c6 j5 V$ X5 W3 N/ Q
       {6 X! i/ L- E+ `; C
        // 对话框上只有上述三个按钮. N  b# R3 F$ Z+ {/ n, s
        return CallNextHookEx(NULL, code, wParam, lParam);6 g( k  |9 z. x! ~, T
       }& E6 B( A9 y5 ^; ?. C
       nCtrlID = pNext->GetDlgCtrlID();; Z' B) Z! t- I8 n! f/ K
       //TRACE("CtrlID = %d/n", nCtrlID);! O1 u# K. g4 t: d; `+ _
      }3 e7 @' m3 h4 x0 C
      pNext->SetFocus();
* \( O7 Y# C5 J     }
6 o) W. I0 Z) _% C. Q) w     //return TRUE;
" F" O: [! I. M4 d; c: s    }2 W- W& C9 z' v2 }
    break;2 G  B# K! c/ C1 P- V
   case VK_ESCAPE:
! H, B) N, b, Z5 t    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);7 s2 Z+ K; W; f- v' C' ^4 G
    //return TRUE;9 O& j0 i+ q6 O3 v" a) P
    break;
8 y2 P' ~" o  ~# X3 C" \   case VK_RETURN:
8 a" @1 E9 X- C; o, Q; j    // UG实际上并不处理回车键' u, `2 @. A1 M+ A  e- v7 W
    break;# j  q  g" {) O  d" r
   default:' B- f% T! x: |9 p. G/ u
    break;
$ i5 ]% m; \9 `: w' o. h   }; R5 C7 K2 P9 P
  }& i; J2 G# s! h, H; b
}
# u' W7 a8 x+ {8 _4 J* c. f return CallNextHookEx(NULL, code, wParam, lParam);$ k" R+ f4 I9 {& ^; `7 i: o4 e
}
void CHsPMEDialog::OnDestroy()
6 y7 Y) U3 g4 a& x. G! X{  s% C0 e! m  _; k7 V: k1 H0 V
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
: L3 ]$ }# ~  U. M- W3 f" S if(m_hkKeyboard). w8 d7 h% m. r4 d+ E
{
3 i' e, o) b$ z" R7 _5 ]  UnhookWindowsHookEx(m_hkKeyboard);
, B6 S# S0 G( t6 h, u1 W  m_hkKeyboard = NULL;6 g( @. V, b# v5 Q( l. r
}
if(m_hkCBT)
: ~0 j0 }3 |1 z. x {
3 f! }6 X0 D% |2 K0 G  UnhookWindowsHookEx(m_hkCBT);
6 A' K* N. x4 ~. T6 V1 w  m_hkCBT = NULL;
% [% ^' N" a* m, p" H }0 C& X0 w( @% x: {/ p2 @0 N  `, G
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
1 m  N6 W# e' |/ t4 [{
5 P- U/ W% e; \6 ]( n' M5 o) E CHsPMEDialog *pTemp = m_spHead;
. w% J3 ]# l% N2 T* ~ BOOL bFound = FALSE;4 ^% S8 b; Z$ Q0 A# J& l5 }3 w! x2 _+ u
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
3 d; }- n6 e' H2 H7 k1 i2 e {
0 h' }! ^6 z2 o3 w: w  if(pTemp->m_hWnd == hWnd)% X" _2 o4 @0 ^# `# b. l- j
  {3 ]+ z0 l) A. @* b
   bFound = TRUE;/ p/ [1 c0 e  E% U
   break;: Q4 ?7 i8 x9 k  \7 i' s) d7 a& m# Y
  }
6 n8 [4 L2 D) g) [* I! ^ }
. j4 E. H* i. Z4 |- e0 y return bFound;
) \4 o2 S- o+ ^5 m}
// Returns the HMODULE that contains the specified memory address9 V6 z$ E* X( A8 J. }3 Z
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
9 x& r5 S( d" y& i; u& ]( c{
: @; b' W; ^6 z( t0 K3 w: ~5 w
: D. {$ o7 S" h+ s/ l8 R MEMORY_BASIC_INFORMATION mbi;
' w5 n) S. v+ V8 q! O7 C return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) 1 c# K  d0 {, M1 q) ~4 d
  ? (HMODULE) mbi.AllocationBase : NULL);
* g6 r/ z, P* h) J; W, ], j}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)/ p3 |  `% j( }  E& `
{
7 d- E) X( j# l4 Z: i if(nCode == HCBT_CREATEWND)
* Q7 z4 x% P5 ?2 {+ k {. B9 P1 W8 k3 \( ]( n/ _+ C
  //TRACE("A Window is being created/n");. t& q# h- Z/ R  H3 x
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;, G7 t- S! B' V2 H3 `
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);4 z! h, j7 w3 O/ M2 S
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
2 L0 i1 p( \' a& L; w8 S' l  {
. {4 h+ t" _1 j% x$ m   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
- W# {8 Y  V: e   // 取得窗口处理过程内存地址. z' o9 u4 P  u9 V4 J& o4 x
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
; O: b( K# ?$ l2 E9 O) ]7 b" W2 X   if(dwUserData)
5 ^6 |  R0 I, W" ~3 {( k9 _8 [9 J7 [   {) R# D. R3 ^  j5 H1 r% a# C" @
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);8 L/ S/ H/ _7 t  S+ ]
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
9 {* N  Z0 e% g" |  ?1 [    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
  v* P/ ~) r2 D. F' q- H; q    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);# }) v( S2 Z* h' u) C
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);  U& _+ u- {6 s5 Q; |2 H
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);* ]9 P7 i+ R7 _7 D; f* m, r
    if(stricmp(szUGPath, szModulePath) == 0)' r- i8 y9 _. R( X& J
    {
  L6 V7 P2 b1 T0 \+ v- C4 r4 y     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类); V; ?+ r  V/ O( V) v; P: F+ F2 |
     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)6 S' Y5 i  J  K( u: y7 s. P* s. F
     {
* H, s1 g" q5 O+ o% k9 t: K      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)) }+ u9 X$ c) ?( D# T9 w/ h
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
( T5 v$ k: [- d# k; ^       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)' n2 E9 f! y* C4 {. k
      {
6 k% M9 y$ }& `+ E$ {4 C" }       // 窗口非本窗口或其子窗口. D' L$ \+ W  M" c6 `0 w# h$ H
       g_pHsPMEDlg->OnCancel();; H% B5 M+ j& q) v6 H
      }$ O4 T& w2 y/ G' F6 S& ^" L" o
     }4 O& X1 q2 L! Q7 W: z' k
    }
& V# i" }/ X% w: R5 z% p   }
% R& A* Q( N3 l5 s3 m  }
# E5 u/ s, G$ P6 `, l2 ] }2 b0 Q5 {9 y" o0 C
return CallNextHookEx(NULL, nCode, wParam, lParam);
8 I: r4 [  P- I- ~0 i1 k}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) / t- g3 B5 |( u
{
; P& Y5 ~4 p) ^/ Z+ w; ^ // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
0 i, ?. g7 I/ }1 B% ], }: Z
/ ?5 F3 ~- ~9 X8 w% A return CDialog::WindowProc(message, wParam, lParam);0 ]4 `0 @) O/ z& P; Q
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) - ~) `8 Z, i1 C4 D6 {2 [
{  C2 N: o% j9 U! e

$ x+ q! E& g' @1 f0 o8 N return CDialog::DefWindowProc(message, wParam, lParam);
) w4 U9 @- ^- l( @5 \}

& X' W: Y7 W7 [( T, r
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了