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

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

[复制链接]

2017-8-31 13:24:24 3339 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
9 o0 O$ B! m* E2 D4 G// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类; e) S9 D# E3 O9 S% D8 O1 d
//    该类来自网络,稍作修改,版权归原作者所有
2 d4 ?. v6 x. n6 `/ ]+ C$ S//-----------------------------------------------------------------------------! q" q7 M0 W& d( h9 i
class CHsPMEButton : public CButton
  ^0 W) H1 c/ d{# C" T- b( G# n8 V6 g" J- }
// Construction3 _) T' h7 A; k* C
public:
. J  q9 U5 b: o2 d% s" a CHsPMEButton();
% d9 t; S0 B; w
: f9 T/ {0 m- O0 v/ q' T // Attributes3 V0 [2 _$ ~, ^) q
public:9 ~6 l8 f7 {5 D0 t% o
" D/ t0 d% H& K4 V! `
// Operations
" f& b# }' q+ M% `public:
+ t" A- ?8 D2 _8 V1 u2 q inline void SetNormalTopColor(COLORREF color)
1 a+ p2 f8 [0 _3 y) j7 f1 c3 W {% h- [$ G1 f% I5 p) p
  m_NormalColorTop = color;: n& k/ Y3 A3 }% X
}
) U' Z2 o, y! L4 j inline void SetNormalBottomColor(COLORREF color)0 x0 w8 r) N! Z7 _" w
{
6 K9 `+ Y0 w( y  m_NormalColorBottom = color;) S: [. L6 i( j2 o: z
}7 T+ W. }0 ^! S
inline void SetActiveTexTColor(COLORREF color)
3 c# Y" z$ c# A$ ]% C. G5 K/ x/ f {2 ~" N; G$ g& X& d/ E
  m_ActiveTextColor = color;
% I+ J: V6 N$ G, } }5 |9 I; p1 L) }8 P9 A* P3 a/ h/ Y) ?
inline void SetNormalTextColor(COLORREF color)  z3 E1 x! X- [
{
& i1 h+ L) V, [9 |2 J  G" t  v  m_NormalTextColor = color;4 e9 a6 U# g. J: ?1 c2 t) z
}' h& H) m6 _) Q( _
inline void SetSelectTextColor(COLORREF color)
$ g& m8 `3 X+ i {! L3 |$ n3 k, M& }
  m_SelectTextColor = color;
& ]. f/ y8 p5 d }" I  Y. y) E1 u4 X( x$ V6 x
inline void SetFrameColor(COLORREF color). l; b- H  z$ C* i' }5 L
{! R+ r. I. P8 l% p
  m_FrameColor = color;& D. c0 B2 D- ]- @4 X! [+ m
}
% d- h% L) D; P8 _# `8 y& V inline void SetActiveColor(COLORREF color)0 h. J, v9 [7 g$ p
{# f, q( q7 A8 y$ H
  m_ActiveColor = color;( A7 H  m( S# D& K( v1 \, I
}
. q8 L( m- C: ~/ N0 F1 @5 ? // Overrides
  W- L; s% i8 q; A  }' r // ClassWizard generated virtual function overrides6 @3 q" ^. h# U1 X
//{{AFX_VIRTUAL(CHsPMEButton)# ]( z1 U# L/ `* g6 k! A4 {
protected:( j; f* G( x: Q2 X
virtual void PreSubclassWindow();* k7 h& \4 C8 ~) W7 o
//}}AFX_VIRTUAL( \+ n; q" F9 y: G" o; W

3 l! p# Y* b; @0 Z4 ?/ D+ B // Implementation
5 x0 a3 Y; _) }public:! _) `8 J* O; x; x* v
virtual ~CHsPMEButton();: x; _/ X1 g4 p
1 t* N7 A6 {0 c! N) J& q
// Generated message map functions7 L; W1 e/ a+ |: e# b
protected:* v: L4 v' w6 L1 @0 B
//{{AFX_MSG(CHsPMEButton)" z' L& m% R2 Q* S. J3 x0 @
afx_msg void OnMouseMove(UINT nFlags, CPoint point);7 E/ U3 j+ J( N( V  l  W' t
//}}AFX_MSG. g' m, @# a: y- V  z+ V
8 i0 e% Q# n7 }
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);! U# J* G% h0 }  F( @7 C1 D; P
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);. f& N& \: ~, V. u) T3 L
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
" ]" E" d9 M5 X: j% C& { LONG OnMouseLeave(WPARAM, LPARAM);& f& x9 H5 j1 U. E  E1 E
BOOL m_bIsMouseMove;3 S9 L. A+ [0 a+ A. z+ y1 r9 L- f( ~) \

3 c" G% |2 o1 B" p4 ~ COLORREF m_FrameColor;
; A9 E) X- D4 d COLORREF m_ActiveColor;
! Q; o) y5 h7 g0 r! O9 E 8 c$ [& V, B3 L- Z  U) e" S( `4 B
COLORREF m_ActiveTextColor;; X/ {1 k2 {3 K( ]; o
COLORREF m_NormalTextColor;
  ^+ f7 h1 ~0 s6 Q0 j9 r3 ~3 i COLORREF m_SelectTextColor;. s9 ~  z1 |. n% o: X3 Y

# c/ A& n0 M2 |+ j8 K COLORREF m_FrameHeight;$ V( W) n0 n+ j$ @/ w
COLORREF m_FrameShadow;
7 F) Z: k, N$ {: p, c- K' V + T% n! I; W! s: N
COLORREF m_NormalColorTop;
9 \: E% x( {; U* e: F COLORREF m_NormalColorBottom;( F; M! E% l. G& _* Y2 l  e
& S* z+ A" j$ w, V+ T
DECLARE_MESSAGE_MAP()
, j7 V. V; F! x. d9 C6 O; J};
/////////////////////////////////////////////////////////////////////////////
. q! u& `4 s6 Z, m/ G/ {* ^- m' T// CHsPMEButton
CHsPMEButton::CHsPMEButton()' L6 C! p7 g( B; ]- u( A6 [
{
, R) I9 s5 I: O m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
' [5 f1 q* x) K" o$ Z2 y3 X1 m m_SelectTextColor = RGB(0, 0, 0);
, b6 b6 R, q9 W+ j2 X m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
; f3 i3 k# S$ U0 C/ |* ?# @' _8 | m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
- D( _7 [6 d6 ~9 e  V m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);- D( L3 m/ v* e' N7 n
m_FrameHeight  = RGB(230, 230, 230);. `# T$ Q# Z. Y7 {1 e* P5 p
m_FrameShadow  = RGB(128, 128, 128);
8 [/ i6 R+ ]2 N  k" g}
CHsPMEButton::~CHsPMEButton()
* Y/ o2 ^  \1 a9 a( _{& ~0 g5 L- `4 q
}
4 P$ J6 w0 p- }. [
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
: r; B: Y8 e( q+ j$ h# [ //{{AFX_MSG_MAP(CHsPMEButton)6 G6 a7 N4 m0 N0 {
ON_WM_MOUSEMOVE()
. F+ S5 U0 i* S1 Q" A# m //}}AFX_MSG_MAP7 N5 ~. x  c+ Z+ o6 W
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)% P) I; f; J7 [$ v; Q$ |" {; d+ o
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
1 l9 \6 L2 }2 G7 M9 V$ ~4 Z// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )- [! t  h1 n2 i) h4 K9 k: O
{
7 }( {5 T5 B) Y. N- e //*
* U1 d! X9 X  K6 @$ L6 Y7 l CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
: q" Y5 d, b$ s DWORD nState  = lpDrawItemStruct->itemState;5 T' {. j  }* n! a, o6 u/ d' E
DWORD nAction = lpDrawItemStruct->itemAction;
6 C. D4 a* z, l& | CRect rc   = lpDrawItemStruct->rcItem;# V; @+ l' U2 @2 B3 Q  O  I) u# Z
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);* R# D) o" V- ~2 y' A" {3 }/ F' @
CString strText;
' W5 m. m& A2 z3 S GetWindowText(strText);
if( nState & ODS_SELECTED )
& r: I  {2 o% d& |6 R3 `# U, O  Y/ E {
- Q' X& ~3 C; K" S% R0 B  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);( ?) T4 z0 Y+ m8 A4 E
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); & p$ u* ^1 u& g! N% ~+ b
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);2 T' {1 ?) n2 B' [" J- S
}
+ {; G% D# d. h; n5 D else //Normal- u* J0 J5 Q& |, E: d  ?- u
{* _- k7 J  \) v
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);4 i; A0 s! s% [; O+ ~
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
  L% e6 i: q- ]' P }
if( m_bIsMouseMove )' k/ f. B" {* y' ?
{
2 m; O% q" J$ j: T! T  CRect rc2(rc);7 f: R1 t  u! Y' c- f9 f
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
6 X" G# o. }3 q& S2 K2 \) @( V8 q   m_ActiveColor, rc, rc, pDC);
! l! _6 W$ c- p2 |/ R+ L" _9 ^; |4 x  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
: G8 U5 F! {" ^. `9 ~/ `  NullBrush.CreateStockObject(NULL_BRUSH);; g7 O) s: y" m0 E7 H- u8 o7 |7 g9 X
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
. z+ i% H7 H; r9 I  
, [$ l5 Q9 y  J& ~  CPen Pen;
* F8 N+ P9 k4 i5 T! ?* x  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);: }, C0 x7 `9 }4 j
  CPen* pOldPen = pDC->SelectObject(&Pen);
8 x$ O( H2 \8 c- W# c3 S3 W# ^  rc.InflateRect(1,1,1,1);2 l0 E1 ?7 x6 |* O+ K4 S
  pDC->RoundRect(rc, CPoint(3, 3));
% X0 i: I/ x. Q" p$ Q  //rc.DeflateRect(1, 1, 1, 1); 1 z3 ?- p$ a3 Y) b. ]# S
  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
- e: ]0 r  j1 y) K1 P& S  
3 J3 M9 z7 m, h7 e+ K: R  pDC->SelectObject(pOldPen);
9 v' D3 G, N: Z2 s' O; [  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
& F/ ^- @8 A4 g% w" G" j7 B+ u4 W: C. P }% G( ^; x+ H3 L3 y. s
% D4 B9 |+ ^0 j% @* \7 D
pDC->DrawText(strText, strText.GetLength(), & O6 r3 @3 @3 \
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);* K$ }3 ]! ?( U" d: p! C
//*///
  _6 q. N# ]) b- M" Q6 q+ C}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) ) g1 G' A" l0 M- a& X% G6 u( ]$ w, W
{% `8 q* {1 w' g9 q
// TODO: Add your message handler code here and/or call default( u- ]. d4 I6 _! a% ~4 L7 X) V  w
if( m_bIsMouseMove == 0 )
* v0 y/ l6 s* X2 T% A8 |/ m {
5 I1 r$ n/ r' L/ B  m_bIsMouseMove = 1;& r4 X8 j9 H# }, d$ w+ X( v
  Invalidate();# a! [7 K3 r2 S; D$ M# n$ ]7 T
  & g" }' E- n5 e3 Y8 c# S$ S' Q
  TRACKMOUSEEVENT trackmouseevent;
" b- }* W# ^  g# N  trackmouseevent.cbSize = sizeof(trackmouseevent);& {. W5 `0 m  F
  trackmouseevent.dwFlags = TME_LEAVE;! V6 p7 _) a1 l. ?
  trackmouseevent.hwndTrack = GetSafeHwnd();. t2 p, e9 M9 w3 }' i3 L# M
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
* M1 i$ T/ j8 P8 {" O$ {  _TrackMouseEvent(&trackmouseevent);
) N4 I9 }* X$ _0 t, l, e9 ^: k5 Y }/ L4 q7 G1 d$ Q3 t+ q# n% t: y% w& g* [. Q

; Q( R& j0 q$ j8 @/ Y3 Z CButton::OnMouseMove(nFlags, point);4 l% ?( t- S, S$ d
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM): Y, M, `0 e8 _  Z
{4 b6 M5 `) B; ~4 i
m_bIsMouseMove = 0;- ]# L; U( c* K/ \- Q
Invalidate();
return 0;8 l. Z/ z; t% q8 t
}
void CHsPMEButton::PreSubclassWindow()
3 J  |& f' M/ j3 Z9 z{
! [8 n: Q- h4 B* f. ] // TODO: Add your specialized code here and/or call the base class
# [: r# O' w' W# l2 ] UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style3 d" v7 B) {) t( k
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();9 i$ N' Y/ n7 n" G" D3 P% ^
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
' g6 j  o% `$ B3 j) {{
7 I' V/ x6 `7 T: y! c- M0 q CPen Pen;
$ `$ B! I1 p, i) r% Q CPen* pOldPen = pDC->SelectObject(&Pen);
: }4 K! j7 c$ L6 i5 @
* K# W& ]  W: O' `  Y: c int R, G, B;
8 p9 R! A2 B* H% |# O R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
2 M3 Z$ }. E8 R  y0 j  i8 v) u G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();  d/ Q. ~1 \0 g8 b7 S
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
1 f1 |/ q3 q3 F0 E' `4 }! Y- p
8 u, j" [" J1 H0 z+ }/ b5 @ //R = R>0 ? R : -R;
1 v1 d1 u. H) o2 B; e) m //G = G>0 ? G : -G;' `8 p* _- @  \( u% h9 ?8 z
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);& r8 W9 N3 K5 }3 C2 Y! ?3 b
COLORREF ColMax = Top > Bottom ? Top : Bottom;( `" B5 i+ s4 T( X. R. k
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
$ }" B/ X& K% \, ^ {: ?5 p- u4 z# }# T
  ColR -= R;4 b6 M* d& `2 ^; P! `
  ColG -= G;
8 G$ V2 z: r2 y1 s- b. p  ColB -= B;
  /*
, X' U' K$ |  [" A+ W  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
  X* c% p) Y7 o9 N0 v% L# r   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||, \4 E1 e& k( G9 H2 l
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
8 l% [0 E* F! h( M$ V  {. J  E$ {, V# L3 R0 h" z" S6 ]  d
   R = G = B = 0;1 f5 a' U9 o0 e* c. |- i9 [1 h
  }///*/
- K' h1 O9 X5 I% Z7 Z2 B3 }2 }
  Pen.DeleteObject();
) u+ N5 R+ u3 s4 |6 v3 N  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));' Q2 |( P8 Q7 W" t! f; H: A2 v
   
* z( w& n. c; ?3 ~  pDC->SelectObject(&Pen);& o9 ?' w, W& n; P! u4 d' {
  
6 w  N* j. v$ Z  pDC->MoveTo(rc.left, rc.top+i);6 _! S- C# u: x* M  _8 V  z
  pDC->LineTo(rc.right, rc.top+i);! t6 e; n: W8 l+ Y) Y6 ?/ ^
}
pDC->SelectObject(pOldPen);
: M) |4 T4 j5 [7 S% A  K3 @}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
& G/ \: x- @. Y0 ^{
# z8 w+ z5 X1 D CBrush NullBrush;
% h9 b) L) c5 H8 j0 l5 `, B NullBrush.CreateStockObject(NULL_BRUSH);
7 C0 R7 p2 c3 i4 x CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
6 B# k8 @* P$ X6 H$ g3 {0 M Pen.CreatePen(PS_SOLID, 1, FrameColor);3 n2 z% E9 k  q  @" j
CPen* pOldPen = pDC->SelectObject(&Pen);
6 Y2 }. i/ ^+ q. o
. _+ w' h, m" ~7 T) j' k pDC->RoundRect(rc, CPoint(3, 3));% D; S6 a' I$ e+ Z
rc.DeflateRect(1, 1, 1, 1); 1 R5 U) F! U3 R& x& I6 j1 `
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
$ f" q; g1 y: } pDC->SelectObject(pOldBrush);
$ k2 j! M0 G) d( Q}
9 B, `, @  y  ]+ S+ F  L5 `
/////////////////////////////////////////////////////////////////////////////( }+ o- E$ ?5 R* K$ L
// CHsPMEDialog dialog
* c( Q5 X1 ]8 o6 s//-----------------------------------------------------------------------------
- [; N1 M& m: U, i3 L// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
+ ]9 u4 T* Q/ [* r//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
/ E9 G3 L" W7 }) k  k//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口8 x- n3 H6 V  W3 G1 A
//   指针将其显示出来,然后隐藏或销毁自身
  Z0 T& q  t6 x9 H1 @5 q% H7 D) J//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。2 U, Y; b0 I; I, E
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类7 q7 p3 ^6 X. M: r; O6 x, e5 P& \
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
3 @6 ?- }+ g0 w, H$ q//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。# ]- N* M0 ~8 J" a! B$ a+ S
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
) f2 B: P; b+ v0 |# I( I//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框/ \3 d/ v1 W% K6 y/ y3 O
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。& C$ C4 g0 C: u% {! \
//-----------------------------------------------------------------------------
6 ?% T9 o8 |. O* p4 @+ J// 注意:
' v: i& [' M7 ^9 \; O0 u5 i// 1、在构造对话框时必须给出其父窗口指针$ |0 G, P$ ]* `/ y# c
// 2、在初始化基类时必须指定对话框资源模板ID8 A5 I$ e( [8 g7 n; R6 c- P
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
% }! a; m# X; w// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel; ?% a" b& F: }
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
* Q% P% Z8 W5 `- D$ I; u{3 d( A+ |- r4 V0 T" y0 j9 E0 }+ F2 |. O
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
4 t2 I7 G5 X7 Y% ^+ g7 V7 t// Construction, C" Y* Y: g0 `7 A# F% B  h" `$ I5 `
public:) {# g; @! B  R0 `5 z8 ~7 [
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
. [0 ]2 L9 B% h$ R, c ~CHsPMEDialog();$ K- K, E3 j; W& J1 y/ `
BOOL Create(CWnd *pParent = NULL);
7 p4 ]$ q) Q1 V- k. F 5 h4 O: \1 N$ M# z- I; l
// Dialog Data
! c0 K- t+ C# F+ p //{{AFX_DATA(CHsPMEDialog)
) F- J) h) ^9 v3 j+ L# M //enum { IDD = _UNKNOWN_RESOURCE_ID_ };
* E) `8 y% ?7 i3 t  // NOTE: the ClassWizard will add data members here
. V; }$ t2 b6 }* a8 t- _1 m //}}AFX_DATA
! m& [* B( u% T) r' E
// Overrides( q& M4 t4 D, ~0 U8 ~
// ClassWizard generated virtual function overrides, b0 F9 i  l& a4 ?+ P5 N* G# @5 _
//{{AFX_VIRTUAL(CHsPMEDialog)+ Z) k) `" E$ V. b) f. H. _
protected:
0 H% A0 O) u2 |8 ^ virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
$ n6 z6 L2 y. E4 r virtual void OnOK();5 s0 Z4 m% w& S$ _
virtual void OnCancel();
5 V* F3 W) `0 N4 F- I virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
" l6 m- j. f" f9 l5 M virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
4 _1 ]9 N/ @: V$ Z! d //}}AFX_VIRTUAL
// Implementation
7 {+ q3 c3 |: ?9 n- q! C3 w$ j! Hprotected:
// Generated message map functions
7 q; J8 b4 _1 l9 w# m7 @ //{{AFX_MSG(CHsPMEDialog)+ D7 N5 i) A7 ~
afx_msg void OnBack();# [7 Q' n* s) N( A9 |' f) J
virtual BOOL OnInitDialog();
+ Z, w1 t$ e; _9 Z4 P afx_msg void OnDestroy();
: n- ^3 C: c$ O+ L //}}AFX_MSG
/ U8 x) z3 c8 w/ b DECLARE_MESSAGE_MAP()
protected:! W6 i" \: i& F: h* U
// attributes: G3 H+ o" _' V3 N1 Z$ i
CWnd   *m_pParent;     // 父窗口指针
+ Q# t. i8 ?$ j) r HICON   m_hIcon;     // 图标, ]" ^0 }. ?+ e6 d  j) M: h
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;' _* r* B+ V. O3 q
CHsPMEButton m_btCancel;
3 ^1 u  R+ e9 B$ V2 A CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄' Q' E) Z# D2 b" ]$ h
HHOOK   m_hkCBT;     // CBT钩子句柄* r7 [, Q. \' X( J8 M+ J$ k
. ~% Q9 w: A+ D
//-------------------------------------------------------------------------
& Q9 }0 x- c: t  b // 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog+ c- M6 I" @- L
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为# S; c9 }/ X1 q! W2 h3 e
// 链表的头及下一个结点的指针
- |1 b( h9 a2 k4 `; k  U& Q static CHsPMEDialog* m_spHead;1 z: |, c: ~1 w0 [
CHsPMEDialog *m_pNext;
// operations  f. B$ f5 t! ^5 L* z
// 键盘钩子消息的处理函数* S. S- k8 T' G/ h4 |5 S
static LRESULT CALLBACK KeyboardProc(
. L% |. T8 e, o3 L. K/ P  int code,       // hook code& ^  v8 y' t4 Z
  WPARAM wParam,  // virtual-key code2 s$ S/ p$ E  [6 j* V* Q' a6 G
  LPARAM lParam   // keystroke-message information3 n! y- ^0 ~- _* l+ f
  );
& `& O4 [! c2 o/ C. I. P! x // CBT钩子消息处理函数
  m9 P+ Q1 a9 h, ] static LRESULT CALLBACK CBTProc(
! s6 t9 c  H# L( m2 i/ O% V, B  int nCode,      // hook code
' O; y0 Q) r) j  WPARAM wParam,  // depends on hook code# X' p1 z" a+ ^( M) L; ]% ~
  LPARAM lParam   // depends on hook code* V7 C' S- D4 s3 p1 {/ g3 Y% Z, n
  );5 W1 H% E5 C% H0 B, O+ Z/ a
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
0 G1 B- \9 S; y- d7 f static BOOL  IsWndKindOfThis(HWND hWnd);
1 e/ }3 A+ M. ^4 T6 q5 y! L2 E2 _( q // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
& e/ }& r1 G) S# a static HMODULE ModuleFromAddress(PVOID pv);& G0 S" E  V. _+ j' \
public:: w4 S+ O$ s& s5 `7 n% {
// attributes
// operations
# f: L0 h4 G, {* h; x // 用于模仿UG的创建一个子对话框,同时隐藏父对话框+ d9 b  H( J8 f
BOOL CreateChildDialog(CHsPMEDialog *pChild);% M; P8 ?' o: Q1 ~& o' u6 Z
};

' D0 @. R" A- @! l: p( dCHsPMEDialog* g_pHsPMEDlg = NULL;, z) C# Q$ `) Y, @  l6 J9 z
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
) a: [9 W0 |2 y5 q# g5 m" u4 @" UHHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
, t, a+ ?$ B' n7 Z+ \7 | : CDialog(nIDTemplate, pParent)
  {& s0 c! e9 Y7 p! e* M- @{: r9 p+ \$ |( E) z; C* I" H
//{{AFX_DATA_INIT(CHsPMEDialog)
) C( Z* S9 X% y9 j  // NOTE: the ClassWizard will add member initialization here
9 z) l  J4 Y* O //}}AFX_DATA_INIT
3 v. x% X, g* k8 [* u m_pParent = pParent;3 D% n% ~, W" a. D6 P
m_nTemplateID = nIDTemplate;' k- n) F+ |7 R1 s: b( \3 t+ `0 K$ `
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
  S, V  |8 b* \7 @( c; @ m_pNext = m_spHead;# g1 q: ]# S& r2 z7 Q
m_spHead = this;3 B# T+ Y' ^4 [3 }1 b7 L2 G
m_hkCBT = NULL;
/ @, }$ _& {8 [, x) ^6 z9 @}
CHsPMEDialog::~CHsPMEDialog()
" f: n4 p# W( I6 Z{
" @  [% _: _0 \& t, w# {2 p // 从链表中删除本结点  F( N: a0 Z% a# e4 k
CHsPMEDialog *pTemp = m_spHead;: D! N. L  {1 U2 g
if(pTemp == this)7 I6 ]) O/ v- F0 `
{5 d" Z+ d% o& x8 ]4 o6 V/ F
  m_spHead = pTemp->m_pNext;
; L; Z7 I; g3 o* M) \ }
* d4 p4 a3 t  X else& o" m! {8 f8 n1 s* y  X
{1 F- e9 g; Z  j2 n: X4 [5 }7 m
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)# {) \( F8 j1 l
  {
3 T+ }. k) x' P, g) t; f   if(pTemp->m_pNext == this)8 a8 A0 |0 i' C5 z
   {
1 v9 w- b% s9 B, E    pTemp->m_pNext = pTemp->m_pNext->m_pNext;; n( c+ K3 S: g- o" r
    break;
* z. m  k7 a% _( `0 K. o# [   }
" J# l) W6 j0 j5 M& M  }3 Y6 P- `2 x9 y* y7 j" {, Q
}# }- ^5 A$ Q. N9 w
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
- s% j- c7 l2 a) G/ l- M$ c{+ {- y  y+ Z+ C' P* D2 H7 k3 u
CDialog::DoDataExchange(pDX);
- V, ?2 u1 [& q3 j, U2 M //{{AFX_DATA_MAP(CHsPMEDialog)4 t. T! _7 H# e: Y4 j" m
DDX_Control(pDX, IDOK, m_btOK);# v! B6 M9 x2 z; r# m9 ?4 H
DDX_Control(pDX, IDCANCEL, m_btCancel);
; y2 h' |1 @; O5 y+ f1 I8 a" i DDX_Control(pDX, IDC_BACK, m_btBack);( d% O3 |/ ~& M+ H
//}}AFX_DATA_MAP
+ l# V6 O$ s2 p5 N}

$ G+ [1 \) n' g7 V, g  jBEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)( A# o  H- c5 @! ~+ t, Y8 q
//{{AFX_MSG_MAP(CHsPMEDialog)4 G/ z. g( O+ Q
ON_BN_CLICKED(IDC_BACK, OnBack)
: R3 u/ s/ |/ A" x% E ON_WM_DESTROY()- @1 k. M0 m. `, Z4 |
//}}AFX_MSG_MAP* L9 n7 h5 T  I3 s$ v$ L" V1 \" l
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////: J4 Z% _# d# X- K2 R+ r
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
# ?$ Y/ V) \( `; m; Z. w3 ?2 _# Z{: V) E. [3 i4 R! O! h3 R/ l4 G
m_pParent = pParent;; l! H- ?9 r+ T5 q. @
return CDialog::Create(m_nTemplateID, pParent);! T7 H1 V! t; _9 S5 [
}

- u$ g" ~! m  W) U  K5 }- lBOOL CHsPMEDialog::OnInitDialog() & u6 v. H7 ~. V9 h) S9 j
{; V" a; K  ^5 x" L! `3 g
CDialog::OnInitDialog();
// 设置标题栏图标
0 l" c4 d4 q+ A% {& |0 w6 J SetIcon(m_hIcon, TRUE);
4 a2 z' _( ?  j( Z. h2 L" y0 W SetIcon(m_hIcon, FALSE);. m6 p6 Z) X; ]$ Y! _5 n

$ f" n. V# V# Y // UG的对话框的几个标准按钮没有TAPSTOP
4 D( @8 ?7 _0 m3 E CWnd *pWnd = NULL;
7 x! d! K+ M" l; q- v6 K pWnd = GetDlgItem(IDOK);
4 n5 c0 l* {3 | if(pWnd): ]- d6 F) G: n$ ^' L
{
1 M( P; C5 Q7 E' O, g  pWnd->ModifyStyle(WS_TABSTOP, 0);
" G9 g" G" ]# V/ {$ O' w7 c9 A7 K }
' f" C- S; |9 p pWnd = GetDlgItem(IDC_BACK);
6 g( m; d& \  u if(pWnd)
- w1 m1 x3 x9 G8 B7 p4 B- f {
, Y$ ?! w- m/ h  pWnd->ModifyStyle(WS_TABSTOP, 0);1 Q' i: }$ q7 U, N9 m, s% N
}# q2 I" W3 U4 ^
pWnd = GetDlgItem(IDCANCEL);
9 ^+ k7 X' a& O) a7 M: ] if(pWnd)
7 E2 @1 P6 I( o# \9 p7 W {
$ t1 U& ?: g' t+ q  pWnd->ModifyStyle(WS_TABSTOP, 0);: @' s0 u; J4 a* c1 N- j
}1 H# G; O4 y. K
4 ~, S1 P- h5 o) z5 |6 E5 ]
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
2 U6 h2 _& c( X9 T6 Z if(m_hkKeyboard == NULL)4 b! w( G; g) j  ^. s
{' g  \( {$ q: D7 s/ m
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
2 c# X9 s( N) v) ]4 R+ l! M7 A }
6 O& ^$ h3 J) h2 N* Z0 R1 v if(m_hkKeyboard == NULL)& F" q, }6 X' w7 O0 j
{/ a, J" \6 P: R0 L: R
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());0 ?. w; C! S- g& [7 r5 u& s. X
}
if(m_hkCBT == NULL)
: \4 U. M; ]% ~: |' M% b {% U  d( `2 z( v' M# h4 b
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
5 o+ L* i2 S* d3 S }
' w8 M3 T9 E7 Q4 ?0 n& D5 w; o if(m_hkCBT == NULL)
' ?: w3 S: I7 q1 t/ E7 r2 J {  c7 h5 Z; v& v+ D4 q% a
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());4 O$ K$ G& b, _* P1 d  Z
}
. G2 y) B9 B8 S( o4 H
6 R5 I( a' h2 I6 D; \- n return TRUE;  // return TRUE unless you set the focus to a control  I* r8 W- v4 {" ^% ^; ^- k4 l- E/ V: H
               // EXCEPTION: OCX Property Pages should return FALSE
$ ~$ C6 o, y' h3 r2 B; x) ^. \6 q}
void CHsPMEDialog::OnOK()2 M% Q; }2 U4 p6 a- g; \' k
{
4 {+ {, p; k6 x7 b& r CDialog::OnOK();
9 Y# x$ h% |# I' h  U7 z# m if(m_pParent)
6 V8 r& g% ]) O) x {  p' I2 i0 L" r9 q% V7 Z1 O
  //m_pParent->DestroyWindow();) b7 M9 ^/ w' z) H) ~& r/ H6 V
  //((CDialog*)m_pParent)->EndDialog(IDOK);
+ T4 L( M& ?1 K  ((CHsPMEDialog*)m_pParent)->OnOK();
8 P* h! G7 k% f" _+ Z8 Q4 v: m! y }
' v1 L- D. v/ c3 r0 }( z}
void CHsPMEDialog::OnCancel()
$ P4 z  Q4 ?% A/ [{
1 Y8 d) x9 x, N$ F5 | CDialog::OnCancel();
9 U% V8 s- o. ^, P4 Z if(m_pParent)( h9 H. k/ o8 w/ q3 s
{
, X: F5 i+ Y% V  //m_pParent->DestroyWindow();
# |$ {4 K! E6 b  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);) @7 I! E% T" d; g
  ((CHsPMEDialog*)m_pParent)->OnCancel();5 [9 f$ W# Z8 y, m8 K! D9 i6 ?+ c
}. p1 |# s3 ~0 |# @
}
void CHsPMEDialog::OnBack()' n! f4 A+ y/ L# q: }
{
! h1 E9 w, ]3 u if(m_pParent). ~4 x0 {& Y" j3 E, g( B) B
{$ ], N6 w: K  z% l  h+ E; \
  m_pParent->ShowWindow(SW_SHOW);8 n; {; N% r0 Z1 ^& Y; i
}9 q7 h- H' o+ a/ O+ q
CDialog::OnCancel();
2 _4 x: d3 e8 {% T2 _4 _3 d% L- J}
9 D, t( ^3 D' j
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)* `) r: j! R. u! y9 B& f
{4 S) S; D, A  }  w; {1 p
BOOL bRet = FALSE;
9 v5 x9 h/ d2 q5 O2 x5 x" b% B7 s if(pChild->GetSafeHwnd() == NULL)
- W+ h" s3 K5 E) K6 U {0 o- u9 U+ @; d9 ?/ X
  bRet = pChild->Create(this);2 b3 V: T% m1 M
}6 z7 C7 k, r& Q
bRet &= ShowWindow(SW_HIDE);
* e3 r& i9 w6 R5 J! Y" c bRet &= pChild->ShowWindow(SW_SHOW);3 K- }% {; i# {
return bRet;
0 U1 Y) K+ C, T& Q3 B9 o}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
( @6 d  {6 k7 p$ [1 ^/ H{$ ~. o* S; F7 Z4 S& t: J" W! b% I
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
/ }# S& @/ `% p5 d {2 U" X9 [1 l8 g: K% m
  //TRACE("Key down/n");+ P- }. O+ [+ F. E5 }: u  h9 e0 Y" _) ?
  CWnd *pTopWnd = CWnd::GetActiveWindow();2 b' {8 Z( Y2 @$ v2 p/ M$ v( J
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
) t7 M2 E( w0 D7 ?: L  {+ K/ i# a7 K. h% e5 L
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息4 |/ t- G2 T1 y' P% ?3 ?) G) Z- v
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)2 \9 P" |" f% q
   {, R8 B, c* y5 |; I$ o& ?' _
    // 只截获tab、esc及回车键
+ W  j( h! L4 f) ]3 l, T    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
, s/ M- l  S$ l2 u8 h    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);' l3 M1 O- Y/ _9 d# z* b: _2 _4 V
   }
. G+ d/ r. `4 b; S   switch(wParam) {
- L, [4 X0 q$ [* D! z# z   case VK_TAB:
1 s9 j7 P+ x2 U& Y    {
8 x  b. z, ]. k" ]     CWnd *pWnd = pTopWnd->GetFocus();9 Z: i+ _# p2 [0 R' q8 j( v* z0 m
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);- ~" j, r0 M& {: E
     if(pNext). o" s9 y1 @4 C$ o
     {) y0 t' Y/ y7 B$ B' X5 i' v0 ]8 u0 Q
      int nCtrlID = pNext->GetDlgCtrlID();
0 H3 W3 y1 n# H: q1 ^5 D1 y      //TRACE("CtrlID = %d/n", nCtrlID);) _+ @) C$ C  w8 r; k  j7 ]8 y
      pWnd = pNext;
( Q+ T. Q7 b$ x  x      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
' X+ F. I3 ^. i1 \' I. w      {% X9 A* e/ ]+ |
       // 根据UG对话框的属性,这三个按钮是没有焦点的
, u5 I( @: K2 ^2 g       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
. m9 k2 L2 L8 \2 b' C       if(!pNext || pNext == pWnd)& x, @4 A9 A8 j: z1 U- v6 g
       {2 {7 }* e5 Q$ {7 G
        // 对话框上只有上述三个按钮, H3 n% U3 P/ T  C+ N! ?
        return CallNextHookEx(NULL, code, wParam, lParam);
* A+ e5 F# S* c8 @/ x       }
! l8 ^3 H! U9 p       nCtrlID = pNext->GetDlgCtrlID();* b! p& t5 s: |* \$ \9 I' C
       //TRACE("CtrlID = %d/n", nCtrlID);
6 U$ t% a3 X* Y4 V+ O1 a' e% a      }6 C* t+ l! b" k6 ]: w$ C6 Q9 u
      pNext->SetFocus();
2 E$ K9 Z. [$ x     }
3 d/ V" u2 p; C* ]5 D, |     //return TRUE;1 g8 s% _9 S/ }9 ~& {
    }$ I: O) N1 ~/ [5 E
    break;
2 [$ \8 }/ t  ]9 T, w# E   case VK_ESCAPE:
* [; P5 H, w% H. B    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
% i, @# I, x" r5 b    //return TRUE;
8 E2 O4 j' \- e  \) F    break;' |# Y( _; j7 l7 F9 ]' G
   case VK_RETURN:! Z% z' Q5 e0 G: e  B; [% M6 B
    // UG实际上并不处理回车键* N8 B7 f. @3 A% s; M
    break;, B# f! p2 ]& s( D2 D  d
   default:
* h( X% P# f" N! F3 v" K  U    break;
2 D# c# q. h' A  m& l. @8 q( A; Z3 F   }+ j1 s$ l4 \' q3 z$ j1 @$ n
  }) Z% `3 X! D( h5 A. m: ^* F
}
7 J* g( R/ w0 _5 H8 e6 W return CallNextHookEx(NULL, code, wParam, lParam);, u$ ^4 [+ a2 T! r
}
void CHsPMEDialog::OnDestroy()
: j+ i  |' c9 M{
7 h1 T3 J! n: C* s5 e CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
+ a5 j2 e5 b5 F: E" F9 V if(m_hkKeyboard)0 l2 s) V4 _% Q' V
{& x( J0 N! j9 _( w9 F* R
  UnhookWindowsHookEx(m_hkKeyboard);
' T4 F& P$ f2 [+ A; }  m_hkKeyboard = NULL;- |) _8 ^: ^8 h) z$ Q! `
}
if(m_hkCBT)
* z7 i& P4 U' s8 f1 W' S {
7 m* N9 C/ b+ T  UnhookWindowsHookEx(m_hkCBT);
1 h4 d! @6 ?5 Y: {, L  m_hkCBT = NULL;0 t1 o4 c0 M. R  h5 H& K% Z4 X' j
}+ e5 G0 P, [$ J8 C
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)) p% H% c1 U. e0 o  S4 k; `
{& N" B& n1 t6 @+ T7 A. Y$ x
CHsPMEDialog *pTemp = m_spHead;
0 }$ y+ _2 d1 r! `+ g' b BOOL bFound = FALSE;
- ]4 q  M: {. G: e8 q' ` for(; pTemp != NULL; pTemp = pTemp->m_pNext)
  ~0 q# u5 u0 ~1 D+ n6 [ {
# l) }" U$ w- S: v& Y  if(pTemp->m_hWnd == hWnd). ~9 Y, Q/ H. G4 }" D, Z7 l
  {$ V% ~9 C" k2 x' }. k$ Q
   bFound = TRUE;/ D6 M1 \; E4 a9 [; X# p
   break;& s8 [6 ]0 m& c' @& ^
  }! T0 O* g1 w2 L1 F9 B+ N; {
}; x5 ?: K* _7 q$ F9 I( U
return bFound;, [& J5 F  `( V  P+ u7 V
}
// Returns the HMODULE that contains the specified memory address
' k  u5 N% U+ |HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
/ o, K+ ?& _) ^: ^  q6 t& Z5 l- W% R{8 T& R0 @/ I7 O: \$ j! h* n& p
5 u! k3 T% g9 l( ?
MEMORY_BASIC_INFORMATION mbi;
8 O6 ]- T( g+ ] return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) * G( W/ Y% `$ i. q; d% g
  ? (HMODULE) mbi.AllocationBase : NULL);
3 B$ N3 f, _6 m& M, }' D}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
3 ]- q# {( \% b5 I. p6 [{
7 T/ i; w7 m) c+ p, F if(nCode == HCBT_CREATEWND)
" D" N. Z9 l1 _/ I) o+ n9 f# _9 @; i {
7 v. e2 Y" X  K3 P) m( T2 b  //TRACE("A Window is being created/n");8 K, I# G) d7 B% S5 k
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;$ ]2 z- U4 G8 a3 ?+ r
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);2 i* u5 u. i. u# I( z# F
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
9 J# Y1 B: ]' ~6 r  {
  a, P& R5 V7 _4 z. E   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应7 O# r' z$ H1 y( z9 t; |- r! i
   // 取得窗口处理过程内存地址
) f: v. o& _8 u4 l   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
* \5 C! J+ C" R   if(dwUserData)/ ^) J/ Z3 E# x& Z( w
   {7 e2 H2 A. C: s) E. X4 R$ C
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
8 G  y2 e: U& ^' S1 {: C; P: U8 e    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
  z: k& ~/ v$ f5 ~6 J  p    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
; V4 f3 ]* h3 d% I. j1 }    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
5 C6 K* R  a% g; x    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
! a3 G3 n# V1 C3 |' q# c    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);6 E  R* F& ]8 ~$ |  [
    if(stricmp(szUGPath, szModulePath) == 0)
8 ~) v3 \; U" b; T9 e3 i    {
# j' N- N: h# c; e6 ~     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
) v3 m  T2 h( @; S, W" k* M. K     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
) G: g9 b" C- b1 N5 c     {
% ~  s" q+ W3 ^4 X  }      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
" g" U' @: b& N% T/ U5 _      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
& L; I+ H. F+ `1 q1 x  c! q) H       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
& ?# v" Z& q7 Y4 ?      {3 o( q9 X' G5 `2 z- d5 R
       // 窗口非本窗口或其子窗口! S+ J) D1 A( B3 F
       g_pHsPMEDlg->OnCancel();
$ a0 |, s) k' j2 s; f      }
; G8 j1 r! ?% ]/ B6 H# ^4 W     }
! c0 |- N9 G/ V! K; Z5 @6 t, f& R    }
6 e8 S4 A7 T# s# y- n7 ?9 a) M   }. `3 o9 M2 @3 ~$ @
  }" P( T, o; B0 {/ r  G
}
$ z2 W) |; |- G/ j+ B" z return CallNextHookEx(NULL, nCode, wParam, lParam);4 C3 v- S# U2 S# w' H# b
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
; C- _$ i" U6 ^: \6 V5 e; T& a8 K{6 }$ l0 }( a2 A, u0 ~2 B
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
* Z5 g* ^( E+ G1 S- O" x/ o: m & J- j# \# l, `* B6 u, ~/ d
return CDialog::WindowProc(message, wParam, lParam);
( |+ G5 P: s6 _# [" o, m}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
+ ]# L0 F9 g8 t" X, p6 ^{. A8 x1 f) l5 R

3 P3 K# a: T, F# y/ w$ o return CDialog::DefWindowProc(message, wParam, lParam);( ~, G$ k8 S, d) L5 k, L3 C
}
- C. L/ r# r9 L' b, h& H9 M! L
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了