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 3162 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
2 V1 J% [/ S3 D2 [& j6 O* Q// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类# V0 @2 u; o7 f; j2 z& B0 b0 \
//    该类来自网络,稍作修改,版权归原作者所有
& q& \% L# k; V! F//-----------------------------------------------------------------------------  o0 w/ t5 Z. y2 j+ O; i
class CHsPMEButton : public CButton
) g% q, x) _- ~" r1 U. s{
0 _1 C- g* m/ Y. T- @8 N // Construction) G0 ^+ v5 T& j! D$ ~6 d
public:+ W" J4 n( `: v5 ^: u0 L& E
CHsPMEButton();
( n$ R% K( q. } - H# }4 _. K2 X0 v& v
// Attributes5 `( a. R/ n/ W
public:
9 D6 b. t- W6 T$ s8 q, E 0 m) y, x  i' x- _% F
// Operations$ g. l6 M  F; V- C" F' O+ Z2 A6 t+ c
public:# ]' I9 L! ^; L
inline void SetNormalTopColor(COLORREF color)" E( o' ^0 m; ~5 M
{
, {. z# K& E) [# `8 X' b! P  m_NormalColorTop = color;! ^  ~  g' R6 B
}1 Q% S7 n( S# D# A$ D
inline void SetNormalBottomColor(COLORREF color)7 Q  G1 w6 N5 }5 t% p4 H* [! t7 u
{
- R" K) c. a& U; M9 N+ c4 ]  m_NormalColorBottom = color;' w. h2 U& S2 C' b, t8 A% D) w
}3 o) `" `! L5 V' g. \
inline void SetActiveTexTColor(COLORREF color)4 C, X* p3 W. A( y( _% ~
{8 h- a6 I8 M) R5 ^  H+ U5 W
  m_ActiveTextColor = color;
  R- |! k6 G* E' D. b }
& Q1 L1 G& W/ A6 W7 o0 G+ N( d inline void SetNormalTextColor(COLORREF color)
8 z" h0 O; s/ N( B; @2 { {3 B* e3 u9 W7 E! x: i
  m_NormalTextColor = color;$ N  g: X6 i* x/ E
}
) V( w) x2 e) g' q# b inline void SetSelectTextColor(COLORREF color)0 q- J# W& J" @2 K0 W* d. Q
{8 Q4 g$ R% U' n' z7 F# A
  m_SelectTextColor = color;
/ g- @# ?2 i4 T$ q }0 d+ ~* g- E( O) F, f
inline void SetFrameColor(COLORREF color)
& S) T* E+ S2 K" k {4 v1 O& ^4 u2 f# N/ O  @
  m_FrameColor = color;
6 c8 V# D# i- [4 ?2 `8 e; i }
$ A  L3 P7 U! q2 L3 R inline void SetActiveColor(COLORREF color)
! T* L9 y5 l! L! f# F {
) E$ `3 J7 g6 v7 W  m_ActiveColor = color;/ I0 ~% N! N& f1 r! b/ M
}& T/ z2 M6 p# m2 E( c
// Overrides
/ S9 i( A8 M9 G; V // ClassWizard generated virtual function overrides
% b8 B( t3 L2 z. x7 @) q, Y. ^0 U //{{AFX_VIRTUAL(CHsPMEButton)
2 g. }% l$ y6 W+ Fprotected:4 @. k0 n% |& c
virtual void PreSubclassWindow();/ q" m( P. z0 h$ U$ ?& I
//}}AFX_VIRTUAL
% q3 l# {7 u3 O+ ?  R; | " T' ]" f' E6 ?, C: d% s
// Implementation+ I. k& I, @# I# i$ P
public:' d1 F2 X# K: k. d5 F
virtual ~CHsPMEButton();
* U9 w) F5 R5 o% L; r5 _( p 0 _# J7 L+ p/ i$ }. U
// Generated message map functions
4 S0 _( C0 h/ G0 Lprotected:$ Z% U+ k) K  w5 P3 V5 J- i
//{{AFX_MSG(CHsPMEButton); a0 {/ R! q/ T
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
5 }- }. I' _! U- a5 p( h7 l //}}AFX_MSG: f; W" M( T: j) h8 e% @
# u2 Y" t- _* g. f' P
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
2 A; ^. _- @9 M$ |6 m void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
& m; _- N9 m8 X$ ]# D! W# B) Y1 a void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );! i7 B: {8 L! F6 K+ u: e( Q
LONG OnMouseLeave(WPARAM, LPARAM);% x7 N, e. q( k* ^
BOOL m_bIsMouseMove;' s7 g0 w) i4 ?/ W5 }- a5 r6 [
& n4 @6 ?4 J7 L
COLORREF m_FrameColor;
" y/ Y( q) `; p; L( d- q0 v, e COLORREF m_ActiveColor;
. |' `8 [( u2 Q; b. ? . D% f! ^; ]; k7 U
COLORREF m_ActiveTextColor;
7 o2 _  o- `  D, B COLORREF m_NormalTextColor;
0 J; s% E. y( q' m' }" o COLORREF m_SelectTextColor;
: t0 i2 e6 K' M 6 F, m& e* E0 ~" q  P9 P. a
COLORREF m_FrameHeight;
8 T: N' z3 x/ O COLORREF m_FrameShadow;
) N% v& N, t1 Q8 ^; p, [' B5 i! g
% s0 C7 [: \, |! O0 e COLORREF m_NormalColorTop;
/ h* H- s4 q* Q# {! T7 I COLORREF m_NormalColorBottom;
  ^5 m( e# P; h3 X: Y2 R
3 `* z+ X$ o" S' z( s" L DECLARE_MESSAGE_MAP(). S# R! v" O2 ?
};
/////////////////////////////////////////////////////////////////////////////
& g, L& h/ t% Q7 H. ~! U: O// CHsPMEButton
CHsPMEButton::CHsPMEButton()
8 m4 N) f7 L' A- H, F{
9 z$ F/ E* P) k8 O% E" l" { m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
6 C/ M  _0 V4 ]$ _* U$ k* } m_SelectTextColor = RGB(0, 0, 0);
2 z6 |9 ~$ |1 q, m! l' [ m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);/ m0 }8 u$ a5 R: Y& |
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色% c1 H; ?; W2 ?+ w7 K8 Y0 `/ ^
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);7 n- i! E+ |4 d; A1 [$ D
m_FrameHeight  = RGB(230, 230, 230);% Z+ ?5 I, n( [& x$ D3 H
m_FrameShadow  = RGB(128, 128, 128);" f, C) d1 Q( }
}
CHsPMEButton::~CHsPMEButton()
9 d8 w& r* y2 T3 g% Q{
! x; p( g6 y# u4 ~3 r}
3 Y+ o; n! e/ m" n
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton). L; m/ Y1 e$ e- F7 q$ B
//{{AFX_MSG_MAP(CHsPMEButton)
4 s* k5 i( J; o2 V& L ON_WM_MOUSEMOVE()
, M6 y5 C6 `/ `, E# O# m8 x- g //}}AFX_MSG_MAP6 O7 a: R) v/ W/ r3 b3 G
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)4 \( k  j" J- A/ h  d1 P( I
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////, p' L2 D0 Q: g& p* G, q1 i* L5 Z
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
9 W6 X1 e# s6 b: P) H% i9 h$ O{  G5 |( H# ]- _4 t
//*
& m7 N  {& n9 ?  I4 `- V CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);' S6 }8 `: L- O4 h
DWORD nState  = lpDrawItemStruct->itemState;
% }+ L& _# B6 r* m! i5 w DWORD nAction = lpDrawItemStruct->itemAction;
2 h: y. J- N+ l2 s3 [1 \ CRect rc   = lpDrawItemStruct->rcItem;& V5 G! L( V; z% a, C; K" e3 X
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);0 T; w/ O/ y& X. ~" j0 _
CString strText;+ q1 |, g* |8 b" \7 A! K
GetWindowText(strText);
if( nState & ODS_SELECTED )4 e/ X# o2 n5 S2 g
{% N- E4 T# e! s% x* O' g7 g" F1 X# C
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
. e! h  u$ H5 k$ \: h  n2 E' r  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); * w+ x% }- }- `6 _0 q5 ?
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
: I  ^. K  m% D/ [ }) u, t8 P$ ^/ T, t: D4 v) z
else //Normal4 n# D+ |  G$ r
{
) b5 a+ u$ k) S- f* n0 r1 e8 ]. I  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
! Z% Q6 \& D0 A/ a+ J0 z; m7 g  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);( E0 g5 Z( w- b" z: A& c
}
if( m_bIsMouseMove )9 l# C% ~0 {5 g
{
1 x5 ^# Y# {) V. m2 o: J  Q  CRect rc2(rc);
9 i' r9 Q7 \: H8 t6 ~1 u( V+ ]  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
$ U1 C* t' U9 j  m+ z$ J: h! \   m_ActiveColor, rc, rc, pDC);; X# ~5 _& P. Q, a
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
% z( v( `7 Q# t& M  NullBrush.CreateStockObject(NULL_BRUSH);# O5 v, W! }6 c1 S- B  m2 c( i
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
! \. }3 P1 w' t7 C# f  
7 ?6 z+ x5 D1 \3 ?0 u  CPen Pen;2 x3 J3 b& Z$ z& W( U
  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);* u/ s3 i) {* Y8 l4 r  l
  CPen* pOldPen = pDC->SelectObject(&Pen);
, `  I- W# A- y% z  rc.InflateRect(1,1,1,1);
9 ~1 [1 p, c; W, _: X  pDC->RoundRect(rc, CPoint(3, 3));# I, S# x2 Y( C
  //rc.DeflateRect(1, 1, 1, 1); , }% |9 D! s$ t. T+ f9 ^% S% W
  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
$ Z2 f. c* L) Q7 W% R7 M" a6 l- X  
; G* O# N3 w4 V9 X: [* k  pDC->SelectObject(pOldPen);
! @& v8 r4 O/ L$ M  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);! w* S9 ?' o  T$ u, \
}0 F" Q0 k1 _* Y& d- v  k
# B9 r4 t* Y* |) _: L+ D+ r
pDC->DrawText(strText, strText.GetLength(), * c! U0 P+ w8 d4 z
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
+ O0 V( }! K9 h% x% r4 j //*///( m6 m1 T1 K, K5 d. p3 [$ {2 G
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
: G3 P8 D8 d( x9 b+ {; I" i2 X{% h; m0 U$ t/ C
// TODO: Add your message handler code here and/or call default: V' n. `, t, n& D8 g' J* P
if( m_bIsMouseMove == 0 )
0 T" P% ?: J9 }( \0 c; C0 l {
( K: P% z3 j  D6 t9 M  m_bIsMouseMove = 1;
  i  N9 e3 W! L# Q: a  Invalidate();; M2 J( Q/ t2 n; p9 X4 k) P
  0 c; A5 h& D0 t
  TRACKMOUSEEVENT trackmouseevent;( a" R9 w/ p. L0 `  a  O3 `
  trackmouseevent.cbSize = sizeof(trackmouseevent);
0 j7 {& V6 V# v6 h  trackmouseevent.dwFlags = TME_LEAVE;4 O! \' J  g* L- F" g5 c8 S
  trackmouseevent.hwndTrack = GetSafeHwnd();, O* e  ~; R9 \! G: h8 W) q
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
# e0 |) a- b% D% h" K" U6 x1 Y! c  _TrackMouseEvent(&trackmouseevent);; u+ v7 B- L. M. q+ }% W
}
" W) ?+ g  e6 c4 Q  ~$ b1 ^; x % N9 m. G/ @1 `- f+ t- `) p. S& _
CButton::OnMouseMove(nFlags, point);% o, A& n& p8 }0 b1 A* j5 ?
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
3 N9 A* M1 D$ e, o: d" ~{; v9 P) o) Y% M8 o. |6 i, U
m_bIsMouseMove = 0;* x3 _1 ^2 u: Z- C7 B
Invalidate();
return 0;: q  H7 R  }& |6 m% Z& `8 z, @
}
void CHsPMEButton::PreSubclassWindow()
4 P0 }8 G- v  A" S8 e{
8 w8 u1 H, z% D% V- y! {$ K/ D7 L // TODO: Add your specialized code here and/or call the base class$ e  A! \' l' l" u0 g+ `
UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style# s$ n% S8 j# ~9 F8 F8 `+ ^$ P
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
0 D+ t5 Z3 F* e% p/ y0 {# C/ i. m: O}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
. q1 B+ c* J6 }- A5 h{
% S1 K, ]  f. H( j+ U CPen Pen;9 X. j" U8 {+ O: E
CPen* pOldPen = pDC->SelectObject(&Pen);% e/ Y) ^1 Z6 v; p+ ]) J9 f
, ~! C8 t8 @# F9 m: ^
int R, G, B;
5 @1 E+ v6 h- K0 \0 E/ T4 ` R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
" H% ^7 W$ S# n2 J1 [% ?" X G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();- q  t3 k$ B# N6 H
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
5 I1 V( _: l- U  h- b. {4 O
  t/ C6 p* o; W3 W( e8 K* Q //R = R>0 ? R : -R;
. w2 z3 x2 g" E$ ?" R# j //G = G>0 ? G : -G;
) l' S" O. S4 Z! L) P: Q* i. p3 M //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);6 `6 S. G; Z; f; O
COLORREF ColMax = Top > Bottom ? Top : Bottom;+ M0 A6 n: L. f% i1 q& t1 ?
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
$ \1 z, W8 l9 M+ ]( h$ k& o$ y {. ^( G9 D! o/ R9 S% s9 j5 \+ a
  ColR -= R;6 G- _- w/ j  t! r/ A* C5 e6 g, q
  ColG -= G;
- A4 p4 W! O6 j* I6 b  ColB -= B;
  /*+ d4 X' ]8 [2 z: B  q8 u# r; i  Q2 n
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||8 o1 D% w/ L: \) i. P
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||/ G( y. y2 m+ d! x8 [% v
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
: q6 C. G9 Y# }# P/ l: B  {. U6 `* q+ C- Y. y" x2 J: e
   R = G = B = 0;
6 Q3 V& Q+ R: C4 e) R  }///*/
8 M8 V) z5 D4 @7 b
  Pen.DeleteObject();
4 `+ H* w$ f* t  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));) j* H1 v+ J6 i3 c, \
    ) ~  ?# u" |9 K
  pDC->SelectObject(&Pen);8 ]+ ]# \5 I2 z: F& e+ F/ E, T. ~) i
  : A; N8 n8 V; @- d5 ~
  pDC->MoveTo(rc.left, rc.top+i);; }% D1 Z% [6 J' j! D3 k
  pDC->LineTo(rc.right, rc.top+i);
; y" k, Y0 m/ x  P: n( Y- V }
pDC->SelectObject(pOldPen);5 u, P% g' n2 t1 O" F3 _# T1 ~
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)4 M2 u' f' {9 P6 Q, H2 c" C
{
8 ^- Z6 X$ ?: x* Q! x& [ CBrush NullBrush;% T, X) A/ V* k1 O$ H+ G6 O
NullBrush.CreateStockObject(NULL_BRUSH);
% M8 B! {! x: }9 ` CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;# K9 {( w3 S5 [/ e
Pen.CreatePen(PS_SOLID, 1, FrameColor);
$ H( d, Z: Y) A3 H5 Z3 f7 { CPen* pOldPen = pDC->SelectObject(&Pen);
9 y8 r" c) f  T5 ?% M; g' L' M% y4 A
& m( n. X6 h4 }2 L5 J( W* ] pDC->RoundRect(rc, CPoint(3, 3));  r) [$ M; x, z0 I' |0 ]
rc.DeflateRect(1, 1, 1, 1); 9 a& z  a, u$ ]- m/ M, ~- E
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
, O1 y1 q  o. J0 E pDC->SelectObject(pOldBrush);
+ X3 Q9 n  d2 l/ @4 y; ]4 i}
1 g" t( T, z4 q  z6 M+ g, b
/////////////////////////////////////////////////////////////////////////////* H& \3 _- L) r
// CHsPMEDialog dialog7 H/ }" b$ P" \+ [, `; L! G  [
//-----------------------------------------------------------------------------+ Q  y/ \' a9 M' [& `" r5 \
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:2 P" ]+ a& z! p/ T
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级! w  Y. s" u# a+ A- j& ~
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口+ z# ]3 F& H0 m1 N! G
//   指针将其显示出来,然后隐藏或销毁自身6 ^' m) D: W3 L2 k$ I/ n5 A! K
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。$ I- ~. L7 t' u3 G8 g8 t8 J
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类0 P3 B9 @/ W8 L; Q# ~# {
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,' v$ K7 R3 W7 O6 H8 x
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。5 Z# S2 P- h- K6 Z8 \: P
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
7 x8 U( x6 b( K( f/ W" Q//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
$ D- ]" M( B9 }% \' B//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。9 \+ b# z7 X# T/ z1 P- O+ U: J+ j
//-----------------------------------------------------------------------------! N% D/ V( Y1 n4 {& d6 b
// 注意:
! Q4 h3 P& \! i! k9 V- @5 k* M// 1、在构造对话框时必须给出其父窗口指针
" O& X/ s4 ~  C' s// 2、在初始化基类时必须指定对话框资源模板ID$ r* B3 ]! Q9 y5 m9 ~
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
: f* _7 t+ @* U5 G) d// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
; V3 f! P) {4 v) B1 A//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
" u6 q: f/ ^- A  ~6 V- `, [0 V{% _# u' e' N4 Y. {0 j8 d7 l
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
; }+ M9 ~( d1 D  }; |# j$ H1 x// Construction9 t5 K; }' q! `, F% t: {) V( O/ y
public:& m. ]5 U/ ^0 ]1 |
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor- [3 D  j! a1 p; k7 f
~CHsPMEDialog();7 }- n/ S: V1 p$ S, N, O
BOOL Create(CWnd *pParent = NULL);" `5 T- a  Z( e+ h( F7 c

0 P$ [3 s/ Z5 D% d// Dialog Data
1 e8 Y) c" ]$ K4 Z/ b4 E //{{AFX_DATA(CHsPMEDialog)& z1 [3 r6 i. V
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };
& O) \( |5 H  e& {  // NOTE: the ClassWizard will add data members here# u! B, M3 ?4 H' Z1 H3 f) F9 i
//}}AFX_DATA

2 j) d# k& V) V# J2 U  D// Overrides* h8 W, C. }9 }
// ClassWizard generated virtual function overrides
- X! J2 p9 J% X //{{AFX_VIRTUAL(CHsPMEDialog)6 ?2 x- U" y  S6 l
protected:
( y: v0 t$ @/ I& f. o1 l1 L virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support2 u# E: T3 G( o% A1 s
virtual void OnOK();* J3 l* k0 O: l  J& O' a
virtual void OnCancel();
% s& B! ]6 M& `. C+ y4 @# d9 \ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
" F* C/ d, ?8 \ virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);0 M. E/ l! N- E- M8 ]
//}}AFX_VIRTUAL
// Implementation: ~5 z% W3 `) T3 {/ m
protected:
// Generated message map functions& R% H& @' ~0 k6 F& K% V  j& K
//{{AFX_MSG(CHsPMEDialog)% k# ^1 s: T3 ?9 B
afx_msg void OnBack();& C$ o+ k/ p7 z
virtual BOOL OnInitDialog();
0 f4 `7 X* L$ M7 j  S5 x4 r afx_msg void OnDestroy();6 |2 H" X4 z5 h
//}}AFX_MSG; a8 b  P$ P( @
DECLARE_MESSAGE_MAP()
protected:
1 m. ~8 H5 j0 e, W* I // attributes
5 V3 J9 E1 ?  w1 m" G CWnd   *m_pParent;     // 父窗口指针
" V$ }8 Y# I1 [, D HICON   m_hIcon;     // 图标* [9 n/ @) \8 c% I6 S, l
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
3 C6 J( f0 ^  S2 q CHsPMEButton m_btCancel;+ D% r* M: ]+ N* ~* ]3 U- W1 y
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄( A, [8 u, y0 J+ ~) k1 v
HHOOK   m_hkCBT;     // CBT钩子句柄' B- d- {3 R; Y4 R# ?- ~. R' g: {
. ?: l+ w" l6 p4 B) H: N( F
//-------------------------------------------------------------------------& k/ l$ d* J6 U0 m: f  c
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog; i* l% ^7 B$ j0 P5 m3 ~+ f3 z
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为* `1 W; R/ k4 u1 v
// 链表的头及下一个结点的指针7 e+ L8 L: N0 V( v; t8 l9 w% ^# _1 w
static CHsPMEDialog* m_spHead;# W+ I# H8 N# P2 A
CHsPMEDialog *m_pNext;
// operations
. V7 m$ e5 f9 t9 G // 键盘钩子消息的处理函数
) R7 b1 F% w2 r& n8 o' O static LRESULT CALLBACK KeyboardProc(
8 g7 X+ X0 _; G7 i# Y2 j  int code,       // hook code
) d+ t  p6 ^4 `  WPARAM wParam,  // virtual-key code
# k& s- U6 U! Q. L0 q; Q  LPARAM lParam   // keystroke-message information
1 }- N' A# t- ]; k; i  );
. b/ f5 _8 K0 t6 [" c  a2 \ // CBT钩子消息处理函数" q! x0 _/ w; d. b! l# U4 P& Q
static LRESULT CALLBACK CBTProc(6 \. _, N% d* [( g- m
  int nCode,      // hook code: |5 b7 m. v. }9 p8 K$ ]* G
  WPARAM wParam,  // depends on hook code5 l" {/ Y6 l8 J' X$ j/ b
  LPARAM lParam   // depends on hook code
. c/ q) L. L# `; K( @7 Q( F# n" T& b6 P7 j  );; ?4 Y" r( E2 Y( G* B7 B
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
  O7 l2 O' i; H- k% u static BOOL  IsWndKindOfThis(HWND hWnd);
3 f: J6 U: M8 }& | // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
% ~! c1 |+ X) v7 ^ static HMODULE ModuleFromAddress(PVOID pv);" q" {3 S' Q% H- C$ ?1 K$ _/ D  A
public:% `5 q1 f  b6 N  _' b
// attributes
// operations
, F2 M$ g& o* L' X2 W // 用于模仿UG的创建一个子对话框,同时隐藏父对话框$ \$ R! _1 i( g, l  n1 S1 y- U7 r9 e
BOOL CreateChildDialog(CHsPMEDialog *pChild);
5 ]9 a# W, r! @. V6 q2 E};
, l; g( h1 S$ ?
CHsPMEDialog* g_pHsPMEDlg = NULL;& V; m/ ?) h8 I8 m+ ^, v
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
& |) u6 h6 F4 \HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/), S* G; b$ z, o) s
: CDialog(nIDTemplate, pParent)
8 G( P  W4 i7 c- Z1 o2 [{3 g5 L! W6 I) S- y
//{{AFX_DATA_INIT(CHsPMEDialog); b) j$ D) M$ C) h: m
  // NOTE: the ClassWizard will add member initialization here6 K" n' W' t, R2 x* o
//}}AFX_DATA_INIT
5 [9 Y7 s. R+ R+ \* Y! S$ c7 L m_pParent = pParent;
" R; L) {' u- ^, J3 D) W9 e m_nTemplateID = nIDTemplate;8 L9 \. q$ B/ b( j
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
/ n9 l5 n) L2 k m_pNext = m_spHead;* N4 O% ?) e9 {
m_spHead = this;
6 @1 V# O8 q1 s+ f6 K' _. P+ v m_hkCBT = NULL;$ C& \1 P; E1 q& e# z3 K  G% o
}
CHsPMEDialog::~CHsPMEDialog()2 Z% H/ i4 Y: @/ L
{
$ F3 @; o" k) u // 从链表中删除本结点
/ y7 s3 E  \  K' A CHsPMEDialog *pTemp = m_spHead;" N/ W  C" M7 T/ |
if(pTemp == this)
7 r* H6 {) [& a9 L) T( i6 a {
  c2 M1 s) x0 ^2 Q' n6 ]3 u5 j  m_spHead = pTemp->m_pNext;
* [0 U3 y# ~! C" X6 r }! G3 {6 H. H/ x. ?  _" r
else% ^5 T- A8 B: ^& y3 R; X3 r4 O1 f
{$ B4 w: j# f4 p: X
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
* G1 e# n+ |6 t% H2 s  {  F% j8 ]5 F8 e8 |
   if(pTemp->m_pNext == this)
& c+ s' W! R, g6 H   {3 c" ~! J% b* {* U, j
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
6 m, i) z5 [8 D5 V4 H& S8 S5 Q' L    break;; z' M. ?6 M9 o0 v
   }
$ I( n/ c: B, q7 O/ W! @; F- o  }
' p1 `- d. a' V# i! X }
3 q3 J) `9 ?: ]' c2 {- J}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
, b. q. N2 W: N! `( Y{  Y2 g7 Y* t0 V% A+ e( R
CDialog::DoDataExchange(pDX);: d4 K0 N3 |  [* |* u
//{{AFX_DATA_MAP(CHsPMEDialog)# `- ?1 i) i/ X# m& d
DDX_Control(pDX, IDOK, m_btOK);  W$ W2 O% r6 e8 L& n/ r2 M- ^! F
DDX_Control(pDX, IDCANCEL, m_btCancel);1 y4 H/ D  y% e3 c
DDX_Control(pDX, IDC_BACK, m_btBack);
! x! v; Y0 ^9 E, R$ M, x; f9 d3 `/ B //}}AFX_DATA_MAP
( _4 `, }/ q3 F}
1 T) |9 |* g* ^% `" [3 S6 X
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog). n) {0 e/ w4 r) K+ Y2 A# N
//{{AFX_MSG_MAP(CHsPMEDialog)' Q2 ^8 U4 R3 S
ON_BN_CLICKED(IDC_BACK, OnBack)5 m' B4 t8 m5 v# D. ], j6 U3 D/ O
ON_WM_DESTROY()
- g1 [; o0 ~; ] //}}AFX_MSG_MAP
6 f; W0 H' p, @( @END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////# U# z7 R+ _& N
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
) n( X7 T$ s1 @: X/ D3 \$ _. C{
# q2 |- r; H4 t+ z5 a m_pParent = pParent;; A  w9 J- I/ M9 y/ y* U( u
return CDialog::Create(m_nTemplateID, pParent);, `: W- d" x' Q3 N7 ~
}
" A' T3 p* i- U& h
BOOL CHsPMEDialog::OnInitDialog() - m/ Z+ a, t1 h6 C
{
* t4 q) L. C$ k CDialog::OnInitDialog();
// 设置标题栏图标
# \; d7 i6 \7 b# ^ SetIcon(m_hIcon, TRUE);' R5 a, C1 G3 {
SetIcon(m_hIcon, FALSE);
8 @9 F2 }& m: t) M7 C% y
9 n0 e2 K0 p# H% |- c // UG的对话框的几个标准按钮没有TAPSTOP* L* N; S. i8 a1 a# b
CWnd *pWnd = NULL;+ e* P' x9 ~  Y$ ?
pWnd = GetDlgItem(IDOK);! H8 w9 j, U& O# T1 q9 r
if(pWnd)0 }" ^* l0 v. _  q+ o
{
5 e8 z4 s: [9 k; F  pWnd->ModifyStyle(WS_TABSTOP, 0);
" i! ~7 B  }9 ~9 A7 N }5 l8 X; t% v: H; j) R9 f- _3 ]
pWnd = GetDlgItem(IDC_BACK);
6 J5 d3 y( r8 _- ]; ^ if(pWnd)
7 h  c$ i& ~* T" x; E1 G0 Q {$ U2 P" H+ }( _  b( @& J
  pWnd->ModifyStyle(WS_TABSTOP, 0);' B; g. K2 \. |5 \6 _( m
}
0 R  c; F! R0 Z  R pWnd = GetDlgItem(IDCANCEL);. v! ?% \6 e0 v2 ~# ]! c
if(pWnd)
- _! U$ L" a9 D* C" C {
; l; q2 g# L4 r4 d3 x& ~  pWnd->ModifyStyle(WS_TABSTOP, 0);
+ K% a3 F3 I, }7 Z3 I. f# O5 ]5 t }& p5 ]% B2 R2 [1 d/ a6 |" X

. P* S6 ~7 b+ l* @+ D" p6 E g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
* j* \6 f# M8 d, w" E, o if(m_hkKeyboard == NULL)
; v0 C, @+ ], f/ Z {
2 q9 ~2 u; e# u# z5 a  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
4 J9 z* j, W- D }" Y3 S" ^+ |4 k, [2 n# R" h
if(m_hkKeyboard == NULL)5 e7 Z0 }% p7 c0 f
{
( W: P( O0 g5 B/ U9 x  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());, l7 \5 G; f' ~- c* l5 F
}
if(m_hkCBT == NULL)
; E7 N# c  M- K! d$ A {
' N2 O1 p5 B3 f: c" h  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());- k7 A# X$ @% X. H9 X
}8 o. U  x; _3 s( c
if(m_hkCBT == NULL); P; x% U+ r: Q" ^
{' v  i8 v; \# k. c$ g
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());/ F0 _  R. b  c0 |7 q7 a1 L
}
" Z( K$ {* u6 U* M; H0 U8 a 1 F$ [8 R7 s6 c) d1 v" |) i
return TRUE;  // return TRUE unless you set the focus to a control8 F6 w3 n' }& J% }5 Q6 W
               // EXCEPTION: OCX Property Pages should return FALSE7 c3 A' ^  T9 O" R, J
}
void CHsPMEDialog::OnOK()" D7 E' @) d. @4 B% ?9 g% b
{
: k( V! w& c  K) T CDialog::OnOK();' [; C& b6 y+ S- k5 k* o
if(m_pParent)
/ j& ]7 V7 O1 J9 o2 d" ]& | {
0 M9 S9 J4 c1 z3 A2 r! F  //m_pParent->DestroyWindow();% g  n& D0 W6 M3 e1 U. _& h1 I
  //((CDialog*)m_pParent)->EndDialog(IDOK);4 _# c  R) H$ w( ?& b. q0 d- v
  ((CHsPMEDialog*)m_pParent)->OnOK();( h1 S" q% |1 I* F' @: T* h
}
/ M9 d& N$ ~2 K( G/ k}
void CHsPMEDialog::OnCancel(); o7 d+ u' C2 N: t+ H  X$ U
{
' ]# G" r, q' H3 B  @ CDialog::OnCancel();! f+ ]  u  E5 g) j
if(m_pParent)  d1 P) B2 `# Z( v
{$ b8 j& n9 q; L* b$ \- O
  //m_pParent->DestroyWindow();2 P2 W8 ?2 p; D8 v3 u& M: K
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
6 X6 m, `1 H  v( Z7 H  ((CHsPMEDialog*)m_pParent)->OnCancel();0 t. |& k- H, r) A( K" E' T2 _+ X3 t( U, H
}
6 Y0 Z5 }+ q: V. J}
void CHsPMEDialog::OnBack()- C% K! C( ^& G% F
{: P  A5 g; l: m2 \8 e
if(m_pParent)$ b1 s8 [5 R7 k# D, J
{, ~. E1 S: v9 C+ E
  m_pParent->ShowWindow(SW_SHOW);
0 P2 w: q9 K7 }6 e }
9 ]6 }2 ^; Z: z) P1 ~% \- Q CDialog::OnCancel();
4 [& r: C- |7 B$ `}
3 A! g# n+ u. p
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)! q' m. {2 g* J6 D9 _3 _2 K4 Z
{
, }" r( _! `- M) @3 m" t BOOL bRet = FALSE;
  M8 ^9 [" m& L if(pChild->GetSafeHwnd() == NULL)
8 H: U- w* w3 Y0 {: } {
) M5 g( k0 z$ q% z( L  X3 f  bRet = pChild->Create(this);
7 z& h* c, c6 r3 Z$ ^ }3 q+ M+ o4 b/ K3 X
bRet &= ShowWindow(SW_HIDE);0 _  J, y' o& x7 D. _
bRet &= pChild->ShowWindow(SW_SHOW);
; b' P7 F* @7 {4 v! q( x return bRet;
1 ^6 S; P4 H) l8 F+ p3 V}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)3 i# a9 O$ E( f; Z4 I0 ~, O
{
5 z1 z+ f1 v* F if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup; v7 z; ?" A- [$ i
{
7 V" K9 m* E! [$ ~- X* y( w  //TRACE("Key down/n");
4 G# ~" @; s3 B5 N- ~  CWnd *pTopWnd = CWnd::GetActiveWindow();
( T' U7 ^; G1 I9 K+ r  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))1 f3 J: K$ _/ C- g! U
  {
& p) ~; J, F/ [/ n( [+ z* |   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息: q# I  E) q1 D7 H
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)& O' Y. Z' w& c9 k  @( s( g- d
   {3 q% E% c7 F0 L5 K1 O4 Y
    // 只截获tab、esc及回车键
  T2 ]3 W% {! L& \8 N% ~" l8 @    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
" F7 @" I' J' u2 U& W8 ^: N6 l- D' x    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);  Z4 c6 F- @0 r0 x8 K9 j
   }
5 q$ k9 D* m  U/ R   switch(wParam) {# x2 I+ D5 |3 k' D( U) U. Z
   case VK_TAB:
4 X' x% i2 g+ ~    {7 \, g5 d' O. c( g+ }+ q
     CWnd *pWnd = pTopWnd->GetFocus();# |' V+ Q2 E  T$ I
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);! ~) u- ~5 U0 M6 D) E. }4 F0 _
     if(pNext)
8 A9 H& b+ ~0 M3 w- `0 ^     {1 H: B9 q5 P! R  L1 G4 \  C
      int nCtrlID = pNext->GetDlgCtrlID();* b$ c; c0 t4 k/ I
      //TRACE("CtrlID = %d/n", nCtrlID);
: U  z# E- `, Y& O6 v2 j      pWnd = pNext;
2 }6 X$ B7 L; |  Y. R2 O6 T4 z8 `      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)# V) w6 _$ h+ C6 K- Z* D
      {( F5 n1 }. p4 ~; f9 x0 I
       // 根据UG对话框的属性,这三个按钮是没有焦点的
- v, o  A" ?( }8 ?0 G$ S       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
# Q( r6 ]. x7 C1 V% B2 ^7 W$ A       if(!pNext || pNext == pWnd)
  ~  s( ]6 O# g2 n4 Z6 W8 p( P       {; t4 C5 l7 r: B& c
        // 对话框上只有上述三个按钮
+ @; C9 R- l' r$ e        return CallNextHookEx(NULL, code, wParam, lParam);
& @+ F1 r' v: q6 S# s       }- }3 a; g% ~" q$ }! E1 h+ |
       nCtrlID = pNext->GetDlgCtrlID();
3 w" t( \; d  o4 I; B7 l- C* L       //TRACE("CtrlID = %d/n", nCtrlID);# w- N6 V& f0 T" S" y& p+ R2 g, }
      }
( I% ?7 V6 c2 U! z      pNext->SetFocus();" c, I# W2 r- }
     }" a; Y- ~2 g0 n; P
     //return TRUE;
. S; b$ c( o9 E  i    }" X; I( y. \- D  k( n% X
    break;9 i+ ^6 v$ m4 A# G) e
   case VK_ESCAPE:, _- C. k- t& R% y! j. G3 d
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);7 H3 l; T4 f& m: F) H" H1 V
    //return TRUE;
& l: Q5 s0 D# I; ?- S    break;5 W1 I  Y" \- f* L, V
   case VK_RETURN:
: _& _( p! |4 `    // UG实际上并不处理回车键9 c/ h  y: i# h! }  I
    break;
+ E. Y+ H  o* x; ]   default:
6 p) y6 B0 h) C# i5 L  J    break;
; L% G1 v2 i! v2 Q   }
! q2 G2 o  O# p' N- S8 I' T  }" \  w8 l8 a7 c/ Y7 P
}" [8 y: M) A% a/ w* K& i8 \
return CallNextHookEx(NULL, code, wParam, lParam);0 z1 c! Q8 }# p! @" K( J) U6 G
}
void CHsPMEDialog::OnDestroy() ; D6 @8 Q3 _3 b( Q1 A) h! W" h+ W
{- V" i$ j0 V  }# V4 a( Y; P* }
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子7 B2 T8 `8 d$ K# j9 @
if(m_hkKeyboard)
; g9 \" u$ g  Y3 y2 `" s {* D) ^" w% d( L- o3 Q8 m# A: J
  UnhookWindowsHookEx(m_hkKeyboard); 6 F- u& M3 x% V( e" y/ D
  m_hkKeyboard = NULL;
9 U+ f& \: f& Y% F5 v3 d }
if(m_hkCBT)9 Y' U! Y. V  {. s5 }; u* p
{
  O# l3 x- `+ w+ Z  UnhookWindowsHookEx(m_hkCBT);
9 G5 z9 R! \/ C1 a: h- C  m_hkCBT = NULL;
- g( g- l2 J( m- `+ t* B5 b9 y }0 u  `8 ]. |  [& P
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
) e, A, T- y7 w0 G2 p/ {& S{
! H" F3 X$ G2 i2 ? CHsPMEDialog *pTemp = m_spHead;4 C# }5 j% b6 \, l$ R5 J
BOOL bFound = FALSE;- R1 N6 l& e) s4 s- _' V8 e2 X
for(; pTemp != NULL; pTemp = pTemp->m_pNext); T+ e" ]7 Y0 w) A4 s1 E& X
{
  }3 }  {: a5 ^. n8 k  m. b  if(pTemp->m_hWnd == hWnd)
* x2 d5 h. {) C4 e! Z  {) f6 b( j: y& D% q6 A# V) }, D5 V# i
   bFound = TRUE;$ e) B: Y/ p( ]9 ]) h5 k4 y
   break;
7 `. f/ e3 ~% j  }
# G0 z6 T  X. R }
: Z, m7 V& F* h4 y8 I return bFound;
) _& Q! J. V; Y- f' x% o4 ~}
// Returns the HMODULE that contains the specified memory address
3 O" `$ u" ~' u8 b7 }' V4 OHMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
: j' N5 `5 p$ ~{
1 l8 Q1 s( T% k$ {. k) l% B
$ K4 S, P6 c: i: D6 ]9 f4 I MEMORY_BASIC_INFORMATION mbi;1 _8 K: L3 b3 Y0 p, R
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
) U1 s* D$ f9 B7 t3 f, }% ]" q! n  ? (HMODULE) mbi.AllocationBase : NULL);( h" t% \2 M, }+ }" a2 \' ~
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
2 E: ~2 D- o1 V- O5 t{4 J8 V( Y+ n0 n+ U+ y$ T% `3 @
if(nCode == HCBT_CREATEWND)+ r$ i$ N# H! y
{
8 {& B4 {' d8 Q  //TRACE("A Window is being created/n");1 Z. I- D  b3 c+ S- r/ I
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;% N* @8 H! A* g+ y
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
- Y! T" p/ [( v/ h& o  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
+ M& e9 Q; r; J9 C  {5 n: H8 [: A5 o- C2 y
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
& y+ b1 J: V, x! b" |3 d   // 取得窗口处理过程内存地址
# F/ N2 C9 T6 g2 a) [. `! k- P   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);( H- l" w- K$ j5 z- |& b
   if(dwUserData)6 R/ N0 @/ o& l  _/ @& [
   {" r7 i0 n3 [* p7 E7 M4 O
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);) Z1 W5 u3 ]* o, Z! ?, ~
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};( A& b: V- L1 w' k: p; I, E
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);4 R1 w& k) V9 [2 n/ ^- O! H2 D; D
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
% M2 g( i$ p% _4 F    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
. V& K/ d3 _9 f& i1 G- X/ z4 |    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);3 \" ^- ]2 s  S3 S. o1 l/ c( M5 o, j
    if(stricmp(szUGPath, szModulePath) == 0)
$ M% f4 t) ?* B- p5 W    {
- e- l1 F/ }: G) G/ H" K0 d( M' C     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
1 A  a8 w3 J! G) d" a' g     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
! Y# ]# h& K! E. c9 f8 u     {
5 L( m/ J+ Q/ @& C: G      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
* W5 y7 `5 k9 k      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && , t* {% E' U7 L' C. r
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)& q, h6 N+ Q5 P0 m4 w2 m1 a1 ^
      {
# _: R: \% {- Q% }* p       // 窗口非本窗口或其子窗口
( l/ g" ?1 M5 e" j: a       g_pHsPMEDlg->OnCancel();
, R: M! o0 b6 I1 I" P4 J      }3 c0 W1 K4 u7 Y
     }  r( C8 @1 y1 F; {
    }  d; F  `; v  ~: n% z) b
   }
7 Y% g. x3 f5 a9 C# s3 m+ ?  }
! T* ^8 z7 E" t }: ?! V! A6 s. A/ ~6 o0 {
return CallNextHookEx(NULL, nCode, wParam, lParam);% Z3 l- i5 Q# O
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
+ ]* i/ `+ g1 M% [! H8 {{
9 U! m/ v6 d) O8 }* v" k% `- h- B+ U1 K+ M8 [ // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
. T% f' h/ Y! j" b0 f1 J
) K+ v1 ^% C1 H+ a" A return CDialog::WindowProc(message, wParam, lParam);
4 A  e  _# O, y( [# n0 L" _}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
- E1 k! f# |4 [, b, t{) y% w/ {8 i. f7 O# T; J$ n
9 s; R7 C" P+ O  ~
return CDialog::DefWindowProc(message, wParam, lParam);+ D7 [! {7 d9 ~
}
: p" y: f6 P+ v% S  m% U/ q
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了