PLM之家精品课程培训

PLM之家精品课程培训

联系电话:18301858168   |   QQ咨询:939801026
NX二次开发培训

NX二次开发培训

UFUN/NXOpen C++和实战案例

适合初级入门或想深入了解二次开发的工程师,本培训结合ufun,NXOpen C++,大量的实例及官方内部的开发技术。
公众号二维码

关注公众号

点击扫描二维码免费在线高清教程

课程详情
Catia二次开发培训

Catia二次开发培训

市场需求大,掌握核心技术前景广阔

Catia二次开发的市场需求大,人才稀缺。掌握开发技能潜力巨大,随着经验积累将在汽车、航空等领域有所作为。
B站二维码

在线原创B站视频

点击关注工业软件传道士主页

课程详情
Teamcenter培训

Teamcenter培训

全方位培训,从基础应用到高级开发全覆盖

涵盖用户应用基础培训、管理员基础培训、管理员高级培训及二次开发培训等全方位内容,由多年经验讲师打造。
QQ群二维码

加入同行交流

点击扫描二维码加入QQ群

课程详情
×

PLM之家plmhome公众号

课程涵盖: PLM之家所有原创视频

×

关注B站视频

所有高清视频一览无余,全部在线播放学习

×

加入PLM之家QQ群

同行交流,疑问解答,更多互助

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

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

[复制链接]

2017-8-31 13:24:24 3193 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
, \# O3 f3 j' }, M% a. z// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
* M$ @% v' u  s1 u) o! z//    该类来自网络,稍作修改,版权归原作者所有
! l& N* ^4 ]/ h/ u//-----------------------------------------------------------------------------( \/ f/ a! C. z! y  `: L
class CHsPMEButton : public CButton
- [0 s- j' Y( L& K{' V; J# }3 F, T
// Construction5 q% T5 z% Y) [8 j
public:
1 ]" v: n8 E" r6 t8 h CHsPMEButton();' d( t' O9 k" {. ^$ w' o( c' u
0 `. J1 s2 @. U1 Z* H
// Attributes
. C$ e0 h/ d. `7 p  jpublic:+ i% o! `/ h- }

' [0 E  @4 }$ g, k // Operations
8 A5 L& e% e8 e  \public:3 J% N- X' M8 L9 A  D/ H
inline void SetNormalTopColor(COLORREF color)4 d" {! G! r" N& C0 g* h4 g
{! u) u" w0 a6 c( t! _: [4 u9 I
  m_NormalColorTop = color;
; ^/ O. v' F) L' l. L  ~, o }) b) b, ^  w9 d5 o6 Q
inline void SetNormalBottomColor(COLORREF color)7 s$ ]9 p8 a" j! A! \
{9 X$ C0 Z# c- e- }/ T* T
  m_NormalColorBottom = color;
" e3 d1 S2 ^! x5 a) `8 Z2 ^4 S }8 @3 A8 {) i/ t/ R1 v, E
inline void SetActiveTexTColor(COLORREF color)# r2 |" G3 _( e8 p& w4 S1 k
{9 O* i7 c. m/ H' r! z
  m_ActiveTextColor = color;
; t# y" n: ~7 l" J }
; u2 _) w1 x9 V9 p4 _3 S inline void SetNormalTextColor(COLORREF color)4 M0 z4 g  Y( d2 E
{' K) W+ i  }( Y7 H$ ?
  m_NormalTextColor = color;
* b/ u7 L" B) N0 [: d }3 ~$ t5 f- \+ S  T% z+ A
inline void SetSelectTextColor(COLORREF color)
9 k* M# J8 C# C5 S {8 Z3 C. h3 h; g% R$ U
  m_SelectTextColor = color;# q* M( [$ |, ^
}9 t3 A* p1 n8 h1 u, ]
inline void SetFrameColor(COLORREF color)
& q$ V9 N% P- G. W* @ {0 o3 F9 O7 D% g5 E
  m_FrameColor = color;
" t6 |* }2 M2 s) |2 x }% Z) f3 R' ]' m. ]+ ^: U
inline void SetActiveColor(COLORREF color)$ C4 N8 h) h" c" Q$ E: F2 E
{: J  F1 m7 |2 f% Q1 l
  m_ActiveColor = color;
0 u0 J8 O; ~' m3 l2 x }2 M9 e! c, S* ~0 L, r% d6 x% n
// Overrides1 J: u( z1 o. ~! C: u* |
// ClassWizard generated virtual function overrides
8 }0 w; d& j2 Z# Q0 k) g% C' u //{{AFX_VIRTUAL(CHsPMEButton)8 b4 x; W, n, I
protected:
: g; ]5 r0 T4 c1 q! V virtual void PreSubclassWindow();# }$ ~% r) L# |: l% I% f! @! c
//}}AFX_VIRTUAL8 a) ]4 }; H1 Z) s3 u
( f# V+ Q- ]( [3 Z
// Implementation
/ y, O8 B( m  k% x+ e/ f5 l% hpublic:
. O) i* D% D* `9 n. w4 I, G virtual ~CHsPMEButton();, \- l  Y' n& V7 x4 W# Y( y
2 m) K; q2 c/ ?9 N  e
// Generated message map functions
9 J7 o$ B5 G8 h* Y$ X, p  @protected:
; z* s( r: i; k$ S9 V# i" T //{{AFX_MSG(CHsPMEButton)5 w  x1 a5 H: J8 P; R9 [' @; h
afx_msg void OnMouseMove(UINT nFlags, CPoint point);! U1 t/ ?) \2 Y* z  h& }. F6 G
//}}AFX_MSG
3 ~0 }, F5 K. O: d% p
: [3 T& Q2 K. W6 L  b void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
# ?  I  @+ p2 W, v5 V- Y% n9 X void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);3 d5 Q( m0 s: v. e0 m& w! R. J
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
1 ^9 D3 M, S- i9 ~9 M1 y  ^ LONG OnMouseLeave(WPARAM, LPARAM);
$ R  X8 |1 [9 L7 h3 \ BOOL m_bIsMouseMove;0 w5 S) i7 U1 n; |1 }/ K

1 J. w7 o2 X' B7 Y* z: D5 a COLORREF m_FrameColor;6 a9 i5 V" T  B0 e
COLORREF m_ActiveColor;
- O& h' ?7 F9 v/ ]3 u7 L
; _2 c0 e3 p8 ~% @) Y& m3 r COLORREF m_ActiveTextColor;. l2 q9 R, x0 y, f0 A/ J6 ^
COLORREF m_NormalTextColor;
7 `6 c. j$ \3 ]8 Z" q8 O COLORREF m_SelectTextColor;
5 D: L" {: n2 e9 n - k4 J% O- v* h! b
COLORREF m_FrameHeight;
# z0 G" v: {$ @& ?$ Q, \- E COLORREF m_FrameShadow;; T0 u4 [4 q# U
$ I) X. P; b9 m# i
COLORREF m_NormalColorTop;1 r2 {) R9 f1 T9 B/ V# R$ d6 T
COLORREF m_NormalColorBottom;* N" R. A' V) s' }1 q1 y: l$ G, {! v
# u3 @8 F4 h8 c8 E: l" s
DECLARE_MESSAGE_MAP()
) A: v+ ]- F' ], E/ d/ ]};
/////////////////////////////////////////////////////////////////////////////
( X( ?. d4 j4 R# P3 d) I/ `// CHsPMEButton
CHsPMEButton::CHsPMEButton()
* b1 g' @+ V/ S9 w6 T2 U{& n( e/ Y: B! I+ V0 b& y% w2 S
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);: l4 j& d( H* P. ^% ~
m_SelectTextColor = RGB(0, 0, 0);& Y7 e- ]' A/ Q4 L
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
& K1 R6 y; H$ q m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色, A! s% d6 u- h2 W7 R- _4 j6 `
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);+ u3 c- p) h) ]+ \: t% `% {/ v- X
m_FrameHeight  = RGB(230, 230, 230);2 Y% p. q% G6 k5 c' b( c
m_FrameShadow  = RGB(128, 128, 128);
+ X3 b9 t  ^& f- [* C0 V}
CHsPMEButton::~CHsPMEButton()  H, Z: o9 a. e
{
( [5 l' w) l: P3 o/ F) x}
1 J" V% P3 {- G' X; }
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
0 b, t7 N5 h3 O3 k/ |1 V0 g& v //{{AFX_MSG_MAP(CHsPMEButton)
. `7 ]4 ]; o3 Q7 j) Y: { ON_WM_MOUSEMOVE()6 i9 A+ `0 h% p" R$ o$ D2 Z; @
//}}AFX_MSG_MAP1 ?  s$ M+ G0 H0 d' U) {" e6 G
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)2 z/ s5 m$ @, P
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
. O3 o* J, r& m$ R( b: \5 e9 P3 t. h// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )( `5 y2 i$ _$ x) n) D
{
0 f5 _) ?9 Z! z; O" m' u! n //*
" O* h5 R/ q1 q8 L1 C4 [$ { CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
, {0 x; n' ]( @# T1 t DWORD nState  = lpDrawItemStruct->itemState;" S6 r* O) x/ A/ K5 z. J7 ^
DWORD nAction = lpDrawItemStruct->itemAction; 2 Y( w# B5 ~; r2 R8 F
CRect rc   = lpDrawItemStruct->rcItem;3 d9 c9 B$ Z" @- s) t
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);
' n' ?5 A2 F3 M+ s CString strText;; D* h4 e  ]0 V( j# n* p
GetWindowText(strText);
if( nState & ODS_SELECTED )/ j0 F5 f2 D5 J' y4 F$ k7 Z
{
  ?, `  P" c5 w9 Q1 o, L" ~  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
% a. D( I* }5 L2 ?" g% u$ E) ~  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
4 M7 b& s- D6 X& h1 R  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);0 [; H1 O+ T* l7 q
}
9 L5 s  U+ |" t0 n" s& L- z2 l$ ` else //Normal! f9 ^0 B# M4 q( y0 C. e8 F
{
4 N0 [$ p$ l+ E+ _( N  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);+ ^: Z# T/ j, k$ P9 \' I
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);+ A/ x! e* [  Y' R2 [7 R
}
if( m_bIsMouseMove )
6 V7 v# ~9 A: y7 s/ ] {( i6 y/ j5 f, A
  CRect rc2(rc);
5 A. O8 Q: U% @. s; p, y  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),/ e! I1 s/ ]- X! {9 w1 T
   m_ActiveColor, rc, rc, pDC);  A' u! j- [+ T; h# Y' Y; A2 }! q9 ?' ^
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
0 K, W. N! A( V: U+ ?  NullBrush.CreateStockObject(NULL_BRUSH);
, U( l2 _. o2 c: g6 q  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);# \0 r9 T( d& {: C& v1 C0 _5 E4 f
  
, C& B3 C+ m7 T$ s5 y: J6 }+ ~  CPen Pen;
5 B3 f" t2 A5 o1 c8 X: d3 }9 ^  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
2 ^1 t# D1 _( n/ `! K) t/ G  CPen* pOldPen = pDC->SelectObject(&Pen);
3 i* ]) t1 f5 z8 L3 Q% r  rc.InflateRect(1,1,1,1);
4 R) a  w1 H0 e( Z, G: C  }" {  pDC->RoundRect(rc, CPoint(3, 3));% Q. ~( {/ x& X7 D, H1 k# C  A
  //rc.DeflateRect(1, 1, 1, 1);
4 b+ |1 t" y) W! J, l  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);! x& }8 y6 w! t" L$ m4 X' v, Y
  
/ c' Q; k' z2 a2 A( r- I0 Q  pDC->SelectObject(pOldPen);# y7 M/ b" M2 j0 `
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
. Z9 N# r+ c6 V9 g- n/ Q. Y }
2 S" S- c2 ^4 N6 |8 S& w" \ " V6 j* J; i1 `: s) Q1 `4 e2 H
pDC->DrawText(strText, strText.GetLength(),
* e: o$ f6 k. O" Z3 x8 G  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
: p5 b5 C& A- @/ Y1 e- R //*///" z* A* M2 a9 R! {2 h3 C; s1 [
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
1 B  W" g+ L$ I9 y5 i+ l{" a0 B1 M0 B* u  g" u( r: u7 s( m; D
// TODO: Add your message handler code here and/or call default
0 E. M3 t+ ?9 a) w+ K1 d if( m_bIsMouseMove == 0 )
7 b; G7 a, w4 {" [: T- N {
; c# ?; F/ n$ Q/ K+ W  m_bIsMouseMove = 1;
- v8 }6 F/ Z$ l$ Y! y  Invalidate();
( ]: n0 ^: D' I+ K: s+ c  
( s& d" L; r0 ]+ W: h  TRACKMOUSEEVENT trackmouseevent;
& U7 G2 u4 L1 t8 @0 p4 `9 q/ H  trackmouseevent.cbSize = sizeof(trackmouseevent);1 }$ l3 z$ K( T' A2 y9 G
  trackmouseevent.dwFlags = TME_LEAVE;8 k* `$ l# \5 y- }6 ]
  trackmouseevent.hwndTrack = GetSafeHwnd();. \3 M$ G  E; r8 \/ Q: i
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;8 \; G; H7 u& J  V2 s
  _TrackMouseEvent(&trackmouseevent);
/ x9 x+ N% a3 ? }8 q" X/ c4 ^1 M  q% a
' `4 x# q/ ?4 l6 Z
CButton::OnMouseMove(nFlags, point);
0 ]9 N8 R9 ^. E" ]( F* o}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)7 h0 g) q6 o9 @; A! P6 D2 ~! J5 q) P
{5 @. }) ~& ^  F6 x1 D/ d3 h* W
m_bIsMouseMove = 0;6 p* Y; V+ ]& e7 d5 c8 z$ j' r
Invalidate();
return 0;
: I: \" K3 |, D% }- Q" {0 ~; H}
void CHsPMEButton::PreSubclassWindow()
( ~: b9 [. |4 |  `{
3 b6 G. c8 F4 q- m // TODO: Add your specialized code here and/or call the base class
7 A% W" j. r; C UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style5 P  t, P0 |" _& }  I* ?* J2 d7 w7 R1 ?
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
; m' j+ \+ A4 `' J}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
: b. c" d0 [: B. N* J+ i{9 T+ b$ L' L: a2 [0 g5 n" o, a
CPen Pen;
  H/ q0 D' e( d+ N9 t CPen* pOldPen = pDC->SelectObject(&Pen);! S  j; Y1 K  L1 t/ q  J( T
+ y/ e. n7 E) g
int R, G, B;
& }1 k) P9 I3 a" K; q, S$ C  b& Q$ Z R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
9 E8 u3 I3 X6 [- e! W/ @ G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();7 l. ^. m9 D( g  O3 C+ G
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();/ `( R$ w+ e% q& U7 K) z7 s6 ^

6 y* ]7 z4 g* s* C5 v! O8 Y6 n //R = R>0 ? R : -R;
' I. ~' G& g+ z //G = G>0 ? G : -G;
4 ]6 B& \4 ^5 u //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
, S2 f/ t' y  B4 \) N COLORREF ColMax = Top > Bottom ? Top : Bottom;
3 ]9 a9 D8 k3 o" \( ` COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)! h* [4 j& Y9 K2 U0 Q: L
{  ?6 L8 I* P% ]8 k( R& P
  ColR -= R;
  T# |9 _) r# r2 P6 _. S  ColG -= G;+ V& o3 i3 Z/ a/ u
  ColB -= B;
  /*; V% n" W; S% Q+ g) H0 U! K9 w
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
  L( L7 X( ?1 {4 Q7 y* n# y5 q+ S   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||7 A  C& o2 t" c* Y1 b3 {+ ?6 o
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
3 W# p+ A5 B/ D7 u/ T  D  {
) {/ ]* `3 H+ x4 g0 f   R = G = B = 0;4 ^4 `- O+ C2 L4 @$ A' t
  }///*/

4 {, V4 q( D. l/ J% T5 L  Pen.DeleteObject();( \, j2 Y8 d% k) ]8 a
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
% f0 I1 K; w/ p# U0 K   
5 C3 K1 V( f9 Y" Z5 k  pDC->SelectObject(&Pen);
# l& T# W. R! b0 @( ]1 P/ j2 e  
# Q6 ?5 R' _( n' w& n* S: A  pDC->MoveTo(rc.left, rc.top+i);
1 Q' s8 w7 x+ t) G2 ^. F" {% F  pDC->LineTo(rc.right, rc.top+i);- b+ E+ {% g3 o; r
}
pDC->SelectObject(pOldPen);, x# K3 v2 p1 }2 N
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
, T! \" j/ S" y{5 H7 K3 }3 e1 X; f
CBrush NullBrush;  a: H# T3 |5 ~1 Z7 B" Z, [& O
NullBrush.CreateStockObject(NULL_BRUSH);
- F/ a" W! Q  F) s1 o1 t! i CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
7 s" ^1 X$ G* @. q% M. y! R Pen.CreatePen(PS_SOLID, 1, FrameColor);7 \  t6 ~& u* O
CPen* pOldPen = pDC->SelectObject(&Pen);& g& _, z- \; D2 L% c
' V+ l2 ^) u) l: n/ C" c
pDC->RoundRect(rc, CPoint(3, 3));
  Z$ N/ {& y7 t, I  v; ]8 H& g rc.DeflateRect(1, 1, 1, 1); 4 W) Z% I1 X" {
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
, u3 F9 E* |& n3 B pDC->SelectObject(pOldBrush);6 q( X8 I8 p! ?
}

* t, t2 p/ z0 X6 a/////////////////////////////////////////////////////////////////////////////% D% o" v+ t3 r7 f( i# e! h6 G
// CHsPMEDialog dialog* m0 \! @" {1 I8 C* w# j, k( A
//-----------------------------------------------------------------------------
( y- [+ Q; D) A4 j// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
7 _9 @% F1 y; \% G  V//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级' p* \$ L2 |9 T
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口+ C) @3 \6 k$ z3 D5 O
//   指针将其显示出来,然后隐藏或销毁自身
- g: `& s( p! p" U) ~/ U//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
* @5 W" \' X3 f- J: ^' E//    采用的方法为使用上面的CHsPMEButton作为按钮的基类8 g2 N, P* ~/ }; d6 q( m
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,) z; G8 A  S: ^" y
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
+ [* o- r5 N; a//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
; I) u3 w  W7 ^: G: }9 D//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框& K& k. S7 p6 |1 l: t4 [
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。
- f" I+ n9 F! L) u" Y7 }//-----------------------------------------------------------------------------# q( w1 c0 r* G  ?  P
// 注意:6 S+ K7 p7 X. h+ S! u* ]
// 1、在构造对话框时必须给出其父窗口指针
( W. S0 r& `* r& j+ f' S. b// 2、在初始化基类时必须指定对话框资源模板ID0 y2 }- n: F8 Q! Q
// 3、对话框资源中必须提供ID为IDC_BACK的按钮: |" _; K% l8 C; ^( I5 c
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel  ^4 l3 {! H/ T# Y2 Q$ u! P4 D+ J+ s
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
2 b# {6 Z# d+ W. j+ J{# b2 E& r7 r2 J; x% Q# I" o
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
0 D' K7 A/ D+ a, ]5 p// Construction
" t+ ~( W+ E* l7 q- Npublic:' V) W) y9 e' C- F+ Z" H# n
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
5 V6 P% `3 q, F  T7 t ~CHsPMEDialog();% H; k/ i; f/ B; `; q. O
BOOL Create(CWnd *pParent = NULL);
* h2 `" q. I, B) n/ U
' G' S0 Y# m& l& E// Dialog Data
4 b1 c0 M2 b& U2 F8 e& c //{{AFX_DATA(CHsPMEDialog)
/ b( p, ~3 W7 i4 G1 G. v //enum { IDD = _UNKNOWN_RESOURCE_ID_ };% t" d2 |- k" u/ q& ]
  // NOTE: the ClassWizard will add data members here
: d8 v* a8 x/ U* K //}}AFX_DATA
$ c, f# u7 L# p# z
// Overrides7 [$ p/ Q* |; v" ?& ~
// ClassWizard generated virtual function overrides
3 q! r' g4 V$ h' t# @ //{{AFX_VIRTUAL(CHsPMEDialog)4 ^: T9 ]" q: _/ c
protected:# A* U4 q, B) b9 S  u% t% G1 A2 N; O
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
# z8 e+ w, ~7 g0 z) Z" D virtual void OnOK();
4 H. d- X! I  c7 t* F9 a virtual void OnCancel();
$ U. C5 |2 O+ e9 S+ N virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);! n  m( I" \& u5 y
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
$ p$ v$ M# ?$ B3 \* [8 F# t //}}AFX_VIRTUAL
// Implementation
6 x5 d* b7 r% i2 F" ~; zprotected:
// Generated message map functions
  f- e6 \0 f9 F$ x7 y' V+ Q //{{AFX_MSG(CHsPMEDialog)
5 w7 b+ L4 u5 q4 e) c! Z# L& V; k' V afx_msg void OnBack();% X# X4 a# d. w( i; u
virtual BOOL OnInitDialog();$ i' X  j- V# T7 M1 C
afx_msg void OnDestroy();
/ B3 q4 M5 P  b+ }* ` //}}AFX_MSG
6 C3 r/ u. P, {1 q+ |) @" `. V- D DECLARE_MESSAGE_MAP()
protected:
; h6 G1 |0 Q1 ]0 }) }6 a5 f/ ]% u // attributes6 @& S1 Q# a0 K# V
CWnd   *m_pParent;     // 父窗口指针
# r% V" f1 _( Y HICON   m_hIcon;     // 图标' O* r# o4 ?; c
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
, q9 k& v% h. S6 l6 m; R# }2 n CHsPMEButton m_btCancel;: K+ B7 l) s- z. E7 L6 j
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
4 u9 g: g% N4 ?$ Q9 y2 k HHOOK   m_hkCBT;     // CBT钩子句柄( o9 ?: C- v# Q" q

  `9 [' o# R2 O5 q5 n4 K* U( y //-------------------------------------------------------------------------5 t5 `; [+ a+ |: Z3 W, [. o
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog! L, g8 A7 Z" I! J
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
+ `- }. j9 _: E) [7 x- `+ ~9 m // 链表的头及下一个结点的指针% k2 \3 `) \: u4 ]" k2 r
static CHsPMEDialog* m_spHead;
! a# C: p7 W8 w) h; z" ^ CHsPMEDialog *m_pNext;
// operations! Y3 u" z& K$ X1 |7 O3 r
// 键盘钩子消息的处理函数
6 k% T# m3 D6 s+ I: o2 q/ g3 x static LRESULT CALLBACK KeyboardProc(- m) _( |2 x1 A: P" Z" W
  int code,       // hook code
+ s1 a7 F9 z9 [# A4 H+ n7 e  WPARAM wParam,  // virtual-key code- l9 G; a; \" b2 o* ]) G( K# V/ {3 G
  LPARAM lParam   // keystroke-message information
" v$ d3 P% r, C" n  );
" Q1 j+ T, P( ~3 ^8 E  S // CBT钩子消息处理函数
: W: O0 m3 ^% B3 K- S8 s static LRESULT CALLBACK CBTProc(
# e( Z0 T  m# ]% K, D+ C  int nCode,      // hook code
4 T5 i$ E* M+ p& S; J6 m* |" C  WPARAM wParam,  // depends on hook code( e4 p0 i0 i% X2 r' @. G, r) [
  LPARAM lParam   // depends on hook code
' n6 N  g! n3 e- \- e( X5 f5 i' N* L  );
4 k; s7 [6 O; N$ B/ u. i( J
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口3 _8 {3 a0 e9 N; p/ d
static BOOL  IsWndKindOfThis(HWND hWnd);
" a# K& h' b# B6 I( `$ U( C // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址): n/ ?1 L) `5 T+ h5 K" N. j
static HMODULE ModuleFromAddress(PVOID pv);
% V  Q! U7 ~. B0 t" D) dpublic:/ I; y( _8 n" `" B( z, E
// attributes
// operations
8 W( ~+ L8 b5 F9 F // 用于模仿UG的创建一个子对话框,同时隐藏父对话框
( W4 q3 m  l1 Y5 [6 S! x+ }. a BOOL CreateChildDialog(CHsPMEDialog *pChild);# s! N( R2 V6 p2 W2 s
};
+ x3 ~& }/ `' e5 |/ |, V
CHsPMEDialog* g_pHsPMEDlg = NULL;
* O% K" P& M  }, Q" T+ cCHsPMEDialog* CHsPMEDialog::m_spHead = NULL;$ E% ?# X, g' I: G9 D
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/), t) R  u, p; X' m$ ?
: CDialog(nIDTemplate, pParent)6 \7 ^( V. {* i% D5 \, j
{2 B5 |/ F# V  k0 ?
//{{AFX_DATA_INIT(CHsPMEDialog)4 @; t  \4 x7 o% j6 o! H
  // NOTE: the ClassWizard will add member initialization here# }3 S  K/ x7 z6 K, l6 P
//}}AFX_DATA_INIT( G; N% n* B; Z4 m3 e+ D+ S
m_pParent = pParent;. P) q% G  u0 b: P( D5 ~, D! v
m_nTemplateID = nIDTemplate;# k& ]% S, M6 G9 z) |: a
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表2 f) N7 Y& v4 |' O8 O! t" Y
m_pNext = m_spHead;
  ~  L$ c) I- r' y m_spHead = this;# c' E$ \5 {# o  j7 I. ]; \6 n$ T
m_hkCBT = NULL;$ m6 Q, _. O. x5 Q# E' r2 x/ H& ~! S
}
CHsPMEDialog::~CHsPMEDialog()6 _4 i$ W0 f% \
{
: o  w4 R$ {5 J' {7 Q9 m/ v // 从链表中删除本结点
1 N. |* R9 @5 w* F6 k% g CHsPMEDialog *pTemp = m_spHead;
8 {9 E# }7 ]% I1 K. ]+ n if(pTemp == this)3 j6 P. [# u; {0 ^$ Q+ \
{
" y2 V5 q" P* x1 {  m_spHead = pTemp->m_pNext;
; s" l" z5 B$ {' X }
2 v  X  Y  b/ _: O& @7 k else
. X0 i% O* J5 M" e" n; I6 c {
  ]: _, w& |0 k( c) h% K  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)) E8 Y9 m( R: z, a+ x4 }
  {
: f4 w# D* M4 q4 s9 u6 s7 S5 [   if(pTemp->m_pNext == this): I5 |8 \: C  F1 n, v* v: B+ N
   {2 p) h- N& W6 [1 E7 Z6 w
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
6 `" G+ d0 n1 j) L  i. c    break;
- @2 i3 g' S) k! e1 Z$ r, i! M: ^" t   }
8 i# L! G6 |# x8 p; _  }
+ R* _; H2 h. w/ v8 L }
# _% p! t4 @% B% k( I}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
) z5 g" ^# \- h, v0 W) i{% Q7 n% I- g3 _) v0 h. m
CDialog::DoDataExchange(pDX);
5 N  l4 W: h0 q  L //{{AFX_DATA_MAP(CHsPMEDialog)
( J8 Q( e" ]& q/ h/ S  k$ I DDX_Control(pDX, IDOK, m_btOK);
3 g* b, o# t& m+ n DDX_Control(pDX, IDCANCEL, m_btCancel);! x' i: P# E* _
DDX_Control(pDX, IDC_BACK, m_btBack);( f0 A2 a$ u" ^% \
//}}AFX_DATA_MAP2 H% Z0 }6 r& U* K2 {$ H+ M
}

& l! d# P4 h5 _; C8 WBEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)5 B* [; `* l1 R6 }: O/ _! t! O
//{{AFX_MSG_MAP(CHsPMEDialog); n8 R  p* T) |& O9 z
ON_BN_CLICKED(IDC_BACK, OnBack)7 F/ B# A0 N9 [# T
ON_WM_DESTROY()
3 k$ _: i4 t; M/ t //}}AFX_MSG_MAP
8 N+ T# s" a) O. y# bEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
( Y# R3 r: n$ z// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
8 d+ d$ U4 H" E' |" n7 U{
6 E( g- ~; g* u; M& ]- w m_pParent = pParent;
: m- j+ w* z2 Z* O$ R return CDialog::Create(m_nTemplateID, pParent);( a. a+ q; F7 q6 l% @# k3 h9 F
}

0 e5 @9 V$ b- y: O# |BOOL CHsPMEDialog::OnInitDialog()
0 [: ?* L) U4 C8 `9 ~{
- C+ }$ i& U$ ~( u CDialog::OnInitDialog();
// 设置标题栏图标
6 m8 A( w9 d7 i. y; U- ^3 { SetIcon(m_hIcon, TRUE);1 E" X9 \5 i( j0 s
SetIcon(m_hIcon, FALSE);$ _- v" u4 ]! j. _6 b$ b% k% m
+ }# `8 E9 p' b0 x' Z
// UG的对话框的几个标准按钮没有TAPSTOP% ?* @: C. `# B
CWnd *pWnd = NULL;8 @6 k: E# h& h; d. \( e
pWnd = GetDlgItem(IDOK);
) L# y$ _5 V* C) T$ S( ~  Q if(pWnd)+ l- X4 m0 o+ u, V- w5 Q& O
{  c1 C& H/ p; S1 F* Y7 S& @8 S
  pWnd->ModifyStyle(WS_TABSTOP, 0);/ a# w0 F  y% X  P
}( I) @& y. B' }* C% y
pWnd = GetDlgItem(IDC_BACK);
7 w8 |* h% W, x* K$ W. T& k! y if(pWnd)4 X# N! ?8 p; f- ~& y0 I
{
# s" S/ `% b; G  pWnd->ModifyStyle(WS_TABSTOP, 0);
. ]1 V6 @, P9 x+ s) _4 k  S8 A }( \& ?4 r8 K, s  l! y, Q1 z0 G
pWnd = GetDlgItem(IDCANCEL);+ P) q8 ?9 @. A$ ?9 V7 W* b
if(pWnd)/ O; p' P; {/ `9 ]# v  k( m
{, ]8 T! q/ ?7 K: a6 |
  pWnd->ModifyStyle(WS_TABSTOP, 0);
- T' c' [0 j6 z' `* h }3 h* k* \7 f) G8 y7 k4 ^

4 k7 x2 I1 T# @+ w4 Y* E1 Z, ?7 U g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子  |  e1 U' \9 ~, N8 t
if(m_hkKeyboard == NULL)
+ v* h+ v$ e/ `3 H {$ Q8 V1 ?8 u7 z, _6 d2 _
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
$ w0 \% \! f3 b$ A: U, W! X }7 h2 m! p* G$ P$ m, p$ m" t
if(m_hkKeyboard == NULL)
4 [; m2 T2 l' Z2 V6 O9 b. s4 V {$ m) M9 d5 M1 w! u/ y5 }
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());/ u5 O  x2 o+ r7 F. m
}
if(m_hkCBT == NULL)
/ x& i1 _# X  u3 G* i) ^. p {" G: u( n% C3 b6 [2 R5 O
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
0 m7 d# F3 X! x' F& p% J# i" p }, }8 p. f  m; q: Z; F6 F! ?/ N( H
if(m_hkCBT == NULL)
0 B6 r" x5 P; c9 }4 \8 p8 r {
1 {7 K" Z" Z7 ^6 V; e; _5 R  TRACE("Set CBT Hook Failed: %u/n", GetLastError());' Q% c6 S  m6 v6 |% ?4 A: o
}
6 @. B, I! O$ m" l 6 m( h. x% }5 e/ E# b  b" F
return TRUE;  // return TRUE unless you set the focus to a control. z4 {: o! Y: F$ |. M+ H
               // EXCEPTION: OCX Property Pages should return FALSE
. r. L# K1 x! }8 g}
void CHsPMEDialog::OnOK()
# I* X! R* J/ S{
" ^. g" r& j  w) M CDialog::OnOK();
- y1 c: ]. h+ \ if(m_pParent)3 e5 t2 ^; D- e) \6 K6 x, `
{
- l" i/ u, y" z  v+ d: l8 Y  //m_pParent->DestroyWindow();
  Q4 Y4 `# Z8 z: W. g  //((CDialog*)m_pParent)->EndDialog(IDOK);$ B* u2 _* A0 ]9 B+ }
  ((CHsPMEDialog*)m_pParent)->OnOK();
3 f4 M0 Z" L4 @! v! o: }- @ }
' N1 i+ ]  ?; u}
void CHsPMEDialog::OnCancel()! W2 n3 l5 l! x6 a' I3 {; e
{
3 z8 s5 W7 v3 h: J CDialog::OnCancel();3 `6 \* y9 o% a& h- ]
if(m_pParent)3 W  n& r& q/ D+ [6 {
{
# s3 A5 e; c3 o2 p; K% T! a+ ~  //m_pParent->DestroyWindow();3 a, A/ _2 K9 G+ h/ U+ W
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
+ s8 L( i* ~! ~  ((CHsPMEDialog*)m_pParent)->OnCancel();
" t' y6 R- H" O9 X; P }
0 p% W; m$ o  a# t1 \}
void CHsPMEDialog::OnBack()
; J5 V: w* K% y) e9 ^; _& e( n: ?{
3 X6 V7 `+ A$ h. j+ V if(m_pParent)
  a, d$ B4 K5 m  n {
3 {& G2 m& v, c$ B' o9 D9 A2 n  m_pParent->ShowWindow(SW_SHOW);
, x! T* p/ r7 _0 u' Z6 M0 Y  |/ L }
) s% Y3 a/ p) x% t; X# h CDialog::OnCancel();% b1 I" Y2 M$ W2 e) K5 K
}
3 ~2 o5 m9 \5 T! J8 r' E0 ~
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)& [+ `* D% a! t+ c: H
{
" h* C/ N6 q* U  r$ q3 y BOOL bRet = FALSE;- u: J5 e* l0 v) T" s3 d: M
if(pChild->GetSafeHwnd() == NULL)2 R$ M0 D; u6 B5 r# b( _+ I4 _' j% s7 U
{6 x) _! Q5 D- I
  bRet = pChild->Create(this);+ Q% l' ^* W8 J+ I
}" ^* {9 B& @( b0 |5 B
bRet &= ShowWindow(SW_HIDE);4 U" H/ y# A1 p4 V- [1 G
bRet &= pChild->ShowWindow(SW_SHOW);, f9 l/ h; c3 m" Q) Q; L7 T' I1 S" g
return bRet;
0 r- f2 V7 @. c- E6 L}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)% W# e1 e9 A% _5 W; u
{
* V; W6 K5 r  F$ F/ K if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
" p2 k7 f! A) l {2 m; x* B( b# k1 v: Z6 ?; u0 O: l
  //TRACE("Key down/n");) B! P7 x/ I' a5 Z" Q  `6 Q7 e
  CWnd *pTopWnd = CWnd::GetActiveWindow();6 `  H3 s4 k7 T% N
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))0 b* P0 j3 S2 o- s9 f+ b
  {
; g: F' N1 g# o- h   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
/ C, J) u3 `2 V6 e   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)7 {' g6 Q. Y- a, V5 p5 K
   {
) G, ^: J+ V* ~' S6 f    // 只截获tab、esc及回车键8 s- S; q7 }& s; `+ C* Z) O
    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);3 E9 u9 q  n3 k7 N' x, g' Z
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
* r4 U: n/ [& V% h' M   }
5 |$ ]! o- A/ j' e9 ]4 `6 i* M. ?   switch(wParam) {% Q9 ~9 p: R* ~0 Z
   case VK_TAB:
7 z$ n. w, ?" M; d/ [/ g    {
: V, n( |- S9 Y* Y" r* l& R     CWnd *pWnd = pTopWnd->GetFocus();) B- i) G( I: G* W4 e
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);" D2 r9 k) K$ J" D4 w
     if(pNext)8 c5 b+ O" d% F0 x1 \4 l( D
     {' Y& @- @* O2 [% M) V" y1 r6 w
      int nCtrlID = pNext->GetDlgCtrlID();) }$ _+ O7 K8 Z7 G# E4 O8 s) }
      //TRACE("CtrlID = %d/n", nCtrlID);
% Z8 B( v0 L# |  F, s) a- k      pWnd = pNext;
/ ]3 i& X# Y, p% j* T/ |      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
9 V1 z5 T% r* F7 x; |) \      {0 u: c' p1 N! f3 W( ~
       // 根据UG对话框的属性,这三个按钮是没有焦点的, j2 U' @6 c7 Y. X
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);! [/ g/ Z) B" o+ I. }
       if(!pNext || pNext == pWnd)) [) t' ?: E4 j
       {
  M0 G3 @; R/ S( @& K; _1 W        // 对话框上只有上述三个按钮
$ v, w* Y1 k, C. [8 H0 B/ J2 Q        return CallNextHookEx(NULL, code, wParam, lParam);+ X9 w* Q6 Y7 I6 ?0 V
       }4 L+ p- H: Y$ n/ w
       nCtrlID = pNext->GetDlgCtrlID();% u* C6 e- `0 h9 @$ G8 Z
       //TRACE("CtrlID = %d/n", nCtrlID);
3 U7 K6 c8 Q3 H* [  |* q( L, ]5 B' C      }+ s5 w* [6 n" v2 z
      pNext->SetFocus();
' z! V5 z2 @+ [1 }  P8 f- D6 y+ k     }0 ?' ~( {. X# b  P8 M
     //return TRUE;
4 t; i1 o1 k8 R3 e( t    }/ I0 q4 z' Q  _* @! c' e+ E( E7 ^* L7 \
    break;8 h9 q' d  n9 J$ j4 V" A$ Y" H) w  b
   case VK_ESCAPE:
+ o# v+ i4 E6 T7 C" d/ k" i6 y    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);! M7 G/ Y) k/ s- w) Q% Q- C! c% I
    //return TRUE;9 X6 S% w" b( P- y" p" F  W. M& N2 g
    break;2 y+ o6 P6 ?, A" ^
   case VK_RETURN:8 \- T9 d% M0 A" d5 P9 l
    // UG实际上并不处理回车键* _0 T1 q6 e& a" |( W/ A
    break;
0 S/ d/ X, ^0 x) Q; F   default:6 ~3 |8 M, p/ G" C, Z( ]
    break;
- i# i0 f! `$ l   }
6 l+ E8 k& h0 {7 Q1 ~2 j6 }  }
" `$ u: e; m/ E/ |3 z) H" I4 ] }
# H- F8 T7 G6 f  S1 g0 y return CallNextHookEx(NULL, code, wParam, lParam);
! E- Q( ~, X  a8 r& T  _}
void CHsPMEDialog::OnDestroy()
2 H  s$ c6 {6 v, s# e3 I{" F8 h& Q, \+ G, d5 {
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
5 A* v1 L. l" m. K( C' T if(m_hkKeyboard)
+ }. J. v4 G( b7 e. b0 ] {# E# }+ h$ b) p  o  h! k
  UnhookWindowsHookEx(m_hkKeyboard); & K9 l2 B3 g* j/ y; N- a" U
  m_hkKeyboard = NULL;$ w6 B; Y8 U2 V, L! }
}
if(m_hkCBT)
) s& W# R% Z# ~ {
/ g' ^5 |# z  T6 Z: z. ?# h$ v  UnhookWindowsHookEx(m_hkCBT); 3 j2 d% K/ t- V% j' G
  m_hkCBT = NULL;# D5 A9 `" i! h8 b' `9 E
}, r3 \- B( c+ _$ J: Y2 B
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)! G& c1 B& N! t& D9 A. x0 ~. A  \
{2 m8 x+ {" A; e
CHsPMEDialog *pTemp = m_spHead;
. K4 q, q4 r; t BOOL bFound = FALSE;0 `$ I, ^; \, q1 }
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
5 |8 `1 w" Q; L8 z5 R, z {
+ x2 ^- ^! f1 W" U  if(pTemp->m_hWnd == hWnd). Y1 F1 Q$ p( O: f
  {" M( ~6 a# q7 X+ b# ~
   bFound = TRUE;3 R7 @% ?; K% L, r* h9 V
   break;, i1 k) e* c, s, E0 B2 l) O8 b
  }
( @' M/ F& }5 A7 H }
- l2 C/ _# i/ i$ x9 x  T) Q return bFound;
( G5 Q+ m% E; _# U" y}
// Returns the HMODULE that contains the specified memory address! K2 Q# d6 \, E+ {4 l; m
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
/ K- {' P# [; K$ t* W) }1 U) Q{, `2 U7 W% d% N! {+ @% W: W

! S: Q& Q. l: n* w! e# j. `9 M MEMORY_BASIC_INFORMATION mbi;8 E% J" D  x9 W0 s& K$ R
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) 0 U# l3 _" U1 G5 @' z# V$ c  D0 `
  ? (HMODULE) mbi.AllocationBase : NULL);
# X9 f( L4 i% }0 A+ \}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
! _0 _' B) C& k  s{, k: h& s5 p& P, U
if(nCode == HCBT_CREATEWND)
' V# {6 C4 x8 n9 y {' m  C! \' q2 k4 K9 w
  //TRACE("A Window is being created/n");( e; B; f* \) L
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;
5 N4 e/ g( N7 l  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);  H! D2 u0 |2 e( U
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))+ ?/ B; J' q1 x) Z" m- g0 ^
  {5 ?+ n: o0 i  ]% \! b0 e' z
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
; q( t" j, t5 g( v  ]5 \   // 取得窗口处理过程内存地址
* R! {6 U7 z3 A' }   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
7 \) V2 ?2 i. \! L" I: J! R   if(dwUserData)
6 R' u8 x: t: \. E0 H+ \1 c   {
- p( G5 f5 u$ d" ]! L" z    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
" J- h  [9 f2 f7 v3 E    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};: p" }1 y+ d& ~. |' D5 `4 C% z
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
4 H$ ~$ Y+ _( {# y    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);8 |2 t* }0 M6 @& \& w8 ?
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);" G- R* Z) d2 _. L  y' o- v
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
2 ~! e, u: }* J& N# n4 y    if(stricmp(szUGPath, szModulePath) == 0)
: o- p9 E3 o" S! x4 Y/ J    {- ]1 n7 x8 j1 @( c9 ~5 h1 g5 m
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
1 p0 W* h& f& _7 `     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
7 R7 q) R8 A/ O% V. x4 p1 P     {! ?2 F* X4 R- F% q# C& a
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)& F& q# J# ^0 o' D, j
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
; }' L7 t: u# D+ s* V- M       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
; [; X/ C, d. ]# J      {
% \9 X3 z* Q& x( ^       // 窗口非本窗口或其子窗口& q" K0 q; J! Q' N3 I7 f9 r
       g_pHsPMEDlg->OnCancel();5 k9 y2 n- C+ j
      }6 Q9 |7 K4 w; v
     }9 |- \+ J6 R7 z$ k$ O0 Z
    }5 e5 ?3 D0 P* R+ J* x. ]/ b
   }
5 J2 x' k  x# p  }% L  _7 W# x5 Q; `' p. m8 y# `3 ?4 R
}
, `9 i# e! |% _' R" X6 P" g5 b return CallNextHookEx(NULL, nCode, wParam, lParam);7 m; U! b$ Q7 k" n1 B- K
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 6 A2 Z  h* V. E5 v  n( y) M
{
. B. r1 t7 K' c' G // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
( P1 x7 U1 k" G, m4 M) M0 M+ t
0 `) ~. @2 \% m: ]$ F" l6 w# P return CDialog::WindowProc(message, wParam, lParam);3 J( x% H# ]& H, p
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
/ M) y5 Z* e; ~) [/ g3 z$ ^% A{8 J) I! Z% D, h5 U2 e4 [9 g8 G

6 h  T  C8 B- M return CDialog::DefWindowProc(message, wParam, lParam);
+ Y2 r7 i- |. Q  E: [}
4 E: [7 H, L9 j" m
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了