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

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

[复制链接]

2017-8-31 13:24:24 3364 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
+ {3 y& W' Z$ g- C/ h! v1 u* ]  C// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类! _$ Y- U/ W& S; F/ D: N4 p% C6 n
//    该类来自网络,稍作修改,版权归原作者所有" x  S5 l+ L# \
//-----------------------------------------------------------------------------
+ `% A2 U* H: T5 M( W9 nclass CHsPMEButton : public CButton
9 F/ _% b- h9 I# \+ E& J* Z+ L: m{7 K4 T4 `+ R9 {4 f5 Y" T
// Construction4 u! z  v' F1 ~' C
public:
) v8 d+ c! B- {+ a CHsPMEButton();
0 `/ A& Z( g$ P! w
% t" m/ y' y3 P5 Y, T // Attributes. W. f( R  ]: m. T# g. Y  f  A
public:/ f' I  A& o, {

5 ^; e7 A# a" o$ Q // Operations
$ h% E: u/ ]" M% d* R! z: V$ o) epublic:
  e' q! g3 Z. s" X9 b inline void SetNormalTopColor(COLORREF color)
; c. U$ r! h0 k- v( f% { {
7 g/ ^& u& N9 G6 ?0 \: I% |  m_NormalColorTop = color;9 ?3 X( j+ P# W% K: ]! _
}6 Z) l# r$ Y6 s' R: ?4 ]' r- n% p1 W
inline void SetNormalBottomColor(COLORREF color)
# b4 A% m% |2 d/ E* s" B4 j {
2 @1 h% \4 r$ M' `, t6 Z( I  m_NormalColorBottom = color;
, b, x4 u( S* I7 F }
# O1 U7 Z4 O: W& E! h9 Q* m/ c" O1 V inline void SetActiveTexTColor(COLORREF color)
+ z: L: l* ^( E8 v. M8 i6 N8 h* V {; _1 K$ \- \5 d3 l
  m_ActiveTextColor = color;( p6 a/ ~# B; _
}
+ W+ Q9 {$ G% x0 P+ G1 m2 w6 i inline void SetNormalTextColor(COLORREF color)6 ^5 K- d& z& R3 Z5 k& i! h. V
{
( K1 P% m1 R% r5 r) c; y) p  m_NormalTextColor = color;
$ S  m% x" Y! i+ x7 a; X }  [$ z, F" a- ]0 u
inline void SetSelectTextColor(COLORREF color)
# u" B5 z6 I! J/ [- M {
5 f9 P" z3 S0 S* |/ W  m_SelectTextColor = color;
+ r: \' E! Y# V9 A( G/ i }$ I8 M1 ~" U+ p5 F' H* X7 _
inline void SetFrameColor(COLORREF color)/ `5 F  K5 \: ]6 _
{- J+ @& U. R; D4 l8 ]; Z2 _" i
  m_FrameColor = color;
7 V+ I; n# `4 V }
& F- }0 h9 O$ j% ]1 c4 f" [, o$ h inline void SetActiveColor(COLORREF color)
+ z8 r% h% {3 H# @9 Q {
1 e3 V% ?6 n+ o9 g, m8 M4 ~! i* [  m_ActiveColor = color;
, A2 Z+ l' k& N% D& X }' T  i( @  \# F
// Overrides7 W3 P# R/ o  {8 |4 `/ f
// ClassWizard generated virtual function overrides
! z* u( J4 B3 k //{{AFX_VIRTUAL(CHsPMEButton)# S# I1 A" e5 V; i. ~* g
protected:
6 i% N5 M  R0 G+ v8 Q; c( z; T virtual void PreSubclassWindow();$ T9 X4 v1 L7 b$ A2 ]
//}}AFX_VIRTUAL
+ G4 m: I# Y9 F" ?
! K% H$ H/ s( U // Implementation$ _$ n" T. i6 {4 @6 P
public:
# b! k4 f" E! A0 ^3 a virtual ~CHsPMEButton();
2 p' `; J: M' a5 R
2 I% z: n7 C' n$ J // Generated message map functions
3 R  G, S* C6 o/ k+ Gprotected:
+ e  @, g0 O- Z2 f2 i9 P //{{AFX_MSG(CHsPMEButton)1 Y) Q6 x6 h7 x3 V4 v
afx_msg void OnMouseMove(UINT nFlags, CPoint point);* ~+ w, k0 t% F0 A1 \
//}}AFX_MSG4 k; U6 _' w- x+ b

" d0 e- M0 ~: `. j, S) v( w void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);: s' h9 {. r5 }+ C  k1 G+ Q# u
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
9 J2 d& p5 w! o% n" g void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );) Y8 ]7 ~" w+ ^) E4 [; \
LONG OnMouseLeave(WPARAM, LPARAM);
# x# j2 J5 p: I# } BOOL m_bIsMouseMove;
9 \) ^9 S; E5 [: n/ z. ^& G
3 _% G$ Q9 s# a) s* q COLORREF m_FrameColor;& \% c$ K- ]. ~: L
COLORREF m_ActiveColor;
0 s8 N) f/ J: ]8 Z/ |
- a: u3 [) W& {8 H; X COLORREF m_ActiveTextColor;) v5 X5 c1 v4 z# |, e) _9 J/ G8 q
COLORREF m_NormalTextColor;; @& ~! Z: Z: E% L& Q9 ~
COLORREF m_SelectTextColor;
7 C: A2 f# d. `3 l5 F
( r. c0 C6 A( X* O& s. N8 G0 V COLORREF m_FrameHeight;
" K$ P; N- M/ t7 w COLORREF m_FrameShadow;/ G! R* g" u0 w" r3 `  C' K
2 U7 b9 u  d1 ^2 Y* W
COLORREF m_NormalColorTop;, L3 R. x) z9 j
COLORREF m_NormalColorBottom;
6 v  ]% L) F! w8 N. I3 u1 n
5 g  t5 R, {, t* t* d7 J# G5 O! L DECLARE_MESSAGE_MAP()
' }. `/ q# u* |1 K" w$ E};
/////////////////////////////////////////////////////////////////////////////. [8 i; \" o7 G6 w
// CHsPMEButton
CHsPMEButton::CHsPMEButton()) X, d. }  Q* V+ U2 C! C
{
  t/ B" T% j# ]  w# w m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
$ i! R+ ?4 Z, @; @ m_SelectTextColor = RGB(0, 0, 0);
  q. H2 ?( u% c2 `4 j2 n3 J m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
. g+ e" e8 k5 L2 ~9 T m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色% F: |% S6 q2 o$ F. \
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
4 a) b/ }$ g1 h m_FrameHeight  = RGB(230, 230, 230);
8 e7 C; F% i/ F2 [ m_FrameShadow  = RGB(128, 128, 128);
, |5 D! S+ V; z) W+ _+ F% V}
CHsPMEButton::~CHsPMEButton()
$ _+ J+ \3 F% E# ~" b' x- n{
: z. b$ c, N; c. {  o$ T! T' [}

1 l0 `3 L5 A! w5 r6 e' ?: O4 oBEGIN_MESSAGE_MAP(CHsPMEButton, CButton)2 J) z2 ?- L$ ^/ v/ X
//{{AFX_MSG_MAP(CHsPMEButton)) F( g4 P% K" g/ E8 V# e
ON_WM_MOUSEMOVE()5 u* E# s  o/ }5 S" w8 m/ P; {
//}}AFX_MSG_MAP
: _$ L2 i8 V. q! P3 i( j! L ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
" {( A. g3 w4 y/ a8 u/ e% dEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////8 M; Z7 v7 ~! I2 T* q, n5 Y
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
9 f, A) a) ]; X. ~{8 Q; p% O" W% Q2 Z
//*
/ B6 s8 p6 U3 ]1 L5 } CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
( D& c. ^+ g; L; W3 z. E% m$ t& h$ k DWORD nState  = lpDrawItemStruct->itemState;
% Y  h7 [8 [+ n" e" L% p. N+ o DWORD nAction = lpDrawItemStruct->itemAction;
, m6 u" Q7 P) s$ I; K- t, D+ b CRect rc   = lpDrawItemStruct->rcItem;" T, |9 S( u1 ~+ o# r' ^
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);
/ p. C. u/ t; i% c2 |5 \7 I0 a! t+ V CString strText;
$ N  v( o# [  r2 r; b! _ GetWindowText(strText);
if( nState & ODS_SELECTED )4 t" ^0 R1 L1 y: m5 k1 P) h
{6 K' [5 ^8 f( v: j3 t2 F6 {
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
# j9 b$ d6 A' j3 F( ?  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); - ]% K9 c& w% J
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);$ A% z# K5 |  e+ e7 _
}- l8 [, Q% g( x
else //Normal0 W9 z9 i6 Z. N8 D1 M; r! Q
{
, Y- T4 ~; Y& Q  M" {1 z  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
& Y/ a+ P  h& [8 V6 d1 @  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
3 O. ?0 [& O( a4 }3 M/ u. P' l }
if( m_bIsMouseMove )8 v2 |) H- w: m% t
{3 Y4 x6 l/ W# v
  CRect rc2(rc);
7 q8 i5 ?2 ]5 h  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),! `2 d; b. x6 N# \/ I+ k
   m_ActiveColor, rc, rc, pDC);
* @8 p, K5 ?/ e. s6 j  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;6 o. c$ m# p  r( b) z
  NullBrush.CreateStockObject(NULL_BRUSH);
) m* Q. u/ a5 i" i) @  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);- n1 c2 p; M* ?* ]+ K5 N
  , t1 R. L, G1 G( t  a
  CPen Pen;5 r( f& R) v3 W
  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
' z9 k+ E/ }% X# x) `  CPen* pOldPen = pDC->SelectObject(&Pen);" v! O, |$ \$ X- i3 c: [9 t  c
  rc.InflateRect(1,1,1,1);3 E( r! d' k9 C/ _
  pDC->RoundRect(rc, CPoint(3, 3));
& i- \. B9 _+ a6 R5 X# r9 e9 {6 \  //rc.DeflateRect(1, 1, 1, 1);
* y/ W% R4 T9 l& w, K  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);8 X+ N* h5 Z6 q! U
  : S% F3 `4 A  k+ ^- J1 c/ B2 N
  pDC->SelectObject(pOldPen);% J" S! c. h! K$ _. q
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
( `" s" ^8 l3 O" A6 S }. ^2 Y; z. b: y' E
) e. ~& s5 b8 ?- E3 f2 X
pDC->DrawText(strText, strText.GetLength(),
: n( i- e% ~* u  z/ {  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
" M( C6 F$ \9 L' T/ ^6 w //*///  a4 i9 Y" y& p4 J; ~- W) v
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) . Y7 \( L( h0 }; n
{! w4 B; @  O8 M2 T2 w" f
// TODO: Add your message handler code here and/or call default
# v/ l+ Q+ z; U9 r. a8 V, k if( m_bIsMouseMove == 0 )
$ ]+ G# N9 g) Q& w3 V5 \ {$ {: V, [6 R% a) P
  m_bIsMouseMove = 1;
8 R! X0 M6 h4 h" `% Z6 M3 v  Invalidate();
& G' p) S+ _9 c! b  
6 i/ h; _) V" `* \, ^8 A3 y, O  TRACKMOUSEEVENT trackmouseevent;
* ^7 D* _* h' B, M2 x$ f  trackmouseevent.cbSize = sizeof(trackmouseevent);* \8 l" Q/ ?$ x, H# M
  trackmouseevent.dwFlags = TME_LEAVE;
% v# _9 P6 ?$ \8 h  trackmouseevent.hwndTrack = GetSafeHwnd();
' k# r) F% ?  @2 d3 ^# T! J3 O  trackmouseevent.dwHoverTime = HOVER_DEFAULT;6 V2 I! a$ l- g* A+ l
  _TrackMouseEvent(&trackmouseevent);
6 u$ a& q4 G) o) R' I }0 W' z' G1 P2 ?: g/ p" l3 V5 n0 K  z
+ r, {# k3 ^5 C2 x1 S1 {
CButton::OnMouseMove(nFlags, point);4 R( U  a$ U+ V4 k: ]$ S
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)6 N; b* }/ d9 i* @6 a) D* F9 ~
{
9 ?5 m6 {7 a7 d) V+ N1 V7 _ m_bIsMouseMove = 0;+ ~3 L. Q1 O1 d0 J8 _5 G/ C8 \
Invalidate();
return 0;3 D, a* I# P  ?9 @
}
void CHsPMEButton::PreSubclassWindow() # J# }% }& ?7 u$ i' Z, h
{
) D' j7 h* H# |$ O3 D# S // TODO: Add your specialized code here and/or call the base class
8 j6 S. ?$ q+ ?8 s; a9 S UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style7 Z4 E5 [& Q, X
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();: |1 v) @5 Q) r! j" M" A) [& y) }( P
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC): U% `$ [7 }" f6 Z% [% R# e
{( D3 L3 S: t) l4 ?
CPen Pen;
0 ^% U2 u  S1 l5 B2 u CPen* pOldPen = pDC->SelectObject(&Pen);
% C0 W: p# {7 Y0 Z" S0 i$ X5 l 7 B- ^* b7 L% z, S# P4 j. Q5 V
int R, G, B;
0 \* d; o# _* B$ d  N6 w5 ?# z R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();& z# e4 R: {6 ~5 l: e/ `% C) X
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
' j, Z7 `  C6 N  p% E) e B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();' }1 h( O- Z  D4 m6 G/ e

/ D4 m7 H$ @8 g6 N //R = R>0 ? R : -R;' V' z) }* N  [
//G = G>0 ? G : -G;
  c2 c/ M& d4 J, S, ^ //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
, q: \' E  E- W3 C5 o# k COLORREF ColMax = Top > Bottom ? Top : Bottom;
5 [. c0 e/ {/ i% }/ } COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)7 ^6 {/ `5 T0 O1 u& `' u! r& K/ v
{6 p: A8 ?) |3 z0 T+ w
  ColR -= R;
1 W* u8 }8 E$ s( [  k) m  ColG -= G;- x7 H0 w6 w# j5 b' {, j
  ColB -= B;
  /*
5 l) k* C) s$ H6 e  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||% G& }. Z  i2 c3 ~7 d8 n! e( }
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
# p( f  y: r2 Q- u! `  J   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
& t2 ~4 z+ Y4 P% ]' z8 J  {
3 }: [* j* i" V/ T! @& x$ b   R = G = B = 0;& O& Z# C( ~1 t. `9 V
  }///*/

: o6 m; {+ Q3 H( f, y. E+ L  Pen.DeleteObject();
1 e9 L9 y( o& P; q  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));. b+ S0 O5 ]% M( D2 m
    " h$ d9 s/ m4 W/ _
  pDC->SelectObject(&Pen);
0 _( O$ r8 ]+ E: q$ ~  0 ?! z3 }2 ?6 J& L/ K2 {
  pDC->MoveTo(rc.left, rc.top+i);( k' n+ D$ h. r9 T
  pDC->LineTo(rc.right, rc.top+i);
& u5 d5 a* d6 w2 N. f/ n  ^% ^# K }
pDC->SelectObject(pOldPen);  m6 I$ a# e4 S. B6 k  _
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)5 m1 w: @. o# S% `' z1 N1 p
{/ x/ _, I0 e1 E; _7 m4 Y6 s/ Z% _
CBrush NullBrush;+ y# }  |' Y9 S6 A5 P
NullBrush.CreateStockObject(NULL_BRUSH);2 T0 t% s% Y( s. |1 @7 g* K
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
. z" Y. [+ V, k Pen.CreatePen(PS_SOLID, 1, FrameColor);+ D. Y8 p7 a( a5 \" K
CPen* pOldPen = pDC->SelectObject(&Pen);
8 G+ z5 u+ F6 X( h! N) `  P * q4 c5 {" _/ L4 y
pDC->RoundRect(rc, CPoint(3, 3));
4 b  F/ @9 p& }' v rc.DeflateRect(1, 1, 1, 1);
( g. E9 T+ [5 J7 b4 F- [# W pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);9 t; P# q8 J* B# U6 _# b: C! h8 k; M
pDC->SelectObject(pOldBrush);$ W8 r! S: K3 L6 a
}
1 y# X) t7 ^) Q
/////////////////////////////////////////////////////////////////////////////
; ?3 K1 @  Z) \, N( `4 Y5 r9 D// CHsPMEDialog dialog
) N9 ~4 l% i5 H8 f6 _4 L( j//-----------------------------------------------------------------------------
5 \, w2 e( r+ P// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:8 h  A% J) I1 P- g5 j
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
: |  a) |" O* E. x5 s  [4 d//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
1 S2 F' ?: t: y$ h/ m//   指针将其显示出来,然后隐藏或销毁自身- w5 ?  x4 j6 M+ |/ \
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。3 C+ m5 K* B& G, Y
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类. a* u7 }+ k8 M3 J4 {% m+ B  E/ C
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,( ~7 V6 A+ K9 O, G0 M! R
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。" U$ v  d  \% u; u
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。  B% C8 E& j1 t- z
//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
) f8 p0 C6 y1 Q- z//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。" s: t5 l1 Q, F: Y6 N; s
//-----------------------------------------------------------------------------. U4 ]  g. I1 k4 M
// 注意:
, U. T6 Z: ~1 D: [* @7 T% c) A// 1、在构造对话框时必须给出其父窗口指针
2 ^& r! R% ]/ F1 X! {5 E, u' v// 2、在初始化基类时必须指定对话框资源模板ID& p/ s- L& J. T* w! @' W0 K
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
7 [1 L* A# x$ @) g, d. z// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
) E7 i1 `# R" n: d; U: d//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
3 E) Q' c& m$ ^# N% t4 ^{% y6 B$ N: i- s' g% G3 g
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能6 t4 o5 z" s" v
// Construction8 E! I+ D: @$ E! \
public:, ~/ R  r5 j$ p1 P0 h2 U
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
( M0 m$ e2 Q% v& U3 r2 ^/ M ~CHsPMEDialog();8 }5 ~6 Q3 e# N+ F
BOOL Create(CWnd *pParent = NULL);6 }- m& ?2 j7 q! ~3 J! I

/ r$ F( D( n" L* Q1 X// Dialog Data
1 Z) h  m. J5 d* h+ V4 _% A //{{AFX_DATA(CHsPMEDialog)
4 ^7 `/ L) H) C; T) J. c: J //enum { IDD = _UNKNOWN_RESOURCE_ID_ };4 b' j3 G9 `4 _  ~/ M1 {5 |1 y
  // NOTE: the ClassWizard will add data members here
5 J# ^' @0 B: }1 a' x' B //}}AFX_DATA

  y8 l( z2 O) u' o5 ]// Overrides/ ?- i  z6 i  ?6 J
// ClassWizard generated virtual function overrides
* |) _1 |- X& w( r, z: G //{{AFX_VIRTUAL(CHsPMEDialog)
( k) f& j+ X+ a3 J protected:' M) w( j1 g# |; P* z/ Z- ~
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support% A# o! F5 w' m: \7 s. i" A
virtual void OnOK();7 `7 K" Z* a; x1 [+ b% c) C9 B
virtual void OnCancel();
2 |1 {; f/ J' `8 { virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);" S6 t3 @# G& q0 v9 M8 c& a
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
" a& X7 x# D! l$ K! ?5 S1 ^ //}}AFX_VIRTUAL
// Implementation5 J% j) O" T4 f) H
protected:
// Generated message map functions
* q' \. n% B0 h0 p% T //{{AFX_MSG(CHsPMEDialog)% h* @, L2 v" g& ]; m; e4 z
afx_msg void OnBack();5 O9 k& s& T* i! F* v( ]
virtual BOOL OnInitDialog();. M8 C; v9 n* U* U, e* h4 H( v
afx_msg void OnDestroy();
" F* C6 ^7 O7 ]6 s9 L. a //}}AFX_MSG
9 I. E5 O- i, r+ k) H: j DECLARE_MESSAGE_MAP()
protected:4 f9 l& C( b  Z+ T1 N. x; j9 ?
// attributes
) C7 I. g0 L0 ]! L8 @ CWnd   *m_pParent;     // 父窗口指针5 U0 ]7 Y5 Q& a- J9 f# d  F
HICON   m_hIcon;     // 图标
3 M, R) Y2 A0 w) d UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;, F; v) T1 U& h4 @
CHsPMEButton m_btCancel;
3 @  |0 B* J1 N4 e CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
' @( ]& F, a0 e HHOOK   m_hkCBT;     // CBT钩子句柄
) ~( d. C8 I$ ~0 ?( v ; B; g* Y% I5 V
//-------------------------------------------------------------------------& n) s# h  D; s: H2 c
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog7 u" ~' b1 u. ]& O  _! K( D* O
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为) z& b3 `8 g4 T6 U7 N  [& Q
// 链表的头及下一个结点的指针
4 c2 A& w( _; Y static CHsPMEDialog* m_spHead;. q6 U+ a, _3 i0 \4 d" O  N
CHsPMEDialog *m_pNext;
// operations
/ Y" Z& V* R0 a5 r0 K- j0 T // 键盘钩子消息的处理函数
. }0 J% T( X5 i' ]3 s2 ^" @. } static LRESULT CALLBACK KeyboardProc(
0 Y. \! `3 ~8 I) B  int code,       // hook code* Q, Y- i7 U$ K: n. A
  WPARAM wParam,  // virtual-key code4 T) N4 T: W2 q% k. i3 |: D) F) g
  LPARAM lParam   // keystroke-message information
  K: M% v7 F0 a7 n  );1 ?+ c7 W% K" S6 {
// CBT钩子消息处理函数
" V* {, H7 v$ v0 \* J7 \8 G8 c& M static LRESULT CALLBACK CBTProc(# ?/ h  d# v- V% L  f; g9 s$ r8 s) m
  int nCode,      // hook code8 W# M) R* ~; `( [4 o/ D$ r. W
  WPARAM wParam,  // depends on hook code
' f% T* n9 E3 s3 }) ]  LPARAM lParam   // depends on hook code
! X' Q( a0 k3 d+ o+ {& j; U: |  );) L% f4 ]6 a- _) W# B
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
* O" y4 @9 d! `6 J static BOOL  IsWndKindOfThis(HWND hWnd);& y7 x2 q7 h+ L3 F* j& o
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
; N( N" _0 A2 c1 v; W6 [ static HMODULE ModuleFromAddress(PVOID pv);
. Y2 O: q% N* h1 }( |. Ppublic:
, {: i4 ]8 k- L# {! W // attributes
// operations
9 w) \. ?1 x& X // 用于模仿UG的创建一个子对话框,同时隐藏父对话框
" U# L: _$ F$ @# p. w. y BOOL CreateChildDialog(CHsPMEDialog *pChild);
. S2 ^' r( K1 J) V! k) Q, s};

: n7 s- x9 x4 J4 f/ p+ B0 mCHsPMEDialog* g_pHsPMEDlg = NULL;
* O7 i" u1 t9 gCHsPMEDialog* CHsPMEDialog::m_spHead = NULL;8 ]- [: X, G& H3 f
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)* E5 K& v9 L/ M& u! l7 x
: CDialog(nIDTemplate, pParent)( l3 O! Y4 b4 }! W5 s( T
{/ C' q2 e8 ~) q
//{{AFX_DATA_INIT(CHsPMEDialog)" `; T6 m& W- F3 c7 N* P  L0 x
  // NOTE: the ClassWizard will add member initialization here' M+ A0 s$ R+ X9 B9 `0 H$ S0 l. b
//}}AFX_DATA_INIT) E, n/ p8 P7 l& p, {; ~/ h; T
m_pParent = pParent;8 L/ _4 O3 {4 {7 G8 q3 H
m_nTemplateID = nIDTemplate;: I( t  q8 o5 d  v7 X7 I
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
9 {: k; a7 C" h1 B3 J2 \' M m_pNext = m_spHead;% g7 y1 V3 k) [% X9 _
m_spHead = this;
& e( w7 M8 `: A) ^* k  m m_hkCBT = NULL;" d+ s4 g  `% Z) j2 K; `# \3 v1 i& T
}
CHsPMEDialog::~CHsPMEDialog()
/ j- m0 A" E. x6 K) n3 D{
2 D9 |) ]+ a" Y* B // 从链表中删除本结点
7 @, M: y) u- H& i2 a9 q CHsPMEDialog *pTemp = m_spHead;
; ^) X1 `0 N" Y& P1 ~" A# U if(pTemp == this)
* T3 q; r( L3 C" g- r {
4 B8 A  o! \) K: ]  m_spHead = pTemp->m_pNext;8 c5 f4 }0 _: q; A6 ]' b
}
- O, j4 Z+ Y! R else
3 j8 J1 y0 c! @2 X {5 i5 M4 ^7 Y1 ]1 ]
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
  B  s: {. S/ Q  {
6 D4 c+ ~2 V. M. ]7 k   if(pTemp->m_pNext == this)
2 }. G& k' J1 s6 j( s   {
; O$ W. E- k' ~$ h" f5 w    pTemp->m_pNext = pTemp->m_pNext->m_pNext;$ W! n% s0 L4 @0 g- [
    break;
8 A( ]2 F! ]! `: z) m0 ~1 n   }/ t3 V& T$ \- @8 }5 n1 i" V& W
  }
3 n+ z7 A6 ]2 a9 e5 s( T, v% P  [* [ }* \, `# M! {  m9 P+ j9 n/ O( j# I- m
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX): w4 u1 Q0 z: D
{
5 u3 Z0 j1 j8 y; K: M  r CDialog::DoDataExchange(pDX);
: z$ k: l9 ?% N' s% m3 D //{{AFX_DATA_MAP(CHsPMEDialog)6 l" q" E7 j3 Z6 _
DDX_Control(pDX, IDOK, m_btOK);
! b1 |. O6 v  W! S6 r DDX_Control(pDX, IDCANCEL, m_btCancel);
: i+ Q" J6 I, @. k% `/ R6 [ DDX_Control(pDX, IDC_BACK, m_btBack);
# i7 n' F3 J% C  Q/ Z //}}AFX_DATA_MAP
) h1 C( V5 U" Q: S( G, `}
+ e. o' q& k# S+ E+ K
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
# B% X* j3 {5 e" H8 s5 C6 @1 c //{{AFX_MSG_MAP(CHsPMEDialog)
2 u5 V$ T- A+ {& G ON_BN_CLICKED(IDC_BACK, OnBack): a; F  f: i9 S9 A- b: u
ON_WM_DESTROY()
+ F, P- f) _6 O0 c8 D //}}AFX_MSG_MAP
' y  S9 h6 G+ C1 a* t2 n2 l8 SEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
2 K# ~" z  O5 A% N- a8 M. B- R// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
' K# u+ K& A* K0 l% b, {; X2 H{
( P* T4 U" @7 |( J& {: ~! \1 V m_pParent = pParent;# ]! |( Z. q" {( A, V( D
return CDialog::Create(m_nTemplateID, pParent);
* y8 B' V6 r8 T9 t$ o/ `7 V, l}
( }" O3 G2 u0 ?8 T
BOOL CHsPMEDialog::OnInitDialog() 0 j2 `' ?7 V2 q8 c
{# c* V- x, s+ l4 q0 k8 C
CDialog::OnInitDialog();
// 设置标题栏图标: l; Y8 \! l( W. {; I: T# T
SetIcon(m_hIcon, TRUE);" R: y$ M1 q. d' O& Y5 Z
SetIcon(m_hIcon, FALSE);' ~- p( {. }- x: `5 t3 q4 e; }

/ A, `' B. H( Z# `" y6 S // UG的对话框的几个标准按钮没有TAPSTOP7 M: e' V8 c5 Q3 F
CWnd *pWnd = NULL;
4 [- g  c3 r! z8 K. h pWnd = GetDlgItem(IDOK);
) i2 d: t7 \3 V7 k) y2 k2 G if(pWnd)
/ j; ?% B9 @8 S) _* g3 q {2 u3 B( {- S; p; [
  pWnd->ModifyStyle(WS_TABSTOP, 0);& V6 i/ z" e5 D9 ^& {5 i8 c) o
}
# l, x' k% w6 p( Z9 j$ K- I pWnd = GetDlgItem(IDC_BACK);
" N8 g' N8 Z  S' f# ` if(pWnd)
2 r! R. h( [8 B# J8 I {
, j7 k% ^; @% B# h, j0 T: N+ c3 V  pWnd->ModifyStyle(WS_TABSTOP, 0);
, u7 N& _5 r7 X$ | }
% e  b" b8 ], Y8 A7 H pWnd = GetDlgItem(IDCANCEL);
6 X# M9 s2 E% D* Z! } if(pWnd)
7 S( s0 z" k! @4 T* R {
0 F( t. ~- R7 m& @  pWnd->ModifyStyle(WS_TABSTOP, 0);" t9 i5 R* F( Z" ~: A" q1 D8 l
}9 y1 i3 U9 K: s; o

8 U" d8 t5 \/ H1 a3 U9 T g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
2 Q( s/ ?: ]8 L+ }* t if(m_hkKeyboard == NULL)+ S: x& U- e1 w, y: f
{
# h, ^( }+ q/ D6 n  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());4 V! R# Y6 g) E3 v$ w9 \, C8 B! p
}
4 z: T: |3 a/ T+ S6 M3 m  A if(m_hkKeyboard == NULL)& T/ b- M- B' z( }  L  V
{# b8 d4 J. l; W+ L& F* ^
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());0 O, a1 p5 m2 Q6 I
}
if(m_hkCBT == NULL)9 `1 e* p$ r+ @1 k& D
{) c+ ~# H$ n4 x. {- L4 q8 l
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
( |5 M9 z& L& _5 w+ F( Y }9 W& e+ n4 w6 |+ w
if(m_hkCBT == NULL)
0 t% d  @' |2 T; c  p {! r; O, k' o. H  J! i$ N. P
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());# P4 K1 O, G1 m4 O3 J. V9 x
}# \( r. w: `6 b: V- V* ]$ P7 I

+ V7 S9 g0 h* F, u( L3 g9 K return TRUE;  // return TRUE unless you set the focus to a control
% f1 N: v: J: W               // EXCEPTION: OCX Property Pages should return FALSE
6 W, g) V4 p7 M) m- P7 _  X) t1 z}
void CHsPMEDialog::OnOK()
4 d. A+ H$ Z$ e$ H3 b9 ?' E{* S8 m; W+ a7 C, e) Q
CDialog::OnOK();/ J# n7 e: ?, B/ P& @* `  p
if(m_pParent)& t/ t9 s: }* B' i# t5 K5 E  r
{
0 V5 Z7 L( O! _* Z( \. u& b  //m_pParent->DestroyWindow();: g: E+ t- [& x
  //((CDialog*)m_pParent)->EndDialog(IDOK);9 X1 }1 J3 Y" E2 `% G
  ((CHsPMEDialog*)m_pParent)->OnOK();9 a5 y4 a$ Y+ r; Y, Q
}
; r( [  J7 f3 O% f  I}
void CHsPMEDialog::OnCancel()
3 m, z; ?# `+ A9 b+ ]% {{
) C$ Q! ]( q7 P$ y1 R, p! L; \ CDialog::OnCancel();; N# _% [. I: _3 v$ y1 w% [9 W
if(m_pParent)
* b0 [, O9 y  C9 N& X$ [' `& o {( }$ E: e) Y4 o
  //m_pParent->DestroyWindow();9 ~0 K1 {+ ^" h& I. i& ^
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
8 |3 b- ]) O% t0 Z. @8 D  ((CHsPMEDialog*)m_pParent)->OnCancel();
: c1 _- V& `2 R) i }
- |/ `5 A# M9 ~. k7 Z( j}
void CHsPMEDialog::OnBack()
7 D$ J0 W8 P1 d0 R{  d; h7 i" ^. o9 }: f& [
if(m_pParent)
- [1 E# X" o' |- F% R {
; d0 |) D* a( \- _9 \# g. {  m_pParent->ShowWindow(SW_SHOW);
9 F$ t+ n- M0 E# p }
4 L% w$ r, \: [  W! e# ?/ {( d) e CDialog::OnCancel();* G$ g- y% v$ K& v+ a* z
}

2 {% D/ H* Z# d, m* DBOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)- i6 I; U4 P2 L- a
{
1 s9 d1 r; J# U' f3 P" O BOOL bRet = FALSE;
1 b3 Y! d% ^$ ~2 P5 c. j if(pChild->GetSafeHwnd() == NULL)/ n# Y. \' M6 o8 z4 s  H& d
{
5 K: W$ t9 X3 M* |! a. k+ K) a  U  bRet = pChild->Create(this);
2 W+ v" p# q& V3 y }1 B5 }& ]# \( Z
bRet &= ShowWindow(SW_HIDE);, f( v- c% q: j
bRet &= pChild->ShowWindow(SW_SHOW);
1 D: L- O; O2 r$ s return bRet;
; e( }' v2 x: S}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
4 Y+ ~/ n$ e6 n0 o& I{
7 z) v- @  @  |8 T if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
! `: k" E& S0 G, c- G! l! f {
) d+ ]& D& Q) d4 T, ~8 _  //TRACE("Key down/n");/ m9 l* z! G6 S4 ^
  CWnd *pTopWnd = CWnd::GetActiveWindow();
% B$ ]+ ~: C3 Q2 z5 A  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
; S3 Y5 F* x, c$ P! T9 I  {$ S( S$ g' e+ V' }
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息$ `! W# B. \6 @  [
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN), J# y# u( q6 V1 B( T. g
   {
- \: G' S& |& T! N- z    // 只截获tab、esc及回车键
9 S3 N- @$ p  e' f, q    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
  B' l. p0 D+ ]9 M% `+ o  r    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);3 o) D3 _! {7 d8 ?9 t* M
   }
( O+ V, F2 N6 Z5 t! `. c   switch(wParam) {9 Z1 [* N/ s$ R5 V- }
   case VK_TAB:3 V8 w5 T: |3 B/ ~
    {1 Q( k2 P4 |/ R& a7 A
     CWnd *pWnd = pTopWnd->GetFocus();
8 B! `+ z& B1 G" m" |     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
6 {% i, z* B: `     if(pNext)
, W% \) K( k/ X! ^7 t     {# c0 w5 L/ `- X1 X& S5 T: d5 A
      int nCtrlID = pNext->GetDlgCtrlID();
; w5 P+ W. a" _/ j) b# i& {: u- D      //TRACE("CtrlID = %d/n", nCtrlID);
5 S9 T5 q5 P' i6 e9 b. v      pWnd = pNext;
0 H& d; R. z& Z$ c      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK): z. u# G1 G* {/ R3 G% ]( O2 Z- B
      {8 G# T' [- g5 g" `) G' k5 i5 X2 R. F( K
       // 根据UG对话框的属性,这三个按钮是没有焦点的
- {. o; j7 \/ X) `+ l       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);8 F& p# U9 Z0 E1 v0 O. G
       if(!pNext || pNext == pWnd)
+ B1 _( s6 b) I: l7 s. I$ n$ Q, J0 x       {
- S+ C: x5 T: {. q! [  q+ i+ F        // 对话框上只有上述三个按钮0 l- p; s" g4 R4 Y# i9 o
        return CallNextHookEx(NULL, code, wParam, lParam);
0 ]2 _" i4 N; Y1 B* A! t       }) {2 G# ]# a4 C" x; |2 ]6 x# u% b
       nCtrlID = pNext->GetDlgCtrlID();! n) f! i3 v+ e: f
       //TRACE("CtrlID = %d/n", nCtrlID);9 S  ~; D. f: \8 b0 m
      }
7 S  ?4 O3 C0 A# X! @! O      pNext->SetFocus();! N0 Y. X. A) c: G; L, S9 }
     }* t6 g: \% }* g3 i8 ~3 P  k
     //return TRUE;
3 A2 I6 m9 R. f5 k    }
9 L& T  l6 v; G) y5 c1 ^. d    break;6 _' W3 p. Q( d
   case VK_ESCAPE:- v7 t6 c- G5 `
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
/ a9 E% x3 m; k, H3 T' U- \7 V    //return TRUE;
' }# ?: R3 ]2 v( \* z( e, S    break;1 O+ e( Q* u6 s
   case VK_RETURN:/ }. }  y; ]0 c# z. ~
    // UG实际上并不处理回车键
- L' T9 D$ @( \& X! o( k" A    break;# _8 R& A( }8 `: [1 R7 ?
   default:
! e/ w% `7 v' V& F$ p5 G% A    break;
8 P  }5 r4 d7 x( C* I# B3 n   }, J# P& N; `9 h2 g
  }
$ n, r- x, m& i( W }
4 k" |9 L$ W% {, A8 c# F" C- ?1 z return CallNextHookEx(NULL, code, wParam, lParam);
# x4 h) s* C$ R* U; R  |# Q7 e}
void CHsPMEDialog::OnDestroy() ! }3 G/ b/ p3 x
{
# L6 G) R  k7 M- q9 z1 {3 l CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子3 K2 U& ?$ ^$ _5 D3 _& Y$ ?
if(m_hkKeyboard)
3 V3 ?  F: c) D. p! @ {
1 I9 \6 c; R4 R- @4 F0 I' e  UnhookWindowsHookEx(m_hkKeyboard);
! i+ S8 t' I  y1 b5 J, b$ O  m_hkKeyboard = NULL;4 }% C6 q. J- M1 j' ?5 `
}
if(m_hkCBT)
+ Q# u; b# G* L6 d+ ] {. N8 b' i4 ~3 W- Z% S
  UnhookWindowsHookEx(m_hkCBT);
4 F& @7 Z! Z7 s$ o  m_hkCBT = NULL;: T" [# w7 Q( [* i3 K4 {
}
0 [5 W8 N. u3 F% s8 E}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
- ]1 T% N: c0 p( U1 z{) e+ x/ o3 F$ y% {6 k
CHsPMEDialog *pTemp = m_spHead;! ~! i( I, w7 w/ f
BOOL bFound = FALSE;
; P# ?; s. |8 C& b8 L for(; pTemp != NULL; pTemp = pTemp->m_pNext)
7 \+ _7 X" W! S- O' u& v4 m/ F& ` {& E: l4 q" l% [8 G  N5 A6 t% T6 m
  if(pTemp->m_hWnd == hWnd)
( R8 V3 u- P6 {7 u1 C4 t6 @  {
0 N" B+ P5 t/ p   bFound = TRUE;; D0 V2 o( v: B$ M
   break;
% u* j: Y, D  y, _5 }- S$ O( [  }
+ g4 |1 `0 Q  b/ X7 V1 ~ }* x; U. w- b" ?+ k/ J& x
return bFound;
& C$ q8 ~& g4 ~/ \- J" b, v. [- U}
// Returns the HMODULE that contains the specified memory address8 P: S  J2 v& I9 G* [7 G
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv) 7 v+ \6 s' {! i
{0 _# P+ ?) o: h" p# o# k3 z, x* G

) P. t+ d; C: K! d$ T3 v% s MEMORY_BASIC_INFORMATION mbi;
% _- I; s. j5 }  s3 S return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
6 ]3 o% a  j6 o. ]/ W" q$ u' w  ? (HMODULE) mbi.AllocationBase : NULL);! J6 W0 f. C( i- i& n/ e
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
2 Y7 B1 ~6 X5 R{
: Y0 o; T6 a5 o3 T0 H$ j if(nCode == HCBT_CREATEWND)1 w. _, ?) r  ^7 {
{! u: v1 D- ?% f& {0 k
  //TRACE("A Window is being created/n");
! ^$ t* c; l* e/ |+ |+ ?  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;$ o# z8 |; `  g; u5 O' {& f
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);  A$ R1 R& R. P# q! n
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
5 Y- h6 O% ^3 t6 A7 V9 D$ g& G  {9 r1 {/ d4 `1 J5 p* }& X7 Z) R
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应6 B5 i& F8 ]$ ]& {; V+ f
   // 取得窗口处理过程内存地址* }. w" I& y) I6 g5 ?  x' u
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
# L6 E0 W* }4 I( Z0 v# ?& s   if(dwUserData)3 u8 \' r9 E' u  a7 |/ k) R% x
   {3 n2 w9 e- n9 w' p9 L1 B
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);" l# a2 [/ L& B) Z
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};" p6 |( e" z- _. F  Y% u
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
3 g- \1 z3 |  ?( I. n' M: C7 E    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
  R: n9 ]* R4 m' [7 X( ?, W* _& D    TRACE("CreateWindow Frome Module: %s/n", szModulePath);& ^* a4 T9 f! X' w
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
0 ?& \' H  O) V" G% K    if(stricmp(szUGPath, szModulePath) == 0)% J9 B8 U! H9 a2 X/ P( m
    {3 p0 D* f5 B' y, r# Q+ D
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
3 v# J# \9 I" B% p     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
7 Y% o$ L, y* n1 V. ~9 \% D     {; R6 k! E$ L- B  f
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
* ^* r6 O& q3 s  i      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && 8 e9 S( D! f8 P6 P) b$ \. W8 e
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
; g4 w: t! b. i      {, W/ R3 _8 B. }# g
       // 窗口非本窗口或其子窗口
+ }4 a/ B" i! u       g_pHsPMEDlg->OnCancel();
. a9 A1 _4 }6 \8 l  ~      }, b/ r3 P- A! M( [
     }
' d) k- s, W( b3 V( i2 U    }* R; Z7 R$ C: J! _! P% I# g
   }
- K& E" N8 D. F5 h6 S% A4 F  }$ e: e5 u  g+ F* l
}! s' l: h/ N. j) f. j, ]: J
return CallNextHookEx(NULL, nCode, wParam, lParam);. j  g  V9 l/ |
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) ( Q' ]" v' h9 j9 W/ B; O
{
% R3 y( ~- h  f' \: Z1 y1 N // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来: h( ^+ S8 o1 }- b9 O3 Q

* H) E; I1 I5 q/ Z return CDialog::WindowProc(message, wParam, lParam);9 H. b" N( l0 n) d& V8 K
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
( ^) G3 T+ v  ~+ H2 V{
8 c, S8 ^" ~% i1 y' I3 y 9 `/ ?: Y! h) _& g$ q: e9 V7 l4 K
return CDialog::DefWindowProc(message, wParam, lParam);
7 [' }$ Q" u. u}
! H' y4 `8 S" n# f5 {6 `/ C
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了