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

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

[复制链接]

2017-8-31 13:24:24 3431 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
' |, @! e; I+ @# K( h; k: j3 U1 l// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类7 Y$ W8 F( T" T3 z
//    该类来自网络,稍作修改,版权归原作者所有( r% o" Q8 Q: k
//-----------------------------------------------------------------------------
' S1 ~9 U0 P& `& M" Y  r: Vclass CHsPMEButton : public CButton
! |& L0 }; S/ _! H# H{- \* E, F! q4 T, y( U: u; n
// Construction
3 R. @! N" f7 e9 ]" }) H5 epublic:
" f2 C/ U) \, H" Z" r( `, z CHsPMEButton();9 g) M* @* m: @" J" F
7 O+ Y3 w0 q* N9 u; D. W
// Attributes* X) |. P: [* p, ~* u
public:; G, H3 ^) {+ l2 A3 Q7 E

9 a3 m0 Y; t& m# p // Operations
- m% m& _  K" R: X  F# E  Fpublic:" }/ R% u/ Z8 a4 G: f
inline void SetNormalTopColor(COLORREF color)
8 W4 J5 @* @6 A2 Z$ { {
2 D  \9 Q, m+ O0 G" \' m- n% h  m_NormalColorTop = color;
+ B: V( v# h: T& a, Q; Q }2 k& y$ b6 g% a
inline void SetNormalBottomColor(COLORREF color)
" q* c  C- x# A6 X" t {3 T3 b7 W( W: Q1 J2 }# B: j
  m_NormalColorBottom = color;
& e$ a( i- B2 t- {/ j! g5 J. t8 L }# d7 M$ X0 R# ^/ G
inline void SetActiveTexTColor(COLORREF color)1 m; b4 B2 ^" l- e
{
* j7 o2 ]+ b  R/ `% E; _6 Q+ f/ W  m_ActiveTextColor = color;# l) j( q1 h' T. B9 g/ B+ u! ^2 M, H, K
}
) [! H* k% i9 t( T; |* i0 J inline void SetNormalTextColor(COLORREF color)& w4 o8 E: ^' E8 I$ x
{
* c) n" Q* l; ~3 W- o- m  m_NormalTextColor = color;# _& H8 c* t4 ~: g/ D& J: N% i1 m8 D
}
6 ^6 q% u9 Q$ E+ C inline void SetSelectTextColor(COLORREF color)
$ R5 i: z0 t) w5 ~3 r {
" h. M) [0 x- a# ]9 Y! i  m_SelectTextColor = color;8 C7 W* ~1 o2 _- i5 f0 q- n$ s6 e
}
0 e, a; ?8 Q/ h8 X; e& _# ] inline void SetFrameColor(COLORREF color)7 j4 L; I& |1 Z0 ]
{7 }5 Z) P( N* O% a' X: v* a
  m_FrameColor = color;
! ~' \* g0 x  m& N# s4 j1 E }
! k; M! t# ?3 r! | inline void SetActiveColor(COLORREF color)  F9 l0 o8 n7 x9 R
{2 _& {$ a+ X' K( o
  m_ActiveColor = color;
- z. A2 q1 `. x( ^/ P/ b }# w! [9 O- ?- ?, ?
// Overrides8 [, {% u& V9 v7 K* L. r" K
// ClassWizard generated virtual function overrides; ?% O- a) P/ y5 b" Y& m4 ^
//{{AFX_VIRTUAL(CHsPMEButton)
1 e( [- W9 s- s0 m4 Y7 B+ Wprotected:
% r2 ]& A8 H- C$ Y( w3 ? virtual void PreSubclassWindow();
: Y+ [3 [: `$ g# W5 M: G1 l2 I: J //}}AFX_VIRTUAL: b( U) V5 ]( d

7 v% n# u; l  i1 ?6 F) T3 | // Implementation
6 J1 v1 c! A5 Dpublic:! i2 o; W, h/ f
virtual ~CHsPMEButton();- J0 P) C$ ?$ h' @  B7 M
* s0 j5 z  @5 _
// Generated message map functions
5 `( T# p2 ]: X* h$ H' z& Q% p- xprotected:
. L% b  z' C" {$ r //{{AFX_MSG(CHsPMEButton)4 O/ A# v0 Z, T" }
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
2 z/ h" v2 i$ Y, v+ ?6 j1 u' N0 g //}}AFX_MSG
$ U& G; T" B! c* j, T8 i
  J! e0 s6 v3 v  e- P% m2 s void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);9 L0 q( k% h, f  n8 N+ u* w
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);/ ?  f7 V: j! b. m
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
( m$ p  \( ~# F1 J+ t! r LONG OnMouseLeave(WPARAM, LPARAM);' p% ]+ p+ s, C$ R) }
BOOL m_bIsMouseMove;( H  Q6 Z7 h# O3 Y( ?; j7 C  w

! |" {8 W" I0 {+ h$ [" k# j COLORREF m_FrameColor;$ {% H. _1 J) D
COLORREF m_ActiveColor;
. ?$ p6 G7 v7 X/ p3 u. `
* @5 O3 m) Y3 A5 m. f3 o+ R. N/ H, _ COLORREF m_ActiveTextColor;
! E: ], n# q+ d# w; `; r& M COLORREF m_NormalTextColor;7 ^! {5 \. [1 H' }9 K
COLORREF m_SelectTextColor;
3 H+ s6 u( K" o+ I7 T2 H
/ s; L; ]# Q8 b; Q COLORREF m_FrameHeight;" ^, \  u& S' @- K
COLORREF m_FrameShadow;
8 k% _: _8 N( h& X
; g1 L+ c& Q, N" s+ z4 f- ^ COLORREF m_NormalColorTop;- d% [6 F* v' u0 l* A; q+ n) ~4 T
COLORREF m_NormalColorBottom;* k: g0 l) W+ q& ^8 f5 \% S
3 F- }# B% \; R- {. m
DECLARE_MESSAGE_MAP()
; }- j/ {4 j5 k- `# b};
/////////////////////////////////////////////////////////////////////////////
/ t+ I6 I- v  X' U, N// CHsPMEButton
CHsPMEButton::CHsPMEButton()
9 k( I; A/ A9 x/ X: L) F. l{" S& s; ]9 P  g7 `* g# p3 A
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
8 E7 B$ O( L; o! | m_SelectTextColor = RGB(0, 0, 0);
# G( P# u. n; \) \) ? m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
' r& F( K/ W0 F m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
$ T1 _& p7 t. y4 s# O m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
  ?5 E4 g, J' p8 w8 d- F( L, K m_FrameHeight  = RGB(230, 230, 230);
$ j/ L# T; }6 I7 G9 X m_FrameShadow  = RGB(128, 128, 128);
' x3 b4 S8 s" W2 y}
CHsPMEButton::~CHsPMEButton()
, N, x: s% b0 Y3 d: Y( T/ k{6 t  A6 e0 J" a, m9 |
}
: S9 Z7 E' v2 `, b
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton): d1 F& M* G8 \
//{{AFX_MSG_MAP(CHsPMEButton)
! V0 X) E& P- R9 A0 |; w& H) {5 V$ n ON_WM_MOUSEMOVE(); |+ e; i# @. z$ n
//}}AFX_MSG_MAP
) o6 x5 ?; n- c! \+ |& O2 Y ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
, R5 b0 u  F' o5 N- PEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
$ c& t3 t+ H( V; p& Q// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )& |( Y, E# e$ C1 p' b' P8 ^
{; K$ N% K$ N& A) ~
//*
) V2 q4 d0 D. A; d4 U& `; c! K CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);. U. @5 H$ x( ?6 R
DWORD nState  = lpDrawItemStruct->itemState;, c# K9 d! E$ r3 v& Q& L0 [
DWORD nAction = lpDrawItemStruct->itemAction; ' e; V; V) B0 V4 T( V
CRect rc   = lpDrawItemStruct->rcItem;# S- g- w( z/ }" v; }
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);% P: W4 [  W$ \8 ^: ?: Q
CString strText;8 M# W2 X3 W$ n
GetWindowText(strText);
if( nState & ODS_SELECTED )
1 x+ x; D& q' Y  i. X: N {
+ a& i+ r: H% i% w' O  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
- Y+ L2 T3 o3 l1 {2 m  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
  u0 f: L2 a& c: K! [  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
, d# W# f/ Y- e$ u: D }! e0 r) E! ~( m. r) J7 C3 U
else //Normal* E9 n) k" B( ]
{
" w0 _9 X" q" K7 G  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
2 q/ f6 b# c1 p" G: y+ _  \4 b9 N, S  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);0 ?. m' ]) x! `% ^
}
if( m_bIsMouseMove )
/ T; N% Y0 {% w$ |4 O" N0 q2 q {
4 J' E9 y% J2 _8 z; Z0 E" O1 b  CRect rc2(rc);. ]/ O' C- z. y% O, ?; @3 b
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),3 B2 B1 p3 O, ^/ e' I1 [$ ]3 f! c3 ^
   m_ActiveColor, rc, rc, pDC);
$ G/ u* |) d5 d: n8 X) \  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;' a- h/ k7 i) N5 T/ }# H0 J1 B
  NullBrush.CreateStockObject(NULL_BRUSH);
$ M7 ^. ~8 z- t, T% N  K7 t  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);) A$ O$ H( q5 {9 Q1 ~
  
3 Z( Y( _$ d2 n) V. f' Y$ ?  CPen Pen;
3 M/ f0 L' F( u" s) I  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
* c  J  k$ \! Y/ a8 t, f  CPen* pOldPen = pDC->SelectObject(&Pen);- l& H* q, D# X8 N" Y- M
  rc.InflateRect(1,1,1,1);, D, o0 q  s' f5 m9 b$ ]0 U
  pDC->RoundRect(rc, CPoint(3, 3));
& x/ Z2 S- c8 @7 V  //rc.DeflateRect(1, 1, 1, 1);
: v  x/ K/ _2 o( y; s. I  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);, w) w; _  X" j! F4 ?: ~
  & r$ O; D! P* @1 r
  pDC->SelectObject(pOldPen);
+ p0 X6 U$ _  T3 b  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);; R" F# l0 b1 y0 N9 b# l$ f
}
4 L$ C+ A9 E5 [, [  ^- D2 U' R
) }; T. K1 W* k' U' l; y pDC->DrawText(strText, strText.GetLength(),
$ m5 Y2 g# K" U3 @9 ]  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);( [/ u* v. e0 U
//*///
9 i  |. @" t  G- M  N}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
% u! F( d8 L3 `, y+ v3 P4 H! ~6 M! S{
- R$ [" |4 ?; ^; k) N( [$ M // TODO: Add your message handler code here and/or call default# ^" q. j) `# Y) ]
if( m_bIsMouseMove == 0 )
0 b) }& _! {$ V' u( M; R {
* y3 K( W) S# x) R, b+ ]9 d  m_bIsMouseMove = 1;1 n+ g" k* O; O. z9 F8 I
  Invalidate();
( r2 x  }# c! w) h6 g% x  3 M8 n) Z1 G9 y; l: F% X# q
  TRACKMOUSEEVENT trackmouseevent;6 J- `! L5 M# M& D7 S$ }
  trackmouseevent.cbSize = sizeof(trackmouseevent);
+ |( h& K% a) P) U. ?8 W9 Y& m! s  trackmouseevent.dwFlags = TME_LEAVE;
7 U/ q2 E) o2 O+ D3 e- F6 X  trackmouseevent.hwndTrack = GetSafeHwnd();
, R$ M# w4 m, J4 S' u1 T+ f5 j0 l: t  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
. b& J1 ]2 \( D3 T" m  _TrackMouseEvent(&trackmouseevent);
6 L# P* Y& ?# F* n% p: g3 g }* f8 O. I) J: t2 @. A5 N
/ n5 @4 |( k( [& R3 q& _6 C( Z0 W5 W
CButton::OnMouseMove(nFlags, point);
, D* ~6 J7 c) B: ?! p}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
- {9 n) I$ L2 t{
5 d+ d/ Y/ v$ Y, l9 h& A: v m_bIsMouseMove = 0;( Y, n3 s/ e% N" G4 h
Invalidate();
return 0;
# m4 f& ^* |1 H: z: m$ }1 W}
void CHsPMEButton::PreSubclassWindow() . W. v) ]' O  Q; G: {- w; Y8 V
{
6 b+ X& q2 `2 K3 R5 e( C3 S7 l // TODO: Add your specialized code here and/or call the base class
7 u- {5 k2 v( q2 m" o  c4 S  y UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style4 B5 S1 e8 R/ s9 e
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
0 X' W/ {7 q8 j3 [6 _- O# s}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)* h1 H( ~- @8 c& b9 B
{5 |3 a( N5 R' P8 u$ i+ {
CPen Pen;
; h! s- q* w( T% h0 e) f8 v CPen* pOldPen = pDC->SelectObject(&Pen);( h- N7 N- i- |2 t2 u

$ P$ }& O% j5 k int R, G, B;2 j" B9 `7 b/ ^' ]6 [
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
4 o- _( M, t. j G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();. U8 ?& ^) }% y+ L6 M6 z
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();; \; {3 w' ^6 Q
- U& @1 n: u+ V4 f5 ?2 g
//R = R>0 ? R : -R;( K( j/ ]. A' z; U0 {
//G = G>0 ? G : -G;6 ]  W5 q" L5 \( B
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
9 i: H; x# u" P9 d COLORREF ColMax = Top > Bottom ? Top : Bottom;( t3 w9 `' X9 f5 R4 `* e7 Y$ t
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
! H; z" p7 n9 N& b* ~, W, _4 b {
! C1 M- O+ s# m  O- `. |( H  ColR -= R;
& n2 T- E1 i3 J5 [3 Z  ColG -= G;( m6 s. c# m* L. o
  ColB -= B;
  /*
7 p) R9 V% k" T2 G  u9 X. @  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
" q1 P# c& P9 ]' \% U# f7 \4 U  W   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
. I9 f# w$ u2 y4 f/ m   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
' r- V; T$ `' J3 R  {
- l  n0 y# E+ P: L0 n; |   R = G = B = 0;' i, _. _. A, V1 ^) \
  }///*/

4 L$ A2 u5 T5 j5 }0 h, [, ^  Pen.DeleteObject();
. x3 m3 n$ ^0 s  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
! U; {" P. T$ I# J+ s    $ @7 T$ z% T6 D! C
  pDC->SelectObject(&Pen);
/ g0 Q. d* ]  E9 _  
& d6 ?$ [2 L" k& S  pDC->MoveTo(rc.left, rc.top+i);
1 e( t0 l/ o% c8 u3 O* |8 G+ v; l  pDC->LineTo(rc.right, rc.top+i);' o8 Y# N5 }: N
}
pDC->SelectObject(pOldPen);
$ ?, D$ P' ?  T# X* |}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
9 W% m  B, ?5 K: S{
2 m9 Q! \: u8 y1 _6 Y CBrush NullBrush;. e: O3 u. J' k, t/ C
NullBrush.CreateStockObject(NULL_BRUSH);: d- I% |5 x( T8 h/ C' X
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
4 K5 ^2 @5 n' U! ] Pen.CreatePen(PS_SOLID, 1, FrameColor);/ b4 M$ A8 O& {  N& l
CPen* pOldPen = pDC->SelectObject(&Pen);) T* P8 G& A% g
: {) I0 m0 t2 y/ g. w
pDC->RoundRect(rc, CPoint(3, 3));
9 g. \4 u# p* R/ E  o1 k! h rc.DeflateRect(1, 1, 1, 1);
3 @) M0 |6 s$ D8 A) ~9 j/ I pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);# v4 g( g( d) {9 e
pDC->SelectObject(pOldBrush);3 g  e4 y; S( I( _8 m: |
}

8 t+ T3 B. s0 _/////////////////////////////////////////////////////////////////////////////1 [8 Z7 }: V4 O
// CHsPMEDialog dialog1 w$ s3 ~$ F& n4 L$ T
//-----------------------------------------------------------------------------
% z2 O3 i, `3 D3 O9 o* v+ N0 L  x# F7 r1 B// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:6 c7 A6 H% f' a% e9 d  W
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
; e: }' N  o+ n' _" F' l6 u7 v//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口/ {0 P+ M/ P. L1 W: Z# q0 o
//   指针将其显示出来,然后隐藏或销毁自身. H) c& c& e2 ?' a, j2 t. _
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
( M' r2 x& V& q; P//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
* i+ z/ x# r& ^/ j5 g, P//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,1 y9 y. X  D- A9 [1 h) _
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
/ _$ i6 g$ i) M) i; I//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
7 h7 P9 b% S4 N//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框- Q3 Z" u! o  _) C9 _
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。" O% _# |/ F1 Y* U# l
//-----------------------------------------------------------------------------
! j! ?8 n, Z3 `) p// 注意:
( W) [! U* z. g: x// 1、在构造对话框时必须给出其父窗口指针) w1 R) E) w2 l
// 2、在初始化基类时必须指定对话框资源模板ID( e, @3 C2 Z" x4 V- e
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
- o( p$ s+ J3 W// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel! |6 p3 I. B1 o1 L) M
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
+ t' O- m2 y0 a) U{
& f" j/ d! E: U. ]1 G4 Z4 h DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能+ E, z) Z( S8 S" B7 N' C
// Construction9 E( b( e. L* t  |* L( j
public:
# W: G. S3 B3 Q' U5 L! @# I CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
+ _0 v6 I# d, P4 Y6 b" s ~CHsPMEDialog();6 \0 ^8 t: o( U: J6 U; F" e
BOOL Create(CWnd *pParent = NULL);) m1 P% k3 S% l2 k2 g/ ]3 U) o' B

5 M7 o# W' \& J6 b% Y// Dialog Data6 A+ _# w% w6 _2 q! K5 o0 U
//{{AFX_DATA(CHsPMEDialog)1 P6 B& S6 M* k+ n  I' |7 x
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };8 n/ {9 _4 {: i! T# z
  // NOTE: the ClassWizard will add data members here
9 l  ?+ S' z* O5 c' ]8 C //}}AFX_DATA
5 G% `/ J3 w# p
// Overrides' \! l4 T1 _( O
// ClassWizard generated virtual function overrides
6 S+ i+ k" ~' _& ~ //{{AFX_VIRTUAL(CHsPMEDialog)
6 F& G$ V( I# \' L% l protected:' X9 m  o  f& \$ l
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support; s" z: {# L5 d! u" f0 S6 f8 O
virtual void OnOK();$ C0 J7 ]1 ]- s& F  ?1 _4 b" T
virtual void OnCancel();
" [8 m6 w* q0 Y" [4 z8 z; |, P! W! t virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);1 G. q+ Z  K) `" |: ^' D8 d
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);( s# k) h& L) c* N: x) U
//}}AFX_VIRTUAL
// Implementation/ R3 e# X6 |3 A' {
protected:
// Generated message map functions
" ^6 d9 C; `8 f( Q& d( E9 [; W //{{AFX_MSG(CHsPMEDialog)- F9 v4 F1 w; n8 z$ X: c: n
afx_msg void OnBack();. k9 n- p. {+ B1 M' N
virtual BOOL OnInitDialog();
' ?; q8 [2 {( h: N9 a7 N, T afx_msg void OnDestroy();+ ~: K4 J+ E% W* V8 t& x
//}}AFX_MSG
1 A$ J! m  R( M  h; w DECLARE_MESSAGE_MAP()
protected:$ W! j4 M# o/ M+ d
// attributes  m( H2 |3 R# I. u, H0 ~% s* U
CWnd   *m_pParent;     // 父窗口指针
3 \- i5 h6 C# I. S HICON   m_hIcon;     // 图标
1 N) u" c) w# u5 g  V3 H UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
9 P% a6 S5 y. ^) X2 q% F% N' q; [ CHsPMEButton m_btCancel;
9 b2 y! w6 X/ Y8 P CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
$ ?8 [4 u4 Y; @/ r4 b HHOOK   m_hkCBT;     // CBT钩子句柄
' G$ ]+ t8 L2 A! y. G& o 3 B9 d5 ?+ n' C$ F2 V3 G# Z" e$ w' h5 z
//-------------------------------------------------------------------------( @' a; A. O) @8 b1 O
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog% ]; C2 `' L( y: W
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为  G: G% |% d3 ]
// 链表的头及下一个结点的指针
5 z7 A& Q' _: h# I4 X static CHsPMEDialog* m_spHead;; Z5 _7 g- S6 i
CHsPMEDialog *m_pNext;
// operations' z# ^6 \+ [& J+ e5 H: D
// 键盘钩子消息的处理函数
2 s# e$ z/ W' s' R6 D( P; ~2 l static LRESULT CALLBACK KeyboardProc(! U8 ]) c; |2 d2 F
  int code,       // hook code. j) E  }% W2 g8 x! k1 Z: |
  WPARAM wParam,  // virtual-key code' a# t/ {& R' x/ @+ j$ l1 `
  LPARAM lParam   // keystroke-message information
3 \' L) O# w( v0 Y4 i8 k  );* M0 E5 w- v0 P
// CBT钩子消息处理函数5 W2 d  o4 \" K5 |$ W6 q3 Y: M  a9 Y+ m8 U
static LRESULT CALLBACK CBTProc(
2 D: e( h3 C& F4 l8 c5 l" ~  m  int nCode,      // hook code
3 h7 B' f6 r6 a; z0 |  h+ |% Z  WPARAM wParam,  // depends on hook code
) N7 n& s0 t9 S$ A  LPARAM lParam   // depends on hook code
6 ~3 k7 \. C, v* k  );
* W7 J1 x7 d: b+ m! S2 H. V; d
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
7 Y  U. y" u$ u2 |! p static BOOL  IsWndKindOfThis(HWND hWnd);
* n2 b, G9 Y7 f! V9 s // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)+ I8 h% i- J% Z5 N  g
static HMODULE ModuleFromAddress(PVOID pv);
5 u8 F' z6 G; d- Rpublic:' y/ b2 z. w$ z; {
// attributes
// operations
5 c9 o+ o. w* O8 X3 `* K/ q  h5 I // 用于模仿UG的创建一个子对话框,同时隐藏父对话框
7 j/ x! w  U. D6 _3 p BOOL CreateChildDialog(CHsPMEDialog *pChild);
- [7 f1 [  A( h};
( b" O/ n2 I% d" x( J9 H
CHsPMEDialog* g_pHsPMEDlg = NULL;
$ }  F" G6 {3 ~CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
: j  V" }  ~3 L- x2 v/ SHHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
- K% h; @/ J) q5 M9 ~ : CDialog(nIDTemplate, pParent)
0 ?. u" |. v$ j1 O5 o) p) l% o{, `( Q0 Z" l, c3 U( ?- b% k$ Q% V5 E1 H
//{{AFX_DATA_INIT(CHsPMEDialog)$ u  e  R2 g0 {1 i9 B# }
  // NOTE: the ClassWizard will add member initialization here+ U& ]9 w  L* R+ }5 Q& {
//}}AFX_DATA_INIT
* F9 L# [3 x! W1 ]; I m_pParent = pParent;8 i3 o* f8 i2 E, }, f
m_nTemplateID = nIDTemplate;
! @( V3 K5 R  _4 d  S m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表6 u2 \) ~  O0 u% i& N7 C4 g+ A
m_pNext = m_spHead;& H  x3 M' Y5 N
m_spHead = this;# ?5 k  r; t" l
m_hkCBT = NULL;
4 c; c! t' J/ m4 c}
CHsPMEDialog::~CHsPMEDialog()
/ u9 x$ d- j$ _8 v{
. M" ]5 y- v8 j& X // 从链表中删除本结点. H, G* D% K+ o  J) \! S
CHsPMEDialog *pTemp = m_spHead;8 ^( N- P: g, j6 h: o
if(pTemp == this); C! C1 A# L% Q2 X& L
{3 I9 v4 V* L) x2 j$ Q" F* s7 o( c1 o
  m_spHead = pTemp->m_pNext;
  h& {2 G2 D& [$ w) H) } }
" K  s9 u" q$ }3 g# ~0 p% J+ [ else
+ F8 _' L2 ]  q {
3 D) W( H1 U5 `$ O# V, ^- ^  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)* m* s; s+ t* S* P+ G$ W& O
  {
9 u, J( O) F/ T. x: h% o& `   if(pTemp->m_pNext == this)
" ~& [: K) A- Q3 f0 b   {
# ^7 d; o% m) U* o4 q    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
7 K* E) y$ b& a5 T7 _    break;; T1 Y5 P: u  B! V  Q& [7 \- \! w7 B
   }3 L2 i% B' O/ b7 ~5 u' u; c1 |
  }
+ Y8 |! S" N: _% q- G }4 U" y" M" V# ~- c# e, B
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)% D5 a: k# u  Z( F
{
3 u$ u* H5 Y9 u. ?+ t$ X* d0 p CDialog::DoDataExchange(pDX);4 e7 b0 z4 g' X0 I8 R9 Q
//{{AFX_DATA_MAP(CHsPMEDialog)
! l. b9 i  o& N$ V! m6 t DDX_Control(pDX, IDOK, m_btOK);: l' i  Y$ H4 ^0 A% v9 T/ ^! s
DDX_Control(pDX, IDCANCEL, m_btCancel);! \/ w3 M3 C& l' a% d
DDX_Control(pDX, IDC_BACK, m_btBack);, \9 j+ C: M. g0 H* |* d4 c3 o
//}}AFX_DATA_MAP! o0 D8 ^: y3 o2 ?8 w
}

" `6 n+ R3 \$ E: c, p- ?8 X$ nBEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
# i6 E5 f& l% q. J* W, I //{{AFX_MSG_MAP(CHsPMEDialog)
# K1 t3 _1 g3 \% d2 [( ? ON_BN_CLICKED(IDC_BACK, OnBack). W; [" D% H3 k% g# }7 u8 q1 _  q
ON_WM_DESTROY()
$ K( ?+ v: E% Y; e1 q* N( Q //}}AFX_MSG_MAP
- N1 l1 {# E) \END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////7 E1 I4 L' ^  D
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
  m) n  H3 f9 c9 q7 {7 f% b{2 w9 u/ i7 K0 V9 c7 X
m_pParent = pParent;
: t  I- N  L( e return CDialog::Create(m_nTemplateID, pParent);
6 ~! V( Q: Q6 Z, N8 [( I7 F  B}
% t3 y+ n2 t8 G8 b" `
BOOL CHsPMEDialog::OnInitDialog()
0 q  n' \1 S0 {& E* A{# b# ~+ ?# ^: r# h/ [' H
CDialog::OnInitDialog();
// 设置标题栏图标
9 {) d  y, Q9 R SetIcon(m_hIcon, TRUE);
% \% F/ Q' \3 Q0 e, R; {; k SetIcon(m_hIcon, FALSE);
+ X$ g: b* W- @0 g/ g- Q# c! k' s
& d  x% Q+ G5 Y0 Z: X$ g5 r) s; N // UG的对话框的几个标准按钮没有TAPSTOP2 p" p& T0 z" P+ D! B
CWnd *pWnd = NULL;- @( a3 u) @* O- v+ b0 h3 Q
pWnd = GetDlgItem(IDOK);9 k/ D: ~0 G; e
if(pWnd)
0 w- n0 S  g. m9 C {
0 h# \. Q# D6 F7 ]$ R! W  pWnd->ModifyStyle(WS_TABSTOP, 0);
. }, Z) s0 p$ p$ o! H. @; g5 A  | }
+ M2 v  m. w/ e& J/ ^ pWnd = GetDlgItem(IDC_BACK);
2 A# p& u# Z& M/ c$ I if(pWnd)2 O5 k1 w$ y+ A0 l
{2 h4 C" e) m0 {* m! c2 M
  pWnd->ModifyStyle(WS_TABSTOP, 0);9 W  E5 p$ v5 |9 J! ^' q
}
% c0 g) V3 c& n& X$ k pWnd = GetDlgItem(IDCANCEL);
8 v& c7 |6 W2 b7 _+ [9 i: w if(pWnd)
4 J4 F% e( `% c- |! I! s, ]% @ {- p/ F6 H: ]9 S4 G
  pWnd->ModifyStyle(WS_TABSTOP, 0);& d! r& K3 x. I: z" b* U! Z
}# s/ {5 F8 p/ i3 m7 D1 j

6 \  U- l7 B) ^2 G$ E. l4 u g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
+ L, E. M; P( p' V0 z8 h8 ?/ A: y if(m_hkKeyboard == NULL)/ r: w7 p5 e7 r) |5 q; ?, [4 q7 H
{
+ \8 k) I* V1 @4 V, p( J  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());1 M4 c3 B' o7 D
}
3 B9 _6 N2 C% J& t& ?0 B if(m_hkKeyboard == NULL)% W: P7 q/ |8 Z
{4 P; L7 J- R' z) ]7 i, F8 v
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());$ k3 |/ r" D; Z+ e
}
if(m_hkCBT == NULL)& G/ ?: M# M: y( Y) f0 V1 A$ }
{
( v! O+ G5 \% S& p7 {& b0 p0 S9 \  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());3 u; `" C8 S. I7 q+ X2 `9 O! a5 y
}
( j4 K; ?) F( t( ^, a; v if(m_hkCBT == NULL)
( B4 x; |! B# A1 Y" L! @" f" B! _ {
) z/ Y% r3 [1 v9 ^4 r  TRACE("Set CBT Hook Failed: %u/n", GetLastError());& A1 x) q9 d; Z" A
}8 u+ j/ h4 \* W
$ B" W* V3 u' F6 k2 j" c
return TRUE;  // return TRUE unless you set the focus to a control
$ X5 O( A" D* ~: D               // EXCEPTION: OCX Property Pages should return FALSE+ @+ [7 u4 Z: h8 ~' }/ }9 H/ Y% K: E5 T
}
void CHsPMEDialog::OnOK()
$ E! T! }+ h2 X. c; r{8 B0 |- k( [" R$ e
CDialog::OnOK();: R! c9 Q% d6 o; d$ @
if(m_pParent)
. B% j9 X6 {8 o" D1 Z- F+ z {
+ f  {1 }3 x  ~4 V# G  //m_pParent->DestroyWindow();# }! B+ T1 h" K3 O! O
  //((CDialog*)m_pParent)->EndDialog(IDOK);
6 f- @3 F# Z1 w2 N1 X( L  ((CHsPMEDialog*)m_pParent)->OnOK();
3 b: |- l1 R- a- x$ U( a- d4 Z }0 N+ i5 `. w& H7 Q
}
void CHsPMEDialog::OnCancel()
# P& q) \6 C+ @# a5 D{4 h5 J$ v/ g0 c- j5 h, s
CDialog::OnCancel();
2 V! |2 m3 F0 d, o if(m_pParent)) s& f4 L  S. `# c7 j3 W
{
3 v) k( I( W  ^5 \: o  //m_pParent->DestroyWindow();
0 h+ w; M9 U, k8 J2 s$ ]( I  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);& h, B. r% j4 q8 J
  ((CHsPMEDialog*)m_pParent)->OnCancel();
6 \' X& ~9 @# M9 x }. B* O, K+ f, O" f
}
void CHsPMEDialog::OnBack()
- N2 h  o% l6 z( J{
; Q* n+ S5 k2 Q& u1 S  Z; f if(m_pParent)7 m/ ?# x, \! D) L- I' h
{
" c. l8 b4 {& V1 v. S  m_pParent->ShowWindow(SW_SHOW);
) j. N( ?# A, ~ }8 v5 |( Z! J6 r6 V/ m! c7 B1 p
CDialog::OnCancel();
" n$ Q* p6 B+ @' |; O}
0 x- u2 A4 B) T" ?. @6 w; ~
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
, C/ J( D6 I; M( g3 H{
; ?7 V# {; o; X. B, v- u% _& E BOOL bRet = FALSE;. T" X5 Z* T. t  K
if(pChild->GetSafeHwnd() == NULL)
# E5 i# _9 j& a. Q6 m {
8 `+ H" d* c$ `5 [) H  bRet = pChild->Create(this);
6 E- A3 X" W' B# k7 |# K" I }3 L. z. p& Y2 @$ p1 I: J
bRet &= ShowWindow(SW_HIDE);
) V. M6 g5 N" A- ~& u" l1 H9 \$ V: l' l bRet &= pChild->ShowWindow(SW_SHOW);2 M) u; {, ?2 N. I
return bRet;7 }. b1 g- ^% @& K
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
3 c; i) J6 L, Y8 T$ g! S1 D{  K+ e! A/ H7 @
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
, |% X3 ]8 }' x. f5 A! { {
0 p* M6 g: A9 a5 R) H4 @0 ~. `  //TRACE("Key down/n");
& z, h! m( b# ]  r8 D" w  CWnd *pTopWnd = CWnd::GetActiveWindow();
2 D0 }6 I- d  ]5 R& M2 P$ @0 c  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))- `2 G' q' G4 @! i
  {/ b+ v, r. L% {* U9 v; Y# u% J
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
  ?9 e1 T: Y6 F+ h6 G   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)" d5 t; e: B" R/ a8 `, s
   {& e8 m. H2 [: t8 i! X
    // 只截获tab、esc及回车键
& b  R% s5 T2 O% i1 T9 W    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);; O8 ?7 P- S. o6 {( h- C8 [1 v
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
' ^- _- [7 ~8 A   }
: A0 \4 Y! U7 A) e- N   switch(wParam) {# t  v% Y' A# F# I( l
   case VK_TAB:' t- M9 r8 D. B
    {0 X& V& W; i$ V" w; H1 b* D! I8 B6 A
     CWnd *pWnd = pTopWnd->GetFocus();
5 I  S% N! H9 w: r; o6 Q8 A! T     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
- Y0 \/ a" n& q! E" @- G     if(pNext)- L) H3 ]$ w# V5 Y, D+ z
     {
) h# I, \5 G6 q% g$ A      int nCtrlID = pNext->GetDlgCtrlID();
" V. O' l$ q5 [! i, N3 ]/ m      //TRACE("CtrlID = %d/n", nCtrlID);7 ?4 N/ J/ I7 j8 `! e1 z3 {' R
      pWnd = pNext;/ E6 B0 L6 c+ |$ H. G
      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
1 L( ^9 u! G. X3 u4 K$ h      {& a% i/ z1 Z( h/ y7 G, E- j3 P
       // 根据UG对话框的属性,这三个按钮是没有焦点的
3 {8 j+ Z1 _+ M8 ?7 k2 _       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);5 H; {1 k% w9 X/ n# X" l
       if(!pNext || pNext == pWnd). y& O. m9 [; a
       {
0 I. z; ?# C" y# `7 H        // 对话框上只有上述三个按钮4 d' f" k; l5 ?: j* b3 Q
        return CallNextHookEx(NULL, code, wParam, lParam);
# ~1 r5 L7 {% T8 h( F       }
4 W# V( k/ S; ^& J       nCtrlID = pNext->GetDlgCtrlID();
+ y' F% a/ ?! V. a2 F; S       //TRACE("CtrlID = %d/n", nCtrlID);
; G. C# x) t2 p, y      }, z* Y# v/ b' n/ O& w, I
      pNext->SetFocus();
$ P$ U6 Y' |6 i" D5 n  ^& k     }! m( _5 ^. f/ n7 ]
     //return TRUE;
% F1 [8 q1 B( M: _" L5 |% d( g( U5 Z    }
( R- F6 L" {8 C- }- u8 q* \2 o    break;( t2 g* M& k, Q; i. c( D! D
   case VK_ESCAPE:7 k) b6 R$ {  w6 V/ R
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
! {. X; F# p8 g. F8 G- ?& W  s    //return TRUE;. f2 `7 `! \( |- k" R
    break;0 ?* G0 {) I- g5 e" d
   case VK_RETURN:  K# l/ O( U2 |: X; A
    // UG实际上并不处理回车键
& C: E/ ~0 r8 Y5 H" h    break;. X# x4 i" s% A8 p
   default:0 S% R6 h" k( Y4 G' A
    break;9 Q- a' @# B# p* Y9 G
   }7 ~3 d9 w; @, x0 y
  }
. f. R! r5 h+ n" W6 _" S }
* P5 ?. I/ ~1 o$ V return CallNextHookEx(NULL, code, wParam, lParam);" O( m+ j* l/ t/ q* X
}
void CHsPMEDialog::OnDestroy()   H5 W( v# n: g1 }% i& P
{
, V; i1 A% i" e! \7 S1 C CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子( m' H7 u$ ~8 o
if(m_hkKeyboard). r) \( Y' B6 n$ ^
{8 M5 v# h9 p7 w' x
  UnhookWindowsHookEx(m_hkKeyboard); ( D3 X# ?* Y) O3 `6 q
  m_hkKeyboard = NULL;
+ F+ M: |1 `$ Z; r# z9 E5 @ }
if(m_hkCBT)- I* U: M5 s" e# q" Q% H
{: c2 d/ K4 G+ m9 k( ~4 t5 B6 x1 D3 a
  UnhookWindowsHookEx(m_hkCBT);
8 q) L8 y7 Y; r3 D  W3 B' P' x  m_hkCBT = NULL;& K2 y0 Q* X# r3 u( T
}8 Z! r2 b2 W' X4 T/ J; S' Q% m
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd), x9 I2 D1 X0 ^# H3 e! l9 I/ F
{3 m* `8 _3 o4 b' U& |
CHsPMEDialog *pTemp = m_spHead;
. G& E( V, J& W BOOL bFound = FALSE;1 P3 z! v# ]6 |
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
: V% I. C+ c& z  }0 Z# P {5 W. ]7 O0 Y0 j$ @; O
  if(pTemp->m_hWnd == hWnd)! q+ E! L& g+ p& s+ D5 O/ o
  {0 S, r2 p$ s; R( H
   bFound = TRUE;
! L1 K: v# r- r7 G! D2 e   break;7 T2 h( u- Q$ c' }2 ^5 @0 c
  }! n2 U! T) D. r
}
+ B8 a  ]% A" J$ o) ?# [) J return bFound;6 B% {' Q# _. q3 `+ q
}
// Returns the HMODULE that contains the specified memory address
. j& J5 Z0 O8 N6 nHMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
/ ?* W- e' J$ G( h" {{5 j& x& D  d) u! e7 Z. f: j
& Q0 {8 `3 S: ~& G6 ?5 R' k; A3 q
MEMORY_BASIC_INFORMATION mbi;4 y4 h7 P2 w. I, G$ h
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
& P  V1 S) |' @5 R- o' t  ? (HMODULE) mbi.AllocationBase : NULL);
! G: K# k, W0 A6 C}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
9 R1 U% z/ b9 S) \# y* b6 x7 Y{
2 B) h  a- h- A6 P; j, z if(nCode == HCBT_CREATEWND)* t; @$ P. ~: K; X. d" d
{
3 P. |2 P/ i% f, r# n' J: e8 z: B  //TRACE("A Window is being created/n");
' P* n; C$ O0 ^! T7 [  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;( ~7 i4 B2 U5 W# H2 x
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
+ a; t! Y& B+ @9 ?8 l" B  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
4 n- E; J7 G2 }+ V8 Z0 L  {
9 ]* h) ^8 X, Z& R8 O   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
% t! v) F- W6 B: ^8 k9 W) \   // 取得窗口处理过程内存地址
: l2 N5 b: e4 Z! a   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);# w% I8 i# M5 u2 `( \- F6 `; o3 s
   if(dwUserData)# d7 D$ a0 J/ c( H1 t* O
   {. a% `# K" h5 [3 _* }
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
- Y5 ~' Z+ o" J! V+ ?% f    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};" U) h1 g1 W/ k) \* i$ V4 e
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);' N, a+ J" K. M. ^0 F0 b4 J
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
3 i% W6 r0 d2 \" K    TRACE("CreateWindow Frome Module: %s/n", szModulePath);# l) |5 c- C1 `
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);  `# t+ [4 D8 z+ w3 O
    if(stricmp(szUGPath, szModulePath) == 0)" M1 V" f! R4 _2 g' Y# h2 K0 t  {# ]
    {
. ^+ L$ e8 N' W( h* S% O     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
& E9 F# H8 o0 U$ F     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)0 {9 G$ R# i6 \
     {
) F/ T! \2 ^, G+ F      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)8 g4 }( l* J  b. k( Z
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && ( @& c1 r: s& w
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)* i6 u' T0 C% i$ U9 I2 W
      {: e& S+ `5 ?; _( `( _; a' F
       // 窗口非本窗口或其子窗口* e3 y! P/ z% L
       g_pHsPMEDlg->OnCancel();
. c, V8 Y8 n$ L( a8 B& ]; p6 {& ^      }8 Q" f, y( {$ t( a. j: @* n
     }% q. X6 O- f* x, h4 ~' k
    }
! h2 T' D" Y+ i7 v   }
: E9 {1 E3 e. D; @  }
8 L. q2 B- J7 m" Y8 s/ [: X }1 ~" a0 D; ~$ A9 H. O8 _
return CallNextHookEx(NULL, nCode, wParam, lParam);
. C$ z, W, _/ y) |. ^' l}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 7 }+ ?9 j/ X) E* |8 c. i0 p. J7 D
{
# n0 R! E( j1 q6 R, \+ l* E2 n* | // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
  W' ^( i9 N4 H) p4 R& t
1 o5 o# a+ P) o" `9 a' @: J return CDialog::WindowProc(message, wParam, lParam);
; q$ ~6 w4 S2 G" {) Z}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) / w" s# O& y' {# ?2 \. i
{  H  Q/ F- ?; r/ }4 h

% V, v( p# d! j" c return CDialog::DefWindowProc(message, wParam, lParam);4 @8 e7 k, z) `# S$ a& |
}

! h/ _, {" t  g8 w
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了