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 2832 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------1 D/ z4 r: P% [7 Z+ \  D) `9 r
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
+ \/ }9 x) j3 M  ?5 O# }' W//    该类来自网络,稍作修改,版权归原作者所有
! t; @- V7 q' M6 F+ }, U//-----------------------------------------------------------------------------
) d, f. T3 s! V) y2 p* Nclass CHsPMEButton : public CButton
/ ^- ~" c% u9 B" \" `$ Z{
" S- j+ l5 v9 h% O5 M5 F; U! A // Construction% t9 l# g' x5 t3 W6 J# e7 U
public:
( M8 c9 K& j  D4 u5 E; z CHsPMEButton();# q* s; F$ s5 n% n7 s2 X+ y

; v7 E8 R% v% A% q1 w7 @+ z1 p // Attributes: P5 D+ o) e& X! x( }' n
public:
7 ?: X: H3 l4 u1 u
* ]+ k& l& y2 m% ]( z // Operations
, z9 r9 E% R. Hpublic:
* i! ~% B4 Y! U' ~0 N0 o( ^ inline void SetNormalTopColor(COLORREF color)* T, ~& A" P3 F" t: v" l
{$ S1 b4 _1 u6 B* f% z
  m_NormalColorTop = color;, ?' h/ K4 H3 n: R2 F2 ?; N/ n
}: T0 U' t( g& A' R8 B& Q
inline void SetNormalBottomColor(COLORREF color)
# P4 X( d' E- |# r2 z- d  a# ]: V9 S {3 k# {# a1 T& N
  m_NormalColorBottom = color;
7 z9 k: K; S- }0 d' Y) f2 \0 I. O }
5 I/ h1 d- J& I+ m7 G" ?4 A  Y) j; l inline void SetActiveTexTColor(COLORREF color)
# [1 i' R. x9 D' l" B% D {
% C" s9 o* f; _+ c' \- I1 i+ M0 E0 L  m_ActiveTextColor = color;
1 v! w; L, ~+ h, `  K/ C, Q$ P }% s$ |' F0 {: E, H
inline void SetNormalTextColor(COLORREF color)
; W: v* P/ b. x5 L1 ~ {
, S' Q* K1 o  P% u  ]  m_NormalTextColor = color;
  v; ~( N  k* x }
1 E; t, R! ?# I) O* _1 ? inline void SetSelectTextColor(COLORREF color)9 ^- H# _1 R( D+ L. y
{5 n- d2 G; ?" l/ O2 ~
  m_SelectTextColor = color;
0 c5 @. M% c6 e6 k1 p }( C' M0 r& x! F9 j- X
inline void SetFrameColor(COLORREF color)
; M6 n' d1 F0 X' M; E7 q- @ {7 N  z/ W2 ~! D- p
  m_FrameColor = color;* T* T; v' V9 K$ l5 N
}
" [) h' O7 x9 G. v4 B inline void SetActiveColor(COLORREF color)- K3 w# v; J* v3 z8 w% W
{
  j; h2 p* ~# A- |& X  m_ActiveColor = color;
  t) L2 C  a0 u$ ]; L }9 K  I1 k- I3 e
// Overrides1 g6 Y1 ]  y/ k% e
// ClassWizard generated virtual function overrides0 L9 g2 q9 k1 P# `$ F6 n% e
//{{AFX_VIRTUAL(CHsPMEButton)
7 i* a; X, y+ y( Iprotected:
) F" f& y' f9 ]3 b virtual void PreSubclassWindow();( Z/ u: U5 X" o. j9 m
//}}AFX_VIRTUAL
. c) Y" W- F: u8 P" H- [
. c; O, e. j( `. u5 n // Implementation8 [( ~5 t0 L) B9 J: o
public:* S7 ?3 }' H  q# Q+ p
virtual ~CHsPMEButton();" a: B3 h3 q6 e$ S

5 ~2 \2 V8 T2 e // Generated message map functions- _) F5 v0 \) N4 W
protected:
$ G- M3 J9 T2 C0 S0 V% J. M  n7 ` //{{AFX_MSG(CHsPMEButton)+ r7 O6 u* L8 f! b7 L) A+ K3 |
afx_msg void OnMouseMove(UINT nFlags, CPoint point);: H3 Z( Q0 L0 P3 S1 b3 U. I% C
//}}AFX_MSG
9 d- T: B# ~) K7 j. J9 m; n
" P# [2 P, p) A4 T void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);) f% n9 c$ [1 c
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
! V+ I$ R0 x: I) M void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
/ p$ [4 ]# k& r( w9 j LONG OnMouseLeave(WPARAM, LPARAM);  E: N9 J4 s" d
BOOL m_bIsMouseMove;7 q6 ~& o2 I- }5 B1 ?8 B& y

7 F/ h8 ~! n+ X2 @5 t* s" B) F COLORREF m_FrameColor;# Y$ O4 r- b9 v
COLORREF m_ActiveColor;/ k( z4 s. s2 ^$ H/ U4 w9 K

1 E& w& ]! N/ h( `9 T COLORREF m_ActiveTextColor;  O4 u0 S0 p2 b, {; B9 T" Y5 u; q
COLORREF m_NormalTextColor;
  z/ e7 n. m+ A COLORREF m_SelectTextColor;) |; e) j! F: k( Z

2 @! W2 ]7 N; L4 W8 i. m" s COLORREF m_FrameHeight;/ N! k: o/ g8 x3 r
COLORREF m_FrameShadow;
9 ?3 R& l, G* F , @' S$ ], r0 a% g/ t% n
COLORREF m_NormalColorTop;0 K2 I1 L1 z7 y2 k( l9 ?+ [8 b
COLORREF m_NormalColorBottom;
$ }* ?4 Q; L, x- K: S( j; k 6 G4 o0 N3 w1 ]0 I7 \
DECLARE_MESSAGE_MAP()
5 j( c/ @+ s) N; w9 G};
/////////////////////////////////////////////////////////////////////////////
3 s+ L3 r' O6 D- Z+ d2 {/ D! x// CHsPMEButton
CHsPMEButton::CHsPMEButton(): S- R+ J6 d- g# c
{
  G/ H3 _+ E' ` m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
/ t- F5 v: S3 X/ ^6 N* P5 M m_SelectTextColor = RGB(0, 0, 0);3 _; L% N$ L0 f! B- P0 E! S
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
2 W0 |2 C: G: D6 J& m" l# Q% r m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
: B, N, A5 [' ? m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);1 F( t2 ~& M  Q. W- e( g
m_FrameHeight  = RGB(230, 230, 230);; K/ g) y- w$ ?( r& k
m_FrameShadow  = RGB(128, 128, 128);; z) A& u4 G5 G2 t  ^$ e: u
}
CHsPMEButton::~CHsPMEButton()
5 p) q- ]" w1 B8 ~- A* f4 c{
7 C% d/ W+ W0 M+ R% P- Z}
- X7 h2 O9 e) d/ [' K  y
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton): _; ]  x' n7 l4 U4 x7 O5 i
//{{AFX_MSG_MAP(CHsPMEButton)
0 X5 w! V+ y2 }8 F9 C4 } ON_WM_MOUSEMOVE()
& t- `. H- ]( x1 U //}}AFX_MSG_MAP! Q+ ~* ^* _, j* T4 Y( B8 u
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)3 u! [& q) D3 }2 x" P
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
( [; Y: N: J! E( l" ^0 i  x% z// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )1 K! s0 f8 T' [* j7 l! f5 m( R
{
0 e: w% q$ y4 \& q$ B //*5 @& j0 Z3 F: U: n
CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
1 h' N( p7 i( r* K7 ` DWORD nState  = lpDrawItemStruct->itemState;
# H9 W  e2 ?1 ]8 ?. M DWORD nAction = lpDrawItemStruct->itemAction; * D6 `$ h- m0 ?+ I  o% J, m
CRect rc   = lpDrawItemStruct->rcItem;
! T$ z: f, ~5 E% U! E6 \ UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);* Q* a% A! {9 }# l
CString strText;$ n9 v' b. r, T3 k% j- R# v8 q
GetWindowText(strText);
if( nState & ODS_SELECTED )
) H& j% T0 J& @5 W {
" y, r) t1 D) @; m  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);$ L% u! {* Y* P" v" j* x$ E
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); + Q9 d; U8 I) M$ `; _& L9 Z
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
! P4 e4 I; ?$ X5 x }/ `. v# L4 `2 j9 ?. T2 `3 T
else //Normal! h. V  O- ~; \
{
5 K3 s1 V3 s* b  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
) @, M  ?3 f0 Q2 J  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
- v( u- v- F, u( z }
if( m_bIsMouseMove )
2 L) b- _  @6 t% C; L {
& q8 ~* R( h0 H  CRect rc2(rc);
+ D. q1 f; j* N' J7 \& k1 K, d* g  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),! V7 C2 [+ H6 @' V5 y7 j
   m_ActiveColor, rc, rc, pDC);% @7 i' N4 O% z7 c; q  [
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
0 ~/ w) A0 r- k% P9 H1 j  [  NullBrush.CreateStockObject(NULL_BRUSH);  q. f/ g) \8 F, M% x: Q& I' S$ q
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
- B1 v& r+ N- [0 G- H8 c4 ^  
. _6 V4 D8 N9 @- ~8 g, E  CPen Pen;
+ ~) ]+ _+ }1 h: |6 @( P7 i  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);7 f0 K8 {! x, W
  CPen* pOldPen = pDC->SelectObject(&Pen);! v4 m% K! @) ~" w1 \5 Z
  rc.InflateRect(1,1,1,1);9 N3 C- q. Y# q9 c" Q
  pDC->RoundRect(rc, CPoint(3, 3));
% H5 i: Q6 r: }, P, J: m% G" {  //rc.DeflateRect(1, 1, 1, 1);
2 Z( _9 ^& f( c/ S4 R  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
7 r( f, @0 z1 `/ Y  & c) F. b* o9 V7 ?
  pDC->SelectObject(pOldPen);
& P' F# t" }5 |- i" \  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
  x% n/ y& M. e& q2 I }" t' T8 J2 K1 b' o. s
+ |  o) `; s0 Y. s- V
pDC->DrawText(strText, strText.GetLength(),
* A. q* v# {+ g% Q  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);' y( {# [! n' l( e
//*///
+ I7 D, H, h/ l+ Q}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point) 3 l9 Y2 o2 s, f; {0 z
{( M% ~+ S3 Z$ G* R; L) E5 H6 m
// TODO: Add your message handler code here and/or call default
2 J3 Z/ }3 S! e1 K! B  c if( m_bIsMouseMove == 0 )
! D+ N& O- S, I% ^" ^ {; }; J# t( {- @, s
  m_bIsMouseMove = 1;# ]. v1 |/ s! d
  Invalidate();- B# S3 i8 \9 Y
  
5 ?& z" H! H$ y  TRACKMOUSEEVENT trackmouseevent;
/ E0 G4 y. o- M) B1 o) {0 r0 a# k; x+ |  trackmouseevent.cbSize = sizeof(trackmouseevent);4 g- v9 B2 x4 X
  trackmouseevent.dwFlags = TME_LEAVE;
$ m: _# J6 }* d/ }: F  trackmouseevent.hwndTrack = GetSafeHwnd();* `! k' ]. K5 {/ W: |8 b- l, s
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
5 \7 n% z; _# a% z/ T  _TrackMouseEvent(&trackmouseevent);8 X: Y/ y; e# S, e8 \
}
9 @) W; f8 q# D- S1 P! }$ s 8 V# `5 I4 M! z7 N
CButton::OnMouseMove(nFlags, point);# C/ ]# y  @0 n: R9 Z  B
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
9 X3 G5 \+ s  A5 {/ ]{
$ |+ k. Q! X5 c4 x m_bIsMouseMove = 0;+ P/ {( V6 y/ B# a
Invalidate();
return 0;
) `1 R% u7 R/ r# g; q* z}
void CHsPMEButton::PreSubclassWindow() ( N, f- W4 b. o4 D
{0 {! e' q$ s! K* F$ u
// TODO: Add your specialized code here and/or call the base class
1 p. Q8 B* B& j# [# z* L( h) ^# [ UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style6 x) M+ m- F% p) b
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
2 P$ X; @, W; j0 E3 ]}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
% u& D$ s% Q: o% e3 b  Y{8 O! ?# u- j6 @# N
CPen Pen;
- v$ I" F0 D9 { CPen* pOldPen = pDC->SelectObject(&Pen);
+ R0 v& t6 B2 m& e( O, J- y
4 l0 w; k' g. R2 A9 T' a( ~, | int R, G, B;+ m+ q/ q$ f. N1 ~
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();4 [7 w  b, w0 c7 ?
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
( f. z' j8 N7 D: b/ S B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
$ m+ U/ O+ s. a4 } 7 G  p9 \% T/ `" q
//R = R>0 ? R : -R;
! Z. i2 m2 l7 A+ y //G = G>0 ? G : -G;6 K) d, {( {) Q2 ]; E+ _. ]
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
5 Y8 w; F% K9 b- o$ T% Z COLORREF ColMax = Top > Bottom ? Top : Bottom;  D1 D. C; B2 N8 B- e
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)3 i9 V" [; ^4 \  T- t% s
{. d$ k. a( b2 ~% o
  ColR -= R;
" S6 O7 K: ?8 s/ N" ^  ColG -= G;
, I# ^6 v* G: M" q" J% d  ColB -= B;
  /*- D. h" b8 r  f) R8 V' M
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
+ E: b0 i" B: Q) l8 U1 |: K   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
5 T4 w0 t% w3 P   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
8 L) ?- n* M6 E; F* J7 z& X, \4 ^  {
, p. x7 ?# l, o/ r   R = G = B = 0;
( D8 ]- n$ W7 d3 }1 X) ~  }///*/
8 q: o# z1 s% h; E4 L
  Pen.DeleteObject();9 V% Z  b4 y/ m" [9 q
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
  I0 E" j: ~9 A0 m7 p; J+ ]   
5 a( l3 x* s' u4 {% W  f( r2 ?6 }  pDC->SelectObject(&Pen);
3 ~3 B3 J+ V: {5 M( I/ E  
2 h2 ?" u+ B" F8 n  pDC->MoveTo(rc.left, rc.top+i);
# L  J5 F  Q3 u  pDC->LineTo(rc.right, rc.top+i);, D8 r' I3 L* X* \1 m8 \
}
pDC->SelectObject(pOldPen);
) c$ G9 h; q" J}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
' k* Y3 m7 q; E; Y# g% V- S{/ O3 s5 Y, _, v* \+ F: n$ _" u& m8 @
CBrush NullBrush;
8 t+ L3 v7 p$ \8 v& N! J( ] NullBrush.CreateStockObject(NULL_BRUSH);; t! e1 v" Z3 D9 l9 T
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;0 {5 l1 e. L/ a0 O7 M7 \! [# |, E3 f
Pen.CreatePen(PS_SOLID, 1, FrameColor);
" ^$ {" u. T$ R9 \4 z: h$ F CPen* pOldPen = pDC->SelectObject(&Pen);
) p& \( \6 h9 Z2 H5 d" k
3 }. f1 h; u5 Q  e2 L0 o pDC->RoundRect(rc, CPoint(3, 3));
; |- i$ E( O8 z+ m' X rc.DeflateRect(1, 1, 1, 1);
$ F7 O6 ]5 `+ y' V+ o5 f pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
+ j$ c  I/ M3 s- v pDC->SelectObject(pOldBrush);
6 @1 V! y; [' r$ X6 P$ m}

2 x$ R, W4 ?; Y( F  t$ V/////////////////////////////////////////////////////////////////////////////% @& u8 c' L/ g. B7 a" e9 F) T
// CHsPMEDialog dialog! v3 A& x& C9 F$ s
//-----------------------------------------------------------------------------
; e# ~6 c/ w  A: v% G# o// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
6 M' K2 g  H" p( d7 O2 G, ~5 Y//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
! S1 n# D  q+ e" L. `% C/ A. X//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
6 r! k4 m' D6 H, W//   指针将其显示出来,然后隐藏或销毁自身6 W5 Q, o3 f, v$ S* |! z
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
! a5 s7 u3 }9 P; q- a) H/ V//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
# a3 ]7 w( N6 B9 e# H( ]  z//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,( \! s2 c7 n( ]! C# P% o$ w& q
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
; V) v+ P1 O. W% z//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。  s% m+ |0 o9 |; G, x
//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框3 `/ k- e# \# s. F" I+ Z% k
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。
8 k7 I- ?7 K5 h% P  }: C9 ]$ V//-----------------------------------------------------------------------------" Z- N( o, B' c' E6 v
// 注意:
& G, {/ k5 }/ {8 d// 1、在构造对话框时必须给出其父窗口指针8 L) P, Q+ ]  o. X# ?
// 2、在初始化基类时必须指定对话框资源模板ID
% j; o( w0 @+ A& m* `( E// 3、对话框资源中必须提供ID为IDC_BACK的按钮  ?4 m' j: E% V( d2 N7 i" c2 b
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel' w; h  z$ `, }1 @) z
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog, y) v7 E* _6 n- U7 [
{3 L: o: a: t: g$ w
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能  y: S! d# t  @+ S  j0 E. A1 J4 n
// Construction
* M* M1 |1 e5 @public:
4 A+ X, }+ W9 c" g" V2 U. H CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor' ^- y  C8 a. z
~CHsPMEDialog();, Z5 b# \- W- ]' C
BOOL Create(CWnd *pParent = NULL);
8 O& L. x! l$ n8 {7 q5 }; ]" s7 Z % z3 B+ [, I6 q+ O, Y- V2 f1 ?
// Dialog Data
$ Q# l! l3 {: ?4 G8 U, [9 h" Z //{{AFX_DATA(CHsPMEDialog)) d- h& ?3 j! R, d
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };
" l1 P* O( k1 L0 U3 u$ A. M7 H  // NOTE: the ClassWizard will add data members here( B7 @1 U4 E0 u# s$ T
//}}AFX_DATA

" c% ]( U% c/ P" N) Q// Overrides7 Y# _5 m1 F, l5 F0 Y
// ClassWizard generated virtual function overrides, H/ B6 m8 K4 a
//{{AFX_VIRTUAL(CHsPMEDialog)
  Y! s2 o8 l" W7 q  ~- | protected:
. }. s% v9 Y# o virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support6 s3 y* g: E  f' y$ W- c1 A
virtual void OnOK();3 @$ e( A1 Y3 }# p4 c
virtual void OnCancel();
, I- g4 D' v; V, z: k% q1 j$ F virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
" u# l9 g; _; x% i virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);- T: g. I3 o. s' b+ t& o
//}}AFX_VIRTUAL
// Implementation
  l+ O9 R' {9 C+ @; ^, G# Oprotected:
// Generated message map functions
, Q5 c- k& K3 B# G2 Y% a //{{AFX_MSG(CHsPMEDialog)
3 s0 T4 N$ c) G6 n* i0 e/ }9 m4 q afx_msg void OnBack();
7 C' u" O; e. E. L6 P virtual BOOL OnInitDialog();  D# ]( I3 \) ^7 F
afx_msg void OnDestroy();9 n+ }0 ?4 l: f( I8 R, R7 _
//}}AFX_MSG0 \3 ?# R* U: K! z7 q. @
DECLARE_MESSAGE_MAP()
protected:
/ ^6 t* W; Y3 a: A) o" S- `) a // attributes
% r$ M2 [  m0 }, N& }+ i CWnd   *m_pParent;     // 父窗口指针
# v& z# h  d8 J7 i! k# n, ?' K7 R: A HICON   m_hIcon;     // 图标8 I. r  o" w7 [& w# X0 q
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
' s  H% u5 Q; J: v CHsPMEButton m_btCancel;$ \5 X  O/ n, r; w
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
% f+ N$ @9 E) A HHOOK   m_hkCBT;     // CBT钩子句柄
6 ]6 j1 o  Z) z% G; ^7 ] / e8 n9 `) f/ _
//-------------------------------------------------------------------------6 {$ W1 [; c' h2 y  ^9 t
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog7 h5 d8 i4 N* E3 y7 N
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
) @0 I! {; i2 T+ L7 G' J // 链表的头及下一个结点的指针
9 i5 Z) U4 h0 G! ?% @! j static CHsPMEDialog* m_spHead;
& M% Y2 M4 o+ w1 j+ G CHsPMEDialog *m_pNext;
// operations
  z% f) x( M/ R2 A, V* O5 t" I# _ // 键盘钩子消息的处理函数6 F# `; m* }) ?& \9 Z1 j- _
static LRESULT CALLBACK KeyboardProc(, x( j: l$ B) q: q
  int code,       // hook code
+ g. t% e5 J8 O& D: e  WPARAM wParam,  // virtual-key code
; _; {- [/ V4 i( z8 Y5 n4 m  LPARAM lParam   // keystroke-message information
& k, P- x- ^8 `- o7 p! a  );+ r9 ^9 D+ T8 R3 ]
// CBT钩子消息处理函数* V) n, A- \4 ]+ x8 k1 O" z& }
static LRESULT CALLBACK CBTProc(- I8 S9 \5 T$ g/ S' n. s8 o, x
  int nCode,      // hook code
. Q; U4 y, g5 J6 X  WPARAM wParam,  // depends on hook code5 w% n$ l, o) ]& f( I5 s
  LPARAM lParam   // depends on hook code  ^" a: o- f' _0 r  Y0 _& D0 Q
  );) u' [# U0 O4 B% i: D
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口2 V3 n5 }* U  L. p
static BOOL  IsWndKindOfThis(HWND hWnd);
: J8 X# I" _3 j" p8 K& y // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)4 Q% v! S& T' Z% H) o3 p+ i
static HMODULE ModuleFromAddress(PVOID pv);2 a) r! ^! `! J( b+ M' }3 y- Q$ z
public:& v8 F( T- X+ p4 Q; T1 J
// attributes
// operations6 r# ?) [/ @" [# c! l
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框
, Z' M- r- I0 A BOOL CreateChildDialog(CHsPMEDialog *pChild);% D) d& `) m9 N0 t8 K
};

4 i4 @3 t0 P, _  a+ HCHsPMEDialog* g_pHsPMEDlg = NULL;
; d2 p8 t& f- K) _CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
' f- O# V! r  \  _% k5 {HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)# u) s. w3 Z- z" J" z
: CDialog(nIDTemplate, pParent)$ v7 V4 \  _$ `8 K: S
{
0 G4 y! R( w5 `0 C //{{AFX_DATA_INIT(CHsPMEDialog)1 W# s' i: T5 h% T
  // NOTE: the ClassWizard will add member initialization here
6 @. @6 x8 w' a9 p# m# l  @- h1 g" @ //}}AFX_DATA_INIT
- F" q7 e% b) n* y2 p" V' Q( r m_pParent = pParent;% ]3 v2 f, I0 ^6 y% l1 }) S' k3 C
m_nTemplateID = nIDTemplate;
2 H! i4 V5 A6 s. {) M3 r% s m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表. J6 W" x& X& e3 y" e1 A
m_pNext = m_spHead;7 ^7 U' \3 ~9 R- r0 j
m_spHead = this;
- ~$ @, V# _! |& C- u$ Z$ l8 w m_hkCBT = NULL;" l# E' l# F; c: C
}
CHsPMEDialog::~CHsPMEDialog()
: f8 |# C" _4 x1 I3 a& {( s8 P{: J& R# _" l* t" @
// 从链表中删除本结点! Z% x- X- L! ^* b: g6 K
CHsPMEDialog *pTemp = m_spHead;
3 ?) ^- |2 x! {* y9 r if(pTemp == this)1 x% d- C( y* ~; p: _4 Z
{5 q, I4 G; v; M" U
  m_spHead = pTemp->m_pNext;5 H% ^8 c8 G" i$ s; o
}
# x! E) {, U4 B7 c. l: W9 o else$ s( R+ F  D6 }7 N! E7 ]
{
6 J9 \/ C1 M0 e1 W" b4 |  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
! z4 C# L# e6 _, R2 q. {# {8 p  {
  ?( ?0 q% p# H# A   if(pTemp->m_pNext == this)2 h" B+ q3 U* g7 A& W
   {. e9 \% R8 g2 E2 B/ P
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
" x7 P8 c. U2 _# A5 B    break;% q, D) K- p. E# i# r
   }7 ^, L+ M1 M, A; z; c
  }' E: m$ _; O0 K. N9 h7 p4 ^
}4 L# l4 J2 ?; I
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
# L7 s5 t/ T8 x8 M$ R5 P{# a: G1 b# W7 S8 ~- c
CDialog::DoDataExchange(pDX);
# h2 k6 A$ N8 W% d //{{AFX_DATA_MAP(CHsPMEDialog)7 ]# Z/ \. s  S1 y
DDX_Control(pDX, IDOK, m_btOK);
4 _# C) j% B* Q& w8 g  S" S9 T$ b- g DDX_Control(pDX, IDCANCEL, m_btCancel);
# }# c0 i) w: K) k  M! L DDX_Control(pDX, IDC_BACK, m_btBack);" y  C8 R6 A# z1 v  l
//}}AFX_DATA_MAP
1 z  I1 `6 n9 v/ h}
3 ~5 X( u8 l6 t6 \# _1 l" E
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)0 p% g3 v2 b8 u; Y+ u
//{{AFX_MSG_MAP(CHsPMEDialog)
# q  Y* p7 }& e6 K* D ON_BN_CLICKED(IDC_BACK, OnBack)$ @& a$ y3 }7 z+ Y6 g9 y
ON_WM_DESTROY()
7 s! }; [. z2 A1 F/ w0 B //}}AFX_MSG_MAP$ y3 M) O4 I1 G/ k) f
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////4 g7 ^5 m+ J0 O* N6 J1 Q
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
( ^+ S2 t. S9 O6 w, y( [{7 D, z9 p' v- E) W: _: c
m_pParent = pParent;
+ m( x* B- P& S; m; _) _ return CDialog::Create(m_nTemplateID, pParent);$ w* a. y' W: h- \
}
+ l  ?8 _2 N9 X5 m3 c
BOOL CHsPMEDialog::OnInitDialog()
5 \" K5 j' |$ d  x1 |* W/ g' G{
* c+ W% J/ ]* x CDialog::OnInitDialog();
// 设置标题栏图标
' G2 o3 A8 @! C4 E7 N/ n  J: P SetIcon(m_hIcon, TRUE);
% i, Y/ H9 d9 j! I% i3 B SetIcon(m_hIcon, FALSE);# ^+ ]# }+ y8 h6 c
$ D! C: R+ v' X& N$ J( s. c+ \
// UG的对话框的几个标准按钮没有TAPSTOP
$ j/ N7 g0 C1 V* N0 s CWnd *pWnd = NULL;
3 b) G/ V3 ]% ?$ }& W% {4 ?' ^' \2 p pWnd = GetDlgItem(IDOK);# b5 G' f( C! a( f* x. Y
if(pWnd)
  T1 S! [% y- {. a( W% [ {/ e! x( R) F: f
  pWnd->ModifyStyle(WS_TABSTOP, 0);* Q5 h; p5 {9 W5 F- Z
}5 f. L' c' ?7 O( D& `& U, V
pWnd = GetDlgItem(IDC_BACK);
9 P3 R% p$ {7 c! u/ a" Y/ a, ~ if(pWnd)9 j; L* r3 C2 L, t( ~
{
9 _2 ^8 p; s4 X& }8 S* u9 @/ ]  pWnd->ModifyStyle(WS_TABSTOP, 0);/ G- y' L, j) r0 V; L& C
}6 c# v  n. S+ e$ s6 R# N! |
pWnd = GetDlgItem(IDCANCEL);
* y( b* }5 y2 N! u5 S* i* C if(pWnd)
0 q" f& _8 x* V0 J3 S# J" @$ k {
) d  N6 b7 ^/ P. V/ d  pWnd->ModifyStyle(WS_TABSTOP, 0);
3 Z4 P" |% f' I$ {: r }
& t2 o  b4 |# p9 ~9 s
: S* n1 c, u8 e( J) O( _7 M* T g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
# _2 _2 t' l" w$ a+ E$ e if(m_hkKeyboard == NULL)+ t( O3 `5 w% }4 a6 e* z" X8 D
{6 M- r" j6 C7 O" t% ?$ n
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
- T+ P$ J+ F1 c: o }: `$ i* B% Y8 o6 v
if(m_hkKeyboard == NULL)0 V) y, w3 z$ z& c1 G7 u3 w' |7 K% Y
{$ s% H; ?& _) N. |) u! C# B  Y
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());
% o3 j! z9 X# [+ R: w+ x }
if(m_hkCBT == NULL). i/ G: S& Q+ q7 q# v0 F: \
{! j8 V! A) |) J6 F0 [8 g9 H2 @: |
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
5 T+ F' x, `0 x! o }( e' J0 ]2 r) \& E
if(m_hkCBT == NULL)
& w1 W" n$ c$ k: X) J5 W8 C  V6 e; c- T {
4 J' D& r: [; J5 \" r# D8 P9 A; U  TRACE("Set CBT Hook Failed: %u/n", GetLastError());
( y/ o1 I+ S2 ], p* \5 c- \ }/ L* p+ f: _7 b- k# l* Q7 ~2 C

5 \5 b: L0 }' t3 T# U9 _2 C return TRUE;  // return TRUE unless you set the focus to a control7 j+ U* s) N% t) {/ N9 P# p/ A
               // EXCEPTION: OCX Property Pages should return FALSE- G  [, J1 F6 r3 l+ S
}
void CHsPMEDialog::OnOK()
; Q* U3 F7 [0 v% U7 c" R5 I{
( u, @! N/ u- M. ^8 } CDialog::OnOK();
" ?- ^" l4 G7 t( _- V. g- \0 \' X if(m_pParent)
2 X( s+ C+ x& e! W+ x" ` {, z5 N5 D* M1 X) U" n
  //m_pParent->DestroyWindow();
- p& ~$ Q. f  ~  //((CDialog*)m_pParent)->EndDialog(IDOK);
8 {4 B& a2 m6 e, d  ((CHsPMEDialog*)m_pParent)->OnOK();  H4 u( P% M! H& O- P
}
, b5 v: k' K- O9 M6 A}
void CHsPMEDialog::OnCancel()' m2 m; r7 a4 O! j# R
{
7 K- N+ ^$ t5 L, ] CDialog::OnCancel();
8 B* w% n' s$ |; i if(m_pParent). e% d+ @; _: {5 `
{, w& Z  N2 W$ c. \  g0 }8 ~! \
  //m_pParent->DestroyWindow();
% k7 {; o$ I  ]  r! r; Y  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
& E+ S6 Z7 ~$ b! M  ((CHsPMEDialog*)m_pParent)->OnCancel();
$ `( }) v, U; ~) q }# E8 X  @1 v7 S, T, J5 Y# V
}
void CHsPMEDialog::OnBack()
  H! R5 O  f  }! g. `{
) w1 U" _9 L0 s) w3 Y* G if(m_pParent)/ q. j& A( p* G
{
4 t/ y* g' U) ?9 B# `1 r$ w6 p  m_pParent->ShowWindow(SW_SHOW);  X; O4 Q# w" W' O( H# j% P
}: s; R) d, k* O
CDialog::OnCancel();- i- }3 H- h  Y! v% v0 ~
}
$ J1 w% F; v) Y  u2 p
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)- ^) ~; c' Y% L: @( c) j
{
% M0 ^0 S, b! A BOOL bRet = FALSE;
2 ?, U# b# p, s& ]7 C if(pChild->GetSafeHwnd() == NULL)+ U8 \, w/ F7 G
{
# O! a. \4 U  I  bRet = pChild->Create(this);/ ?* ^5 v0 I7 O# s  k
}. T) G9 h5 [- a% y- `
bRet &= ShowWindow(SW_HIDE);
6 @& D, x0 f* H bRet &= pChild->ShowWindow(SW_SHOW);
! ~) E1 Q( ]. N2 ~( D8 r+ U3 ` return bRet;4 }# X3 r. ~# J+ D
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)) H! O- l, [, R9 y1 m! A
{
5 l: y4 l# h3 K2 \+ V if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup2 s( L, t1 A0 U
{  ]# _6 s: P  T7 `
  //TRACE("Key down/n");9 X* B+ ~% r# A
  CWnd *pTopWnd = CWnd::GetActiveWindow();
0 X) F. F) a. S9 W2 W# d0 ~4 m  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
- M5 {! Q) M; x  {
) l; q. f, |. c% g5 I4 l   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息. A- d3 s) g3 u9 H
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)0 `# L" T( s4 h% O
   {
  m1 ~! Y1 k* j) w    // 只截获tab、esc及回车键  y: H, \* I+ k& s: @* f
    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
: d6 v2 W  \5 K) C    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);. Z* U6 l4 t5 y4 I9 q) |' L1 p
   }+ {7 B! D6 j/ {3 V6 S+ u
   switch(wParam) {
! h8 T, K0 I3 \% X- _) z+ U+ c   case VK_TAB:
0 j' Q+ G3 F) O    {$ L- Y4 u: D- E) m: J" V
     CWnd *pWnd = pTopWnd->GetFocus();% w. c; M, h; g$ a
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
( o3 \8 O. |8 {* }- U     if(pNext)
: `2 k- r8 z, C0 [$ r     {6 z7 T7 N' k# F: k3 ]* P$ G$ l
      int nCtrlID = pNext->GetDlgCtrlID();
% f: H) x. v* U2 {: }      //TRACE("CtrlID = %d/n", nCtrlID);! \4 k4 E+ k' ]: l
      pWnd = pNext;
( D/ _, s+ M) R* I      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
& |" e! e. x3 F6 |      {9 f$ |' G+ Z) Q9 n. K
       // 根据UG对话框的属性,这三个按钮是没有焦点的% a0 {4 T5 s4 _& }* r- l) H
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
( V9 n, J( \" N* M5 p5 ?5 H1 a       if(!pNext || pNext == pWnd)
" Y, `/ A0 @$ ]( w       {
+ Q& e3 [! I1 D6 V        // 对话框上只有上述三个按钮
1 q( p  ^& ^8 [. v) o, O        return CallNextHookEx(NULL, code, wParam, lParam);8 n5 N% }5 ~. N* h& P; j
       }
9 z" Z" i8 b( q& f9 P+ P7 Q       nCtrlID = pNext->GetDlgCtrlID();. p3 H+ E2 r3 ?1 V/ n
       //TRACE("CtrlID = %d/n", nCtrlID);+ K' ^, H$ c, R$ _; N; d
      }
, y  m! c! K+ g& o      pNext->SetFocus();
. ~% G' R4 [0 [" O     }7 e9 r) J( \% r9 a
     //return TRUE;6 _( o' e3 S4 Q# a
    }0 M" X* _. u7 y2 |  h! N
    break;
% Y9 e/ \2 a0 v2 e" U   case VK_ESCAPE:
8 c3 r- S: g3 N' U6 |! a" [: P. D    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
( @, @: F) p( |2 r) @/ z' n    //return TRUE;; @& I+ b) T. d, m! y" [, Y
    break;8 }! K7 G2 \6 d3 p# l
   case VK_RETURN:
( P& c! g7 I% M( \' `" e/ P& s3 ]    // UG实际上并不处理回车键
, @! S" T( \7 z  p# _- r$ T$ \    break;5 p: e4 o, f# ~# p8 D4 P3 Y* R  s
   default:- Z  q1 c1 T% g# l
    break;
$ @- R" d' N5 A& Q   }% g; T$ G" I2 H% X) x
  }! \" N  o  U8 n3 t" m
}) r' k9 I* c- {
return CallNextHookEx(NULL, code, wParam, lParam);
6 G  B" C6 j5 m# C}
void CHsPMEDialog::OnDestroy()
! R- A% P: t0 s0 ]& f+ h{
* g6 N- c. o$ [" k+ D3 J$ X CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
5 Y0 ]" ~, N& d2 x) ~ if(m_hkKeyboard)
$ Q7 j+ Z! b$ l* l {
2 F) V1 m+ F4 r& `' \  UnhookWindowsHookEx(m_hkKeyboard);
+ a( E! ]5 x9 [. H( U& k0 x  m_hkKeyboard = NULL;
- }$ q; ^1 o) P4 z+ `* K }
if(m_hkCBT)% i" p1 q# _/ x; `+ O% W
{  S' n  D) Z3 `% y; S, M5 _7 \
  UnhookWindowsHookEx(m_hkCBT);
$ H: Z$ `8 W! m% i  m_hkCBT = NULL;
% [( l" d+ T2 j6 \. f! P4 H! ~7 ~# ]5 p }7 a1 I7 K' c* ?
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
) _/ L  J* T  F# z{
$ a1 E! {3 O* H, S& x CHsPMEDialog *pTemp = m_spHead;* z' F( G4 Q  z7 \* o0 Z
BOOL bFound = FALSE;
4 ?% `7 q3 C2 V# S  X( K# C for(; pTemp != NULL; pTemp = pTemp->m_pNext)
# l$ U6 T. q* R+ X7 C% y {
2 x; u3 Q8 E$ H: U  if(pTemp->m_hWnd == hWnd)
% p) l0 Y- Y1 N) i+ c  {6 ~2 y9 O0 H; q- S: t
   bFound = TRUE;
2 I% n( @' `6 ?% U& i+ F: F+ v   break;( P# t8 ?" p% C% a4 j
  }
. y3 E2 q  {! x }
8 n# O$ [) C, m% R, k2 S5 u return bFound;1 W  _! O, t0 C6 |& C) B( v
}
// Returns the HMODULE that contains the specified memory address: g) v* V6 c. H: L4 w
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv) % r6 j/ _% I. w! B. q. L+ f; S4 n
{( F% s+ w+ O; P9 _0 t4 u

2 i# q2 m: r' Q MEMORY_BASIC_INFORMATION mbi;
! N& {/ q, x1 I  F5 d1 M0 I return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
7 |1 f/ ]1 @0 c+ }0 ^  ? (HMODULE) mbi.AllocationBase : NULL);- i6 L: f. J" K! ]" k+ l
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
# N6 O. Y) C7 H" h1 ]5 I  b{
+ q$ T+ d3 u2 R" _3 d) x if(nCode == HCBT_CREATEWND)
! q* U4 }2 u+ F# ^ {  [" D) h  A6 e
  //TRACE("A Window is being created/n");
/ E( A4 F4 S8 H2 Q0 d: ^( f- b  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;8 k0 z' D! Y9 g) D7 m. @
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
$ N. K$ ~" R. a  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
4 r3 F7 c& @, j' H# N9 B  {
2 l9 ]4 t/ j/ I% ]  X   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应; y; [6 y; X! n1 v5 _/ c
   // 取得窗口处理过程内存地址
6 h7 D5 y& {# c- Z; a) v5 a' c   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);+ k3 K4 h: z7 ~) c) T
   if(dwUserData)
: O& |- I0 Y) o! _  e3 v$ _   {
' T6 K4 I  J5 [; I    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
  U4 E( _2 N4 W7 `8 N0 \    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
7 I) Q  f: b1 i6 \/ E' V* r7 Y    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);5 O* U  b" U& ^) z4 j* M
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);3 S+ \3 n! }- B
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
. G7 m- C+ t+ C6 R4 L    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);, Z4 Y. [7 A" m$ g2 O; f
    if(stricmp(szUGPath, szModulePath) == 0)
3 V: f: V- z; h4 C    {
- I1 Y- t" D) v1 }     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
2 Y7 r; r" ~# U- f/ X' o! n     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)3 V, b5 o2 i' a* Q3 Y
     {
7 ?0 ~* h$ E% s. O; e      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)3 W$ n5 u# F: l0 U7 Q3 x
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && # v. g9 ~! [8 D9 Y
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
6 H( Q( s9 b6 \( [& A1 x) ^      {- q/ R5 m- j, N% N. T4 H
       // 窗口非本窗口或其子窗口
+ }, w' q3 L/ G* k       g_pHsPMEDlg->OnCancel();! \; P) ?6 m5 J/ t& \: T
      }; i: `  M# `6 t( B/ l$ R
     }
7 N/ ]2 P% W, g% G( _7 Y$ o    }
! \5 A! W0 [& }* n4 G$ J   }
6 q# c2 i: u' j+ X7 {, }5 ~- j0 ]6 a7 F( E  }# P' h0 g8 `: ?4 }$ q
}; p* Y/ S7 W/ L
return CallNextHookEx(NULL, nCode, wParam, lParam);  ~& I. F& e. g8 b  N; P# _+ F
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
9 I& D7 S1 V. D6 q{* A! o1 \, V) q8 @- ]! F
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来# n8 Y3 F( F# d% [0 h6 X
9 V/ Z+ o& n+ F" m; I' S
return CDialog::WindowProc(message, wParam, lParam);6 l9 {* S$ M  q8 T% c, n- r, u  s
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
# E: q5 `* b5 ?7 t+ a3 ?" ?4 T{
( k# c' l: E" C; M 0 }5 S& V% X2 S+ k' P. d* {  I
return CDialog::DefWindowProc(message, wParam, lParam);$ G) V# w( ]) n8 [
}

# o  I; q  C# A2 F, U$ B6 ^4 L
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了