PLM之家精品课程培训,联系电话:18301858168 QQ: 939801026

  • NX二次开培训

    NX二次开培训

    适合初级入门或想深入了解二次开发的工程师,本培训结合ufun,NXOpen C++,大量的实例及官方内部的开发技术对于老鸟也值得借鉴!.

    NX CAM二次开发培训报名 NX二次开发基础培训报名
  • PLM之家Catia CAA二次开发培训

    Catia二次开发培训

    Catia二次开发的市场大,这方面开发人才少,难度大。所以只要你掌握了开发,那么潜力巨大,随着时间的积累,你必将有所用武之地!

  • PLM之Teamcenter最佳学习方案

    Teamcenter培训

    用户应用基础培训,管理员基础培训,管理员高级培训,二次开发培训应有尽有,只要你感兴趣肯学习,专业多年经验大师级打造!

  • PLM之Tecnomatix制造领域培训

    Tecnomatix培训

    想了解制造领域数字化吗?想了解工厂,生产线设计吗?数字化双胞胎,工业4.0吗?我们的课程虚位以待!

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

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

[复制链接]

2017-8-31 13:24:24 3122 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------6 D/ c* T) j6 e6 l) g) B7 a/ K
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类; c8 X0 Z# J% W7 M
//    该类来自网络,稍作修改,版权归原作者所有
" Y$ k( p# k% v- }! ?( G5 q6 J9 U//-----------------------------------------------------------------------------
; U0 s/ A/ C9 B  Q* ?class CHsPMEButton : public CButton1 X) l7 [! T4 g: P
{
4 n' l2 s! P# w. \' Z // Construction! U# }% d$ \# j
public:3 ]! F5 _, E6 T) I" U
CHsPMEButton();- [% x9 C4 h/ k: [4 `) t
6 H0 a. c/ a) ~
// Attributes
' [. G! N) S9 M& O, Ppublic:* Y0 \! g4 s7 A8 J3 `$ E

; V. X: Q/ a; Q$ p6 } // Operations
: R5 n( y+ u9 e* n" k( m2 {8 cpublic:* v0 `. L$ a  x, i+ a' ?6 ]$ B" r. t
inline void SetNormalTopColor(COLORREF color)& J# |  \7 M" c, S1 L3 z
{! ^. b7 q  ^1 d: ?4 B
  m_NormalColorTop = color;
1 {* A. V) p9 J }6 v8 ?: q1 p' }; }- v( L, h( L$ h- ?
inline void SetNormalBottomColor(COLORREF color)/ j# V7 j: J, h" Z5 G
{4 W' h$ P, [0 f) t
  m_NormalColorBottom = color;
) B/ y4 N: W- N" w2 l }
. V) J% @% A0 H: j! w2 Z inline void SetActiveTexTColor(COLORREF color)
% V  ]5 P6 B% F% u3 F {
" L! S! Z; P: k8 I" U; A  m_ActiveTextColor = color;
: f4 h! C0 z: Y" x# E/ ~! e }
4 s2 b! q+ z6 }# _ inline void SetNormalTextColor(COLORREF color)
" `( @7 p% _- |1 v1 m {) B2 Q5 a) o! R+ ]1 R
  m_NormalTextColor = color;
* |. P; f# g+ M/ J: E$ T  n4 } }* {8 C1 k* ^1 h+ a
inline void SetSelectTextColor(COLORREF color)  G' I" i$ C% C4 y6 q. r% r$ p; E; r
{; o. _3 X( n. L% F8 }% m
  m_SelectTextColor = color;* Y9 L+ |' X3 C( K7 {% H/ X
}
/ Y4 F1 P1 ~- Z# m inline void SetFrameColor(COLORREF color)
$ B6 K: b+ r5 Y) b$ g$ z$ | {
9 G0 F: Z2 Z( g  L8 U+ o  m_FrameColor = color;
! y3 [2 Z8 `! n4 x; S0 I7 i' g }  z) l5 R4 ?$ C5 K7 d
inline void SetActiveColor(COLORREF color)
$ g3 }7 \+ i* t8 g: S1 ] {* r' x: `  F4 ?* T' l2 o
  m_ActiveColor = color;5 I8 P6 B' M* P. U
}( a( A6 v7 z# j( [" {* _( H, Z8 z8 o
// Overrides( c. l" l# G1 b' D- P7 a4 i" @
// ClassWizard generated virtual function overrides
; u& x  U. T* o$ J+ K: ` //{{AFX_VIRTUAL(CHsPMEButton)
  q) ?& P! ~2 {( _9 {6 {protected:/ D& x# V6 V2 Z
virtual void PreSubclassWindow();
/ B; A; H( h" \; K7 z  J# | //}}AFX_VIRTUAL
; |' `. s( g/ m/ `3 }7 b' R ! e% D5 D! H" V0 Y5 f' `3 m+ W) `$ B
// Implementation* a, A) @; r5 J; M; S: o
public:1 [/ ]  o" g  i. r3 q2 f
virtual ~CHsPMEButton();
6 ?# i) |7 Q& p  X9 X9 a/ D / d/ Z9 |/ O% _) @- t9 `
// Generated message map functions/ Z) j, B/ F0 d* x" [% L+ y
protected:/ ], x, \9 [* r& W: n& x' I8 `# e
//{{AFX_MSG(CHsPMEButton)
8 l* n( f: B; [ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
' g/ a+ [& o" n9 C" v/ E5 S //}}AFX_MSG3 B. S  _0 w: Z6 L

+ W3 |# I+ W- B9 u) N void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);5 Q/ L# u. b* o$ ^' R
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
, E+ G/ Z: a$ q3 [ void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
8 y4 W/ \/ u5 _: {/ q- W) I LONG OnMouseLeave(WPARAM, LPARAM);
7 X% u: Y1 ?7 X, V: C% C BOOL m_bIsMouseMove;
! o' P" ]3 N, `, |7 C; V) o7 K1 [
3 H9 [( N0 _' n& o5 E, x COLORREF m_FrameColor;# ~: x) V: r  S2 M# }8 {
COLORREF m_ActiveColor;# @4 {# k9 y/ W6 _( `; q3 o

* o3 }" g6 \, [! {3 I9 }! l* B COLORREF m_ActiveTextColor;
2 `7 I0 X# f: Z9 S$ Y COLORREF m_NormalTextColor;
7 f) s: j5 h1 E8 R0 n/ z* P7 T COLORREF m_SelectTextColor;
; m# N4 @# k, h0 F2 p 6 |- j, ]4 ^! r" W) N% h" O) C
COLORREF m_FrameHeight;
. p6 }& U" h# o% d+ [1 J! ~0 X COLORREF m_FrameShadow;
+ ?, E# I/ s/ s" }2 ]5 z; F+ W) n
) M2 y- g1 {: w& u* D COLORREF m_NormalColorTop;) x) [$ F* B) W! \
COLORREF m_NormalColorBottom;
+ v5 P# A- E! }& D" t' o9 P 4 N* \4 a* z- W/ ?
DECLARE_MESSAGE_MAP(), m6 y  s6 o: G6 ~- ^) y1 D" E) m3 Z. ]
};
/////////////////////////////////////////////////////////////////////////////( _" M5 A6 Z, A3 `( P" z
// CHsPMEButton
CHsPMEButton::CHsPMEButton()* C: |- O% V  p: J, T
{
. r! Y' g  E. B m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);( z# i8 v. V3 ^  r1 w+ t3 @/ f- h
m_SelectTextColor = RGB(0, 0, 0);
2 h7 l. L3 X, W4 }: t m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
+ [1 L7 _' p( S0 S- }! b$ I1 B3 C m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色5 b) \  l% }% T. m  C" q
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);3 K) q7 Q6 ?4 p
m_FrameHeight  = RGB(230, 230, 230);5 m" @- O- Z3 y+ L2 V+ o
m_FrameShadow  = RGB(128, 128, 128);
! y  M, R/ p- `+ o5 }9 x}
CHsPMEButton::~CHsPMEButton()
2 o- S0 _* u0 m) }' C! c{
' J: Z" v) w, D7 C- r% P) {}

8 _5 q) k1 o2 [1 m* O, v3 |BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
% x& ~0 J6 H$ j* b/ I+ r //{{AFX_MSG_MAP(CHsPMEButton)5 z( N: [* e; _# z( w" h) f$ h# K
ON_WM_MOUSEMOVE(), T  M( v, w; ~# o
//}}AFX_MSG_MAP
4 v" |1 D" }, V2 O ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)4 n# @- y! m/ g+ Z3 `* G
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////9 L* L$ }- X9 B
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )9 L! b/ b7 q8 q& P5 y7 g" V6 E
{
, i% P9 u* L. r/ a/ i1 G5 l( x //*
% d1 B, A, d- q# [3 w7 J CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);. U! I, R  g9 {3 y  I
DWORD nState  = lpDrawItemStruct->itemState;
/ n. V, l5 O: e- l0 V$ q+ n DWORD nAction = lpDrawItemStruct->itemAction;
& L( S0 y; ~/ P6 P, Z; P CRect rc   = lpDrawItemStruct->rcItem;
! q! p% g6 W- j* U) K+ W9 ~ UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);
. m  k( m9 M- q  T CString strText;
6 }' }/ {# |+ S3 l# U  a GetWindowText(strText);
if( nState & ODS_SELECTED )
+ D- ]* Y3 M" @ {
5 z- t. e/ C2 ?  V) P- y  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);1 C( H" `  m, _7 `# S
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); 9 s* |/ v% u% t) F
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);/ Q- f+ o, D9 e! r2 ~; O
}. c8 Q/ |6 d3 D0 ^
else //Normal' P4 t# F$ ^* P% @; ~$ U
{* e" M* U3 Z# K1 [
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);4 I/ J6 Q/ ~0 w1 p  \
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);4 \5 X( X4 R7 f$ m4 Z; s
}
if( m_bIsMouseMove )
  Q8 S, l: c9 m, E6 `2 L {
/ o, {. [* m: h# A+ H  CRect rc2(rc);
) C  H6 ~8 v* Q% f3 H  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
' }6 x* p0 o6 |. K2 E6 x" `$ o5 R: Z1 y   m_ActiveColor, rc, rc, pDC);
  ~* N! T- v$ h' W2 j# M# `  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;4 k; w* _1 l6 D& ~" I' n
  NullBrush.CreateStockObject(NULL_BRUSH);
# V/ p" C, t+ N6 I- D" H( N" D  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
3 p  k6 e  }9 y/ ]- L  9 S8 ^/ E  q9 k: L# V
  CPen Pen;
5 H2 b, Z3 X; ?6 G$ I: D  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
: U5 K/ N5 w/ h& `  CPen* pOldPen = pDC->SelectObject(&Pen);  Z! u& }: a# d  }
  rc.InflateRect(1,1,1,1);9 L. O% S' {: R" w( B
  pDC->RoundRect(rc, CPoint(3, 3));
+ R8 m9 D: H: I3 Z  //rc.DeflateRect(1, 1, 1, 1);
. K# B$ k  C8 G$ Q  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
. B) w8 J0 [4 r- k( ?  0 J& w" g( k% s& H+ Z! F
  pDC->SelectObject(pOldPen);
# @* n9 P9 ^4 f/ d6 o- C  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
$ Y8 L' `& u+ k; f. G }9 U. S( e8 F- L; Z
' _# U) c4 V& B
pDC->DrawText(strText, strText.GetLength(),
3 E4 T& F# _1 \$ a( m  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);2 m! C2 A1 C+ v' X1 o0 q% |3 Q
//*///
! b4 Y$ Z/ Z7 s+ _) G6 h+ w}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
% H: N2 s; h9 e( [{$ Z: `, t# h( `( w
// TODO: Add your message handler code here and/or call default
; W# R3 Q# ~- |) o9 H" f if( m_bIsMouseMove == 0 )+ h( u2 q" m9 a
{
% `8 ^0 o! V+ \% \0 v  m_bIsMouseMove = 1;
  T3 T: s& ~( ~8 o* V: l; F  Invalidate();& v# q3 g# u7 D7 q- t8 f" x
    d( w; H9 s; y, N$ ]$ L
  TRACKMOUSEEVENT trackmouseevent;
! s2 k( [; n# k9 p7 V/ a6 Q8 [  trackmouseevent.cbSize = sizeof(trackmouseevent);
+ [4 I1 X( T; [, Y7 f& D- I: C' D) }6 H  trackmouseevent.dwFlags = TME_LEAVE;
$ a: `; i6 q, H8 F  trackmouseevent.hwndTrack = GetSafeHwnd();7 Y& e7 Y& q  I0 `4 T$ w5 l" d
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
  f1 s  @8 o0 d, d# V  _TrackMouseEvent(&trackmouseevent);
, n3 G5 }) V4 k) f }
" z! @  K- V& y 7 d9 U2 I' p$ f3 ^' P! a: p
CButton::OnMouseMove(nFlags, point);" ~. i0 Y& o/ e) L9 J' Q
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
, [9 o  Z; }7 \9 E% J{
9 G+ C% i0 m/ w* C m_bIsMouseMove = 0;, ^) J' Y. ?9 c7 o4 v" _4 L
Invalidate();
return 0;1 H3 k; j) ~  V+ z: ]
}
void CHsPMEButton::PreSubclassWindow() * c; v9 i, t1 P3 ^
{
! m! {& W5 n7 |% G, B) Z& r7 C9 q // TODO: Add your specialized code here and/or call the base class0 h- q! a* n9 ]. }4 J
UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
- ^! t1 A+ H- L+ y% t SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();$ @) Q& ^; ?* i
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC); ^, |- ^/ N3 n& @1 j2 C
{+ @- R2 X, w7 X& ?# C0 d0 E7 T
CPen Pen;2 f6 d# y" p6 p! h! a  L
CPen* pOldPen = pDC->SelectObject(&Pen);& l, C8 ^$ J/ [8 G; g- t; u

; z! T/ Q9 r) S2 C int R, G, B;" L' A1 a+ u: @- j5 k0 @
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
0 T6 ?: R$ p- d( x* t G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
& [+ D/ s* }. }% j7 [6 D B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
0 f4 s9 w3 p5 y8 z, T/ B7 T # t# `, _3 l% O9 u
//R = R>0 ? R : -R;
* A$ ^8 L. F9 L2 O; k' u //G = G>0 ? G : -G;( U4 Y6 I* t( y. n
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);$ S0 D  _% K& d8 S0 f
COLORREF ColMax = Top > Bottom ? Top : Bottom;
+ ^' N+ Q6 ?5 Q COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)1 t) c5 r, `' _
{$ k6 Y$ X8 D9 }- w% \8 z
  ColR -= R;
5 D" y; t% o( X! I9 R& U0 q  ColG -= G;
# n" v( }/ q& q1 e7 u" C- Y  ColB -= B;
  /** ]/ L6 L9 k! c* v7 m6 r
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
2 O& w4 X0 p7 w, L! I6 W3 d' n   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||9 a& O1 p" r$ a/ p8 p* u/ v
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )% l/ ]# `2 t: ~+ U8 h
  {1 x3 C9 D$ U/ T4 x
   R = G = B = 0;
) h" g. _. ~  p* j$ k! [  }///*/

( [; \# g: J3 n; d  Pen.DeleteObject();- G# ]- e2 r6 M# ]
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
, S# Z  `9 a" |+ @$ k% V    $ u' o* R+ u- p& V
  pDC->SelectObject(&Pen);' e. ], A0 y$ P- Z# N
  & x% v5 M( {, n+ ]
  pDC->MoveTo(rc.left, rc.top+i);  F. `0 p3 {* ]; r& v2 P
  pDC->LineTo(rc.right, rc.top+i);/ r5 C* y" S3 ^2 d! d" C5 z
}
pDC->SelectObject(pOldPen);0 j2 V9 r) c+ p, D6 K6 `
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)- _; C: L" R- p4 A
{  y% v+ y$ E( f
CBrush NullBrush;
) J: R* ^8 X9 o$ {& Y NullBrush.CreateStockObject(NULL_BRUSH);
6 _: c9 b8 M! b; k& Y CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;6 @" P% h1 ?6 R4 k
Pen.CreatePen(PS_SOLID, 1, FrameColor);
. s* N; r; n& N CPen* pOldPen = pDC->SelectObject(&Pen);; e  K" ]- J; {$ z' \% @$ K
3 o& ^5 A8 N) y
pDC->RoundRect(rc, CPoint(3, 3));
" R3 v) i( ], W6 K: j! q3 N4 a rc.DeflateRect(1, 1, 1, 1);
( X8 c/ Q+ l2 a pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
7 [% E1 J. E; t# J" h# G pDC->SelectObject(pOldBrush);
, p) f% K; [# T1 D; s}

- E9 H7 D3 [. t% [& R$ S; A! D4 W/////////////////////////////////////////////////////////////////////////////
) r, z$ @) Q$ B$ }& Q, R9 {* d& t// CHsPMEDialog dialog
) P  J5 S% b7 ~+ `9 A; A//-----------------------------------------------------------------------------
+ K! X1 s  s" X: A2 ]. @9 [1 L1 f// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
1 h/ B0 l4 d' J  \/ w  ?//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
) g4 z/ \) `1 c# U5 `//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口) _3 ]2 t! |$ \3 q- Y
//   指针将其显示出来,然后隐藏或销毁自身
: y: o/ z" n' ^/ R) Q//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
1 E4 j0 b* g* g2 s+ S' l//    采用的方法为使用上面的CHsPMEButton作为按钮的基类" `2 R- P; v2 H4 V8 C0 y! c
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
; Y; J7 i7 v2 L$ |  M% K//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
* n7 m7 \1 {# x//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
2 g( t) m& [2 f' i//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
2 b. ^0 U1 K/ Y2 C! k7 C//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。2 i( _  c' I, H/ h
//-----------------------------------------------------------------------------% v9 u& }; v: {
// 注意:
9 o$ o, m+ F$ b  G. Z- |6 `// 1、在构造对话框时必须给出其父窗口指针
+ Y' O/ f, F7 j// 2、在初始化基类时必须指定对话框资源模板ID
. U0 W# j  [. h; z4 |// 3、对话框资源中必须提供ID为IDC_BACK的按钮
7 `# M# [- J% F. l% k' d  ~// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
0 S; [) C0 ?% {( |//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
) y" M7 v+ H' d0 b{8 N; k( ]0 z4 \5 Z* ]! w
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
  r$ w4 _; g0 v, p6 I) n// Construction
0 V) M! Y0 e+ a5 l8 j2 tpublic:/ s1 F- U. B5 z: p  R; l
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor2 I( q( M9 }3 J/ O1 Q4 s4 _/ ^
~CHsPMEDialog();$ N; E- d/ f6 _% o9 O( [
BOOL Create(CWnd *pParent = NULL);$ X' ~" F1 X/ ]+ t  Z
( [# [+ Z5 c( \+ U
// Dialog Data
4 T' z# j% F. M. e* B5 U5 ^" w //{{AFX_DATA(CHsPMEDialog)# [0 `0 C( D$ M; d; g
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };
4 B. A2 D. e+ d/ T9 d# p  // NOTE: the ClassWizard will add data members here& ^$ W1 [: r0 z! @+ |
//}}AFX_DATA
5 r5 F: ?2 ~' G" N( V
// Overrides8 Z7 f9 ?% S$ n
// ClassWizard generated virtual function overrides4 R5 y3 a" f9 p: i3 c
//{{AFX_VIRTUAL(CHsPMEDialog)4 B  J/ N9 C5 Q" V1 X- @
protected:- P  g8 K* B. O; W6 e# p
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
, k1 Y$ V2 ~2 [  Q, U virtual void OnOK();& S$ E8 X5 z4 R
virtual void OnCancel();9 S: ~7 S: W3 V( s
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);# z4 f' q# y' H
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);0 l1 E/ r/ o5 e# w
//}}AFX_VIRTUAL
// Implementation
8 Z; x% y# F+ q& N/ @5 Uprotected:
// Generated message map functions- m# f6 W4 E) ?: C
//{{AFX_MSG(CHsPMEDialog)
0 p9 x8 w( e. a7 Z- ~ afx_msg void OnBack();& L2 U0 K, P0 K
virtual BOOL OnInitDialog();
& f! Y+ s' H% M8 S8 G afx_msg void OnDestroy();
# v$ a! r' w- N9 D! t4 T) w( \) ] //}}AFX_MSG" k6 u' U, K4 P
DECLARE_MESSAGE_MAP()
protected:
' g! S' e5 q( d1 ^ // attributes9 x( z) }/ l+ B
CWnd   *m_pParent;     // 父窗口指针
; r5 Y& Q* X) P; {: ]) g HICON   m_hIcon;     // 图标% r! |% B' V5 w+ q# z3 j! U
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;3 {) w: L3 d5 \. ?3 x* b( P+ X
CHsPMEButton m_btCancel;
( W1 L$ R' }- s! c; c, P CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄" x% j  T* N& G; r- X. A" z' q
HHOOK   m_hkCBT;     // CBT钩子句柄) z5 k/ r- T  |" G- p1 x
4 O8 q+ a: O* `1 Z/ x
//-------------------------------------------------------------------------/ ~; U, U: ]0 J+ B  S
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog: {" b, [6 l/ O  Z4 z
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为; {- T6 g' H5 n2 t* ^- Z: W8 {5 V6 x: c
// 链表的头及下一个结点的指针
7 w' U3 ?7 ]& ~! `2 W+ x5 G8 [ static CHsPMEDialog* m_spHead;& t* U7 Q+ ^+ |, U) ~) G6 z
CHsPMEDialog *m_pNext;
// operations6 G+ S. Y& o0 t' X" D7 r8 h" j
// 键盘钩子消息的处理函数" ?2 V% f1 A/ D+ j* e
static LRESULT CALLBACK KeyboardProc(
' o. B( S, J& ?- b# T  int code,       // hook code5 \2 _" u# x) J/ U
  WPARAM wParam,  // virtual-key code- t6 ?8 _( O; \) a0 ]0 n1 d
  LPARAM lParam   // keystroke-message information0 g+ t' _1 }- Y! W! w  D8 z# m2 f- i
  );8 Q8 q0 U* T- u% t* m
// CBT钩子消息处理函数
, y5 X8 x1 o1 C static LRESULT CALLBACK CBTProc(
6 b5 b. Y; D7 c4 I8 v) [0 L* c! W  int nCode,      // hook code
9 ^: z. _3 }; k  WPARAM wParam,  // depends on hook code
9 Z$ P2 N) @1 f; P% D; Q  _8 g1 R$ P  LPARAM lParam   // depends on hook code5 r7 ^. q1 @& P5 |+ ~) \# m
  );
% B; k$ L* U" s' Z. b
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
5 }, [$ c9 W* {9 I& J( @ static BOOL  IsWndKindOfThis(HWND hWnd);
8 q! d- o8 }. d! g // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)* @' G3 _0 I+ C1 ~7 `
static HMODULE ModuleFromAddress(PVOID pv);
! I1 `$ x  \9 M' d8 S) {public:( z, s' X! `0 o( w
// attributes
// operations; v  H: w' P6 `0 W; Q8 R) d7 p
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框; Y* `" H9 J+ Q4 M0 ~5 |1 r: K
BOOL CreateChildDialog(CHsPMEDialog *pChild);: Z3 B" i! W/ H* I  e+ v' e; v" x
};
; m6 |( m% Q( e- Q% p# a
CHsPMEDialog* g_pHsPMEDlg = NULL;9 q# v5 f2 Y5 ~  a' Z, E
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;3 W/ D, ~8 u* F' D: j9 r
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)) g0 ]; s! n! W: j: x  `: m
: CDialog(nIDTemplate, pParent)
) w) J9 z. J* n( q2 i{1 o9 `6 M! J, K2 c% U7 z0 E
//{{AFX_DATA_INIT(CHsPMEDialog)
+ v7 t) o, m, Q  // NOTE: the ClassWizard will add member initialization here
- m& D' W" i7 E  d7 |$ ] //}}AFX_DATA_INIT
3 x7 E' ]1 j7 W- v$ D% a0 b, h m_pParent = pParent;
' ^- P0 ~  ?- |' | m_nTemplateID = nIDTemplate;
7 ], v& [% u# [3 i/ g4 C5 w m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表5 \: ?4 I6 q* T
m_pNext = m_spHead;2 R, t! a% i" w  m
m_spHead = this;7 Y4 P  v  f6 \4 G( Y" O  \% p
m_hkCBT = NULL;2 u) F: N3 w5 V6 }9 w+ x- h4 u9 Y0 a0 i
}
CHsPMEDialog::~CHsPMEDialog()
: _. z5 P; @- l' R( G8 E{
8 w' D9 c5 c, n& a // 从链表中删除本结点
3 s1 ?& f) m6 d: m) a" S2 M# G; P& | CHsPMEDialog *pTemp = m_spHead;
$ S$ |2 k3 \1 j( Q8 @ if(pTemp == this)
4 Q0 g3 U0 x7 H/ p! `8 g {
0 \0 H+ S$ q# F7 f8 B1 K  m_spHead = pTemp->m_pNext;
) b/ p, X  T8 ~2 X1 L( U }+ N: q; }& d* t* X# ^* g( _. S
else
9 I: k% c1 i* W9 f! S/ e {
$ e$ e2 Z0 {6 x" m) V" |8 R' q  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
7 ]3 s; u* u/ H2 F- u  g% `  {
% K8 _* y7 j1 M. a* p   if(pTemp->m_pNext == this)
$ f: C2 B5 z' C! }   {6 V& Z- o( m) K$ }  K, C. J
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;8 B7 p4 W9 i( ]9 M# F3 f) y
    break;
0 w! V6 y! B; @4 v. {$ V# m# G   }$ Y. ?# W# |2 Y0 p6 l
  }0 f3 y& m# O( \( v1 t3 f. a* t# n+ F
}" v5 `8 }; K% H9 U4 ^
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
$ k# W' \/ M. c  v# Z5 ~, |( R{
# G/ \! M" D  V) E, k CDialog::DoDataExchange(pDX);- e- {$ c. T; x* d! d( M
//{{AFX_DATA_MAP(CHsPMEDialog)
5 I, Y1 h  e3 n% _: t7 g DDX_Control(pDX, IDOK, m_btOK);
$ p8 {4 q1 f1 N; Y, c DDX_Control(pDX, IDCANCEL, m_btCancel);
/ R- O3 z" q$ o7 J0 V0 ] DDX_Control(pDX, IDC_BACK, m_btBack);" ^# K7 |; R# K3 B! k
//}}AFX_DATA_MAP6 E3 d, |0 l- I; `
}

& ^. a# Z9 a5 s- b( `7 a! W4 b4 UBEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
8 S7 L' z2 F# b //{{AFX_MSG_MAP(CHsPMEDialog)
/ r8 E+ S5 t2 o' g6 \( r; L, Z ON_BN_CLICKED(IDC_BACK, OnBack)
5 q/ P0 D+ U9 Z% @& p1 ?5 h ON_WM_DESTROY()/ V! `0 N" O0 H  V
//}}AFX_MSG_MAP
6 u/ c# a) E0 I  D+ oEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
9 H& p* j; N! s. l! k- F// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
2 A4 k) Y) Q( w. Q6 D{
! f0 f1 J+ m2 h& b" Q9 h4 v) w m_pParent = pParent;- ~( G8 u  s6 f% j# S
return CDialog::Create(m_nTemplateID, pParent);: I, n8 v- p2 @
}

- u+ H+ n; y5 }3 h/ hBOOL CHsPMEDialog::OnInitDialog()
$ d) G& [2 d. ]2 p( q. p{, Q1 u4 @/ p3 ~
CDialog::OnInitDialog();
// 设置标题栏图标
7 h  Y, E3 g, l" [1 e2 S SetIcon(m_hIcon, TRUE);- K4 B  G2 f) @& x; l- v$ N: W& }7 {
SetIcon(m_hIcon, FALSE);$ S) Y7 R0 W% p, R$ `9 {2 x

! f+ Y0 @3 _. m$ y4 O5 q, I // UG的对话框的几个标准按钮没有TAPSTOP; g6 Q) N5 [' A) \/ {" n; q
CWnd *pWnd = NULL;* Q' t6 M& m, \; ~# X7 e5 ^7 L; M
pWnd = GetDlgItem(IDOK);9 j- L, l* O" a( ]& M# {# d# [* U
if(pWnd)
' H# ^* `/ o& W0 H$ E7 R {
& k3 X- \0 b" D' Z! N6 J6 M  pWnd->ModifyStyle(WS_TABSTOP, 0);( W0 r4 `7 s- X$ S: T  U
}
* P! D; _/ |( G8 i/ U pWnd = GetDlgItem(IDC_BACK);5 p" ^" y7 n: D, G# h) N  F
if(pWnd)
. O+ c. g! m7 H {5 w* O4 t% r. F
  pWnd->ModifyStyle(WS_TABSTOP, 0);; q& T" k: m, X. C8 ]
}
6 d+ Z- a: Y. S% X" Q& y pWnd = GetDlgItem(IDCANCEL);7 @' h/ _" P) H& U. h
if(pWnd)
6 ^$ b, Z7 j2 c  f( B0 x {
$ G6 ?0 p" A$ O# N* o, N  s+ u$ T  pWnd->ModifyStyle(WS_TABSTOP, 0);
: r- ^8 a7 e3 Q! o: A9 x) r- N }
. B3 ?3 ?' M. }4 v4 c
( o* X0 S; R, d* \4 Q: B! c2 y g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子5 ~, |9 |+ k! X
if(m_hkKeyboard == NULL)" }# t" N; n5 h% j; a
{  T0 F! P6 t# e7 W8 j
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
, n' Z( ?" A% X3 Z }
9 }+ R, @- A$ i, W if(m_hkKeyboard == NULL)
. L- |9 ]& E9 V0 g; B8 y3 O- b# j6 x {' Z) u9 w- ?* w
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());
: d5 y8 {' s' i5 O8 d9 X) l }
if(m_hkCBT == NULL)
. D5 v- ^% _( c) T {
; C/ M* Z: q" m. t  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());1 Y3 g- q% F4 g  d
}
% d* f) B$ v7 D' c) C. q+ i6 `. x if(m_hkCBT == NULL)
/ z' b' U2 l9 t% S' U1 N {$ Z% O; {. u3 ^) L
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());
. c4 X: A; Q7 h; g }
4 U$ H; L$ l+ F' I3 w0 }  V- v! l
4 C! H2 X( }6 w return TRUE;  // return TRUE unless you set the focus to a control* v- c! Y' M, ?# o4 P$ |0 ^
               // EXCEPTION: OCX Property Pages should return FALSE
/ j2 n+ i$ `' _}
void CHsPMEDialog::OnOK()
9 r! F5 N6 d1 b" D. [% E" s{# _) d$ k- p6 E! @0 l1 S8 P5 D
CDialog::OnOK();. k' ?& D$ E: d  ]3 x8 W* u
if(m_pParent)
7 L6 k/ S% j2 n8 l9 K! z {! b# y, r" x1 l; y7 v
  //m_pParent->DestroyWindow();; X( }8 Z( v9 P8 M
  //((CDialog*)m_pParent)->EndDialog(IDOK);/ \) N9 P5 T3 l4 k- n+ ?' P
  ((CHsPMEDialog*)m_pParent)->OnOK();
! a  x) ?7 ~7 A1 Y7 C }
! c  ]5 P3 K6 N% I8 H}
void CHsPMEDialog::OnCancel(); `6 `8 a+ K: M* G
{5 h, K" u& J8 s  p; c
CDialog::OnCancel();3 k( @) z1 C' q8 `
if(m_pParent)
* d$ ^5 B6 a- g" V$ o* V4 d. u {
/ i% ]5 h+ {8 {" x% P( t  //m_pParent->DestroyWindow();
' L+ u4 P" G3 F1 b+ |/ h/ o  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
" S3 T/ A+ U0 G  S  ((CHsPMEDialog*)m_pParent)->OnCancel();. @  I! ]) S& s
}4 R1 }" ^* e* X8 w# _: X% |
}
void CHsPMEDialog::OnBack()
7 ~$ Z4 h" h5 \# {: ~' [# \{
. P# Q6 P  S: O$ H2 L if(m_pParent)% M2 H. b  q9 I! w( M/ J
{
9 D8 ]: P! T8 {, f( j  m_pParent->ShowWindow(SW_SHOW);
/ Z- K# e! e3 A+ b# ]- y, U }+ ^& y  r) c& k
CDialog::OnCancel();
8 L- |  P$ y6 J/ s. C' s9 G}

% q$ G  F, ?, P( R- v2 Y9 `6 MBOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)0 f( n: e7 Z% N! a, d. j) S2 B1 ?1 I
{/ _9 }% o0 M4 F" D1 I& `* t/ J3 S
BOOL bRet = FALSE;7 \% {8 S2 D0 Q+ g
if(pChild->GetSafeHwnd() == NULL)  d; A5 s1 s! ]1 c6 r
{
% Z0 H5 H8 q  P  bRet = pChild->Create(this);$ R# E9 E9 u3 \. m9 o$ e
}" C5 w2 r+ M" @( E8 _# s
bRet &= ShowWindow(SW_HIDE);
8 p  V) X( l) W" b bRet &= pChild->ShowWindow(SW_SHOW);9 m2 B2 {* R$ C" @- ]# _
return bRet;) o  W3 m, c3 o: W1 m# i( t- R
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
2 Y  U' ~* }( |{
; O! j7 P/ r( e) C! I, U" r: h( t0 { if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup6 N- k8 ~5 g% O
{
; P9 J# v; U$ b$ M  P& S* Z) y! ?  //TRACE("Key down/n");
9 O9 m! C2 e) T- l# l$ p8 ~2 V+ a  CWnd *pTopWnd = CWnd::GetActiveWindow();
2 T; w3 G4 H8 b  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))' @& w& b( Y7 k+ D+ b0 t6 p
  {
) T6 W3 }1 D. \; c9 D! b$ E   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息+ l5 P' p" k" y4 D2 B
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)
3 q* G4 a& {5 t8 a, X' ?   {
$ w; x* V: h7 U    // 只截获tab、esc及回车键
& V; V9 O# T& h1 ]# H. e6 \/ J    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
5 u; j" ~2 f' r2 C8 }. o2 [7 k/ Y    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);5 Y' d5 u. `3 N9 x+ h
   }+ F) `8 C% w( T& c% B+ U- @  m2 m
   switch(wParam) {
2 \" k0 J4 g- W" o) O; t1 R   case VK_TAB:
$ c: x' e* W! \3 i# x    {* P% x6 c+ R" \5 ?9 a; U
     CWnd *pWnd = pTopWnd->GetFocus();9 I& `% ]) \3 n  u
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
7 z8 m3 \3 v  M     if(pNext)
# K0 n. ^0 g. H% _     {
# M1 M' p, {8 K$ H/ [4 o- s  N      int nCtrlID = pNext->GetDlgCtrlID();2 n  H& C  U" ^) |
      //TRACE("CtrlID = %d/n", nCtrlID);
: R; R9 y  D% c5 @      pWnd = pNext;
5 C# H8 D9 s5 T      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)- d* e. R& s% m/ F2 X7 j+ |6 y
      {2 v6 ^+ J+ P9 e# M6 n8 Z$ @( J
       // 根据UG对话框的属性,这三个按钮是没有焦点的
; ~1 \9 R4 y/ a1 F       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);& d9 i' L+ Z* Y0 t+ y
       if(!pNext || pNext == pWnd)0 ~/ |3 L# X9 c& [
       {
7 X' d- f& s, P8 s        // 对话框上只有上述三个按钮5 Q6 w% q7 t0 D- b
        return CallNextHookEx(NULL, code, wParam, lParam);6 Z- T: m7 `( k) Y1 q6 u. a
       }4 R! f$ Z6 m$ g6 G$ \: k
       nCtrlID = pNext->GetDlgCtrlID();
% g  b: u9 X, A       //TRACE("CtrlID = %d/n", nCtrlID);! Q' r0 t  _* w+ V! H, v6 v6 Y, G
      }# ~; q1 ^7 V1 h6 {: V
      pNext->SetFocus();
( r- X7 H+ Z; J' W2 E     }6 i$ w" g5 D0 |0 d
     //return TRUE;
) P# ]9 v* _. M) P% b0 y/ M    }; q7 U5 k( i* w1 r0 H. d2 E
    break;
: h- G6 w/ t5 `  b/ S% l3 n   case VK_ESCAPE:
$ A6 [; M" G* j' z: j4 E7 t: i7 S4 X    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);8 d3 e0 ?6 A/ V- P8 F
    //return TRUE;
: E' u& B) l' r9 H" x    break;. e4 v9 _8 M) H  X+ L. H$ b
   case VK_RETURN:
# |) [, V. e1 T3 z3 g5 i, M    // UG实际上并不处理回车键6 ~- K# D. K1 l/ p- y( A
    break;, m. T6 p* |5 Z$ q5 R! d
   default:
+ k! g$ ^1 R  [8 v    break;, T, A) B! X1 s& f
   }
+ l( R5 o: r% J9 q& S" N1 j+ c. v  }& p# D7 v7 H; `, A9 y
}
4 p/ t7 E4 Z; y7 k& K6 F0 f return CallNextHookEx(NULL, code, wParam, lParam);/ U9 N& h6 ]- S* l: Z# S) t, K
}
void CHsPMEDialog::OnDestroy()
& X! o& k5 P/ {/ O0 E8 P# C{
- `8 T/ j4 ^0 J( \8 n CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
; V& T! q9 x- t: J9 b7 j" } if(m_hkKeyboard)' o  u  N1 i) e" C3 M7 c! I2 Q
{  s# k" a/ O* @3 ~
  UnhookWindowsHookEx(m_hkKeyboard);
: |# o7 d: @5 B# V$ P9 L  m_hkKeyboard = NULL;# B" a& E+ W1 G! c
}
if(m_hkCBT)
* @- h3 `' P! T5 g1 m {
  Z0 {- @) L0 I+ O6 z  i5 t  UnhookWindowsHookEx(m_hkCBT);
  ^$ A# ^( K& P4 R  m_hkCBT = NULL;) S/ Y; f2 W0 N, ]3 E% K& U
}
$ H) ~. D& u3 S  C}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
) C, I: Q8 ?( v7 ]8 _4 f2 ~; N! T{0 J2 T* v1 H% D; g( F
CHsPMEDialog *pTemp = m_spHead;
0 \4 b$ u$ e5 g7 P  | BOOL bFound = FALSE;
) ?+ o+ e+ }9 f0 x4 T9 ~* p1 ^ for(; pTemp != NULL; pTemp = pTemp->m_pNext)$ j- ?( ^0 J$ q+ K
{2 g- }( [# t3 N# u+ D: C% m2 F
  if(pTemp->m_hWnd == hWnd)" U& Z4 d3 f; j& d- V
  {
" x& m+ u8 M+ {1 z+ Z% q3 X$ Y   bFound = TRUE;% v0 @9 r. m9 W. ?' U: |+ X+ t
   break;1 W$ Z. _0 `- v. g2 S0 {# b
  }% x5 k2 F) p. z3 }- S
}  M; Z1 Q) D; Z8 K
return bFound;5 ^5 J# P) }& a* X9 u3 U
}
// Returns the HMODULE that contains the specified memory address
# l; y& f- j9 ^2 b" AHMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv) 9 [1 v% \- K! w0 L' _; z3 N, E
{- u4 u7 @8 g8 F& R% \9 u3 Q8 A
/ ^( @/ f5 T& m4 P2 I6 z$ j; K4 ~
MEMORY_BASIC_INFORMATION mbi;
* U2 x, C+ K' g% f* b7 Q3 B- {# |4 m return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) " i: u$ _# C. v: o
  ? (HMODULE) mbi.AllocationBase : NULL);
; r5 ]& H! H" @6 a  H" o* e}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
5 X9 z2 X8 E1 @4 m{
/ @. u9 f5 {! K+ B if(nCode == HCBT_CREATEWND)
2 C; F2 l( B/ ?3 h# I5 ^ {. ?. E/ o) S* ^' T$ t4 p
  //TRACE("A Window is being created/n");8 F* z9 I* }: E. ]# H( R( D/ x
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;8 e# k3 f7 A6 O: V' d
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
6 f, B+ @2 I9 z; K0 ^# A- m  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
' F! @/ N. S+ o0 m8 Q% D% h0 R  {/ k+ @9 i! j# K6 b; b8 p
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
/ }5 j3 A' U0 T% S5 ?8 z8 ~   // 取得窗口处理过程内存地址
* D+ C" D8 d' ~   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);# L/ I: }4 t: a
   if(dwUserData)% i; P4 U( C# K/ J& g
   {
# ^3 I( W& S# n9 o) D    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
* {4 J3 k6 m" g6 a, s7 y    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};' C$ t1 [1 N: K) k) M2 b1 H
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
- o/ k  n8 P% I' E/ Z    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);# \- D" z) M+ p. q* x5 E2 a: P
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
- ~: t5 y4 {2 \: S1 U$ M    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);9 U  x) [7 N' W- H
    if(stricmp(szUGPath, szModulePath) == 0)
! v( U  n1 c4 n    {7 m" _" R) a+ o: ?
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
) Z5 Y% Y# X2 }3 R/ [( a  u  `     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
5 b3 k# i5 g, e) W8 H     {+ U. Q/ b3 ?# x) V2 @. O/ u* l
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)+ D8 C7 j2 D# r
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
; ?5 Z$ S5 ?( j0 v1 [       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
% {2 q% G+ @9 ~% K8 _, v+ W      {
* j5 V4 F- S: ~1 K       // 窗口非本窗口或其子窗口! Z# g! v, F  W% {5 c
       g_pHsPMEDlg->OnCancel();
3 G8 y2 N0 w2 v, |4 p( a/ V      }6 ^  `' }6 v, a# R. J$ q4 ?' O; c
     }* a* G' A- c* Y+ Q9 N. h! j
    }
5 F7 I  w+ c  S* W5 R   }3 N8 o! }, Y& B' m
  }
; V5 U$ n9 H* {) \. z1 } }
# d/ p5 q5 h8 w! b) A) U return CallNextHookEx(NULL, nCode, wParam, lParam);
  J- s; q" @' V}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
$ s/ |) I$ c* F" U' v{
) h4 T& c5 y" E // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
, w( f! V/ e* W: k: A7 l& b2 K
7 y( `/ J8 V( Z' p7 ~ return CDialog::WindowProc(message, wParam, lParam);
8 e. `) U( m2 U) j: ]}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
4 @( h2 v  h% y$ Z0 A{) U" f' l! V3 X# i

& x: P# \8 A- U4 g3 w6 L return CDialog::DefWindowProc(message, wParam, lParam);6 Y; `, n( ~/ v0 }) u) ?! O/ ?
}

' E$ |) i, S. w% \: n
上海点团信息科技有限公司,承接UG NX,CATIA,CREO,Solidworks 等CAx软件,Teamcenter,3D Experience等PLM软件,工业4.0数字化软件的实施\二次开发\培训相关业务,详情QQ 939801026 Tel 18301858168 网址 www.diantuankj.com/ doTeam.tech
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 注册

返回列表 本版积分规则

  • 发布新帖

  • 在线客服

  • 微信

  • 客户端

  • 返回顶部

  • x
    温馨提示

    本网站(plmhome.com)为PLM之家工业软件学习官网站

    展示的视频材料全部免费,需要高清和特殊技术支持请联系 QQ: 939801026

    PLM之家NX CAM二次开发专题模块培训报名开始啦

    我知道了