PLM之家PLMHome-工业软件践行者

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

[复制链接]

2017-8-31 13:24:24 3432 0

2470

主题

1275

回帖

8万

积分

管理员

PLM之家站长

积分
82170
QQ
发表于 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------3 F# ^9 q& |$ L% v) W+ V. V
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
7 o) O! T' k7 l4 R1 f4 W0 V//    该类来自网络,稍作修改,版权归原作者所有7 P  d- j1 j' I. Y
//-----------------------------------------------------------------------------
7 V& D, T: i( z! m, R  N6 V, qclass CHsPMEButton : public CButton
) f# ?1 G5 B5 |; R{
% J3 [3 z" {/ B% q& y6 s1 \% K // Construction
9 c9 f# F) B9 y; w1 I' Q7 spublic:
6 f6 h( b. I' ?" \* N- E CHsPMEButton();
3 E/ H( j7 @1 N$ ?  w  T
9 {' B1 D" G) R, o) S( j // Attributes8 S+ d! G& Y, d
public:5 |9 }2 y% j: E: x. j
$ C5 _7 d, Z) f$ {; z% `
// Operations
6 d; n% g' \( Zpublic:
; T9 ?. d  z9 i$ z inline void SetNormalTopColor(COLORREF color)
% w" K  T  d8 o8 @3 g2 ]- h {
$ P  q* j7 @" Y# f1 B5 M# ]5 j  m_NormalColorTop = color;
/ K) s% N: v; A& C3 A' Z }7 f7 j, E# ^/ y+ e0 f( O5 q
inline void SetNormalBottomColor(COLORREF color)& S9 E: J* x2 D+ i3 H; t2 N& N
{! D0 C! g4 }) N/ i/ @# A! }7 ]2 Y- F$ Y
  m_NormalColorBottom = color;* d- `& w, b" c
}: v! k/ U( K# Q2 O, a/ ?2 k& ]9 J
inline void SetActiveTexTColor(COLORREF color)) H# J. Q; {: g" C
{) ~% F2 S' Z5 q: ~6 K
  m_ActiveTextColor = color;/ f: L9 b. l0 G4 s, T
}2 s2 Z" P3 U+ X/ @0 |8 {1 m
inline void SetNormalTextColor(COLORREF color)
, m3 H- T$ G# S1 p; n" L9 `: Q( K {6 w8 F$ L+ K( B4 S8 i- h
  m_NormalTextColor = color;
  |; |  r+ A3 |4 a/ K% ^' a+ i! Q }
% z+ U/ L2 N# E" d# H inline void SetSelectTextColor(COLORREF color)6 X  g% P8 E$ R7 B$ Q* j2 u8 H
{
/ i! V0 `3 ]/ I/ Q  m_SelectTextColor = color;+ k9 |' P) u  r$ Z
}# U( z+ e; s! j
inline void SetFrameColor(COLORREF color): n' x, y! y4 h, @/ e2 G  _
{
  u. Y* X/ Z! K) ?( f5 x$ P8 L1 E, X  m_FrameColor = color;
' L# F6 ^9 N3 u9 m }2 f9 J  ]2 T7 U2 P" p
inline void SetActiveColor(COLORREF color)" Z" B3 M" D9 r6 l
{
1 N8 O3 l: K' l( F4 v  m_ActiveColor = color;
& s. v6 f% z6 Y' m, L }
6 c0 c' P4 ]. ^" w5 A: |, A // Overrides; i9 H- {* P. x2 m' p
// ClassWizard generated virtual function overrides
3 F0 ^$ j( r% u  B5 j* ] //{{AFX_VIRTUAL(CHsPMEButton)
' ]. x7 \6 B7 \3 ~6 vprotected:# G$ a3 }, g0 i( }
virtual void PreSubclassWindow();+ {9 b5 e2 Z) W0 Z8 b
//}}AFX_VIRTUAL/ x- x2 w- p9 F1 E' M

+ K; y* m7 X* u // Implementation
7 [6 I3 N$ U' C  ^$ Z$ e9 Lpublic:
! {3 @3 Y# d: l9 `/ \ virtual ~CHsPMEButton();
" G5 I( j" @# ?" n# S. j. U
. v/ V7 ~( _/ t9 U/ O // Generated message map functions
' s: {, t; ~9 I' E6 U, Q8 q2 \protected:% E' \0 c# Q5 i) T3 H0 G
//{{AFX_MSG(CHsPMEButton)# V+ k1 |3 G6 I6 `0 E0 X
afx_msg void OnMouseMove(UINT nFlags, CPoint point);8 g- R" U- i/ M( C9 V: j8 P
//}}AFX_MSG4 {4 [: d0 i$ ~) i% C( }. e/ Q

- U$ Q* i9 M. X% j# l0 J. _2 o) W4 E void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);+ W3 D9 ?) E" l2 i& h
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);, H3 b; H6 E/ U. O
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
3 n; Z, \6 F1 A. k" W7 ]: W LONG OnMouseLeave(WPARAM, LPARAM);
  N  g) D& w$ q1 Y/ o BOOL m_bIsMouseMove;8 Y$ N" B" S0 }' U3 Y$ {& [

1 T0 \, z$ N0 i* _5 ~, q COLORREF m_FrameColor;+ x6 H4 O% P9 P6 E2 q! @* R/ J
COLORREF m_ActiveColor;5 r9 c* |# l/ q

% o& w. {* x$ F9 r0 G3 t COLORREF m_ActiveTextColor;
* B* u1 C/ n7 C+ u4 p COLORREF m_NormalTextColor;% a2 U7 `" M2 B
COLORREF m_SelectTextColor;: E: F& V* ]/ S5 X

, X$ T; ~; [) Z0 H& m' S4 ?: K COLORREF m_FrameHeight;
: ^0 w! Y3 _4 D8 S8 ^# O COLORREF m_FrameShadow;& ]; R: n; h" s/ W
+ x- g, a7 O* e, P% Z  j
COLORREF m_NormalColorTop;* q. c) S: Q# t' o6 R% I5 b
COLORREF m_NormalColorBottom;
/ H6 D- w. X5 F: X8 D' F6 t4 @; @ . c3 C+ C1 d4 S0 w- x
DECLARE_MESSAGE_MAP()% }0 i: b0 W1 e6 T
};
/////////////////////////////////////////////////////////////////////////////
9 _3 H$ J4 ?, B+ T// CHsPMEButton
CHsPMEButton::CHsPMEButton()
  E' O, P/ n, f% ~1 o8 X{
' |7 W9 Z/ K1 ? m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);" v9 d  w1 n' ^* a  _1 [
m_SelectTextColor = RGB(0, 0, 0);
& H! d- ^* K& x6 Z" f m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
/ G  S! J3 U7 K; A$ X$ B m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
8 ~6 w: k# r% N3 Z( H( i% F" v m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
! }6 p2 k4 W1 |, N. ?3 s  x" ] m_FrameHeight  = RGB(230, 230, 230);! ]3 `/ U- S/ I) p
m_FrameShadow  = RGB(128, 128, 128);# y! V# z0 V1 w0 |" @3 Y
}
CHsPMEButton::~CHsPMEButton()7 P% [; F" @2 X% e+ ?- [. L, z" V
{
# d- b0 t8 v6 o}
# L+ i$ v% `) {
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
3 n6 W: I; t2 B- _$ j //{{AFX_MSG_MAP(CHsPMEButton)& u3 K( I* e  `' n1 H
ON_WM_MOUSEMOVE()* R- e7 h+ |) w; y
//}}AFX_MSG_MAP
& L& i- n& l3 V) |2 W7 r; p. X ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)& S0 c* }9 W' R& {( N+ f  j2 K, t" L
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////! h6 \' q, X9 r" j* {: m9 z
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ); {0 v/ r' P- J5 c3 W
{
7 b1 T! h; z! E //*
/ z! b2 y) Q4 A6 |$ x CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);/ c' l/ F% ?: F3 O
DWORD nState  = lpDrawItemStruct->itemState;0 X  A1 t7 J' L  y, d, K
DWORD nAction = lpDrawItemStruct->itemAction;
" [# R. z* {. L5 i* D CRect rc   = lpDrawItemStruct->rcItem;
* B3 B/ a) _3 R5 \$ a( ~, r5 N UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);5 x9 r' w' g; k9 l( @9 t. h7 X
CString strText;
4 o. ?3 q/ Q. e) V GetWindowText(strText);
if( nState & ODS_SELECTED )
* C2 S' l0 A% T: h% v& c3 l {
1 G" b* v" h- H. n" L1 p  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);% r  C1 L; W4 O: D- y- L
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
+ G( S# f- a; y  E: w9 j; `: s  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);2 D+ E' G  o. N0 ~
}0 C7 a) {0 A0 B. y
else //Normal; ^& O# y5 k2 m
{
9 G! @" y3 |) V% T6 p" c  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
: ]& V3 c4 \' M9 p& m  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);- n2 |% {! f' L0 T$ m. ]  Y
}
if( m_bIsMouseMove )& y- {, F0 c5 J! ], Y3 F
{
4 G0 o: @7 V  j, f9 q8 L/ K  CRect rc2(rc);* W! F" w7 P3 k! ^9 |9 K! d
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),( |' F4 `' L9 s3 p0 g+ n
   m_ActiveColor, rc, rc, pDC);; [+ v/ V" y% s1 {0 [5 u3 ]
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;; u  k! K" f. R( _6 W: ?
  NullBrush.CreateStockObject(NULL_BRUSH);
8 o. Y5 |; B8 z! f/ [  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);% M+ ?  j+ s, L% X% T" U6 j
  ) m, }. i, W) m7 l
  CPen Pen;1 W# Y9 \* p" z( Y9 m
  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
+ K, m# z0 {) c2 A! H: q4 Z  CPen* pOldPen = pDC->SelectObject(&Pen);
& D: m, w, m0 V( O- A" c0 `4 \  rc.InflateRect(1,1,1,1);$ V  D/ b; m+ L$ u$ M3 K
  pDC->RoundRect(rc, CPoint(3, 3));
1 r/ b" H5 W$ O, {  s5 \$ `  //rc.DeflateRect(1, 1, 1, 1);
9 |8 @/ s9 h! l8 a  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);- |1 u2 Q( k* L! L0 g
  
* N& a% c* F3 L$ q  pDC->SelectObject(pOldPen);( q& y/ B+ _! z' U! `
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
  _3 d* f/ o2 x+ o3 I5 N% B% ]% z6 K7 h }) H9 G5 G% b* D- W9 H& d

# \' U& V, d& y6 ]* M+ v2 ] pDC->DrawText(strText, strText.GetLength(), 1 W: V4 ^+ S7 ~9 s
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
! \( P! z9 l! |- j4 s; Y //*///  W5 q* j, q0 }5 ~
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
. g- Q$ g: w! _/ j; m1 {1 A{
+ t" U5 u2 O. n' ^. C  h7 m, V" K // TODO: Add your message handler code here and/or call default9 b$ M0 q, b. B
if( m_bIsMouseMove == 0 )) \& m( n' ]; v  q1 @+ J" m
{
* Z: G7 b1 z. s% b  m_bIsMouseMove = 1;
8 O' k' ~  ?( {. @1 t* P9 E' Q, d  Invalidate();5 @; l, j, e) m2 o3 G. e8 u( T2 I1 f
  
7 ]4 U5 g* ^1 K9 o! e4 U  TRACKMOUSEEVENT trackmouseevent;
4 Z, w5 V; W% R1 U; I  trackmouseevent.cbSize = sizeof(trackmouseevent);0 q! z5 F* T, t4 u5 u& W+ l
  trackmouseevent.dwFlags = TME_LEAVE;7 r& i$ n" l: [
  trackmouseevent.hwndTrack = GetSafeHwnd();: w4 p( y& q9 m
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;& H* e, m- o8 W0 y
  _TrackMouseEvent(&trackmouseevent);$ O/ m# S, X! K& B
}. [  l  H6 A6 D* x5 }: \

$ v) ]9 g6 A9 `3 N( E CButton::OnMouseMove(nFlags, point);  k% b6 e" |8 }% b0 e4 p$ g: k
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)' P# c. g" s2 {# C* r# K
{
% ^. \6 v% J; J m_bIsMouseMove = 0;& J4 h+ U5 _) f9 }+ @
Invalidate();
return 0;
* u# p3 }: v, f! T}
void CHsPMEButton::PreSubclassWindow() - E" p9 W4 t1 G7 E& k2 ~  d) |8 L
{
+ g& W3 @( L9 e. D. v // TODO: Add your specialized code here and/or call the base class+ j; t4 J: I/ j, {0 G8 _
UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
3 M1 {! b- K4 M: M: U2 p SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();5 \% y7 S- N" b. I$ i) f
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
/ o- r; q3 _+ E! x) Y" J- ~{+ B/ N) q" Q  l/ _- Q: s1 s
CPen Pen;# p  _# ^$ z8 C7 Q7 E
CPen* pOldPen = pDC->SelectObject(&Pen);' T* `# M, l6 p& y  D5 a  O3 w

. g' A/ |7 c0 O/ V! U/ y int R, G, B;; Q) e5 Q' m0 {8 F& _
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
# @4 U3 K) O* }# C0 Y( n" X: O6 q G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
! r! f" w' n& S B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
1 H. `7 p& m; j
/ Y! f5 m4 A: e# E; t //R = R>0 ? R : -R;
& e4 E1 m; r3 U6 Z1 k; M //G = G>0 ? G : -G;
* ^- g: e- w/ E( S; e  t. }( s //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);0 v  j- L/ t$ a3 y' q
COLORREF ColMax = Top > Bottom ? Top : Bottom;9 o* \; J* U' Z5 p; m# x
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
3 i' E: J. A; L4 D( M* X( g {2 m( p# w& G  h: b/ |  ^" I
  ColR -= R;
( ?* }- }: s) r# @0 l7 C# o  ColG -= G;
$ U( F9 P, o$ D) @  ColB -= B;
  /*
1 F$ O; T3 S5 ~2 {5 V: j  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||& H0 y+ s$ G2 D$ w
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||# m  m, r! F9 ?( t+ p
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
* y5 z7 P1 ]) h5 S3 E* r  {
3 k. `9 z* E" d* l( O- f, {$ f   R = G = B = 0;
/ P# Y* l4 b! o  }///*/
+ s2 P9 ~7 j! q0 [$ N3 U
  Pen.DeleteObject();" X! q4 A! a, G9 ]/ q
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
  w! K) R3 S+ M2 @# Z0 T    0 i. y4 x2 @. |7 g0 W
  pDC->SelectObject(&Pen);% Y9 g" d3 U, y$ [- n$ o. O, i9 h
  
: b  ~8 P# {( ?: A/ l  pDC->MoveTo(rc.left, rc.top+i);
* C3 p; ^8 C9 \  E( E* e  pDC->LineTo(rc.right, rc.top+i);8 ]+ M! j, D" V2 o
}
pDC->SelectObject(pOldPen);
" R& T2 w- J# U" A9 D, r}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
4 [0 `$ v3 {9 m6 q5 {  L- C{
! T7 K8 F! Q" ` CBrush NullBrush;
" \" h6 M3 k8 G1 M7 T" H NullBrush.CreateStockObject(NULL_BRUSH);
) L( f2 @  u. A! \4 \6 [" ~ CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;, H* K" t: s% C& ]  y* G
Pen.CreatePen(PS_SOLID, 1, FrameColor);
" L, K0 I3 _* a5 Q7 ?. l+ w CPen* pOldPen = pDC->SelectObject(&Pen);: z, G) p4 c( r+ i5 T" j
/ J0 R% ?% s" D# c1 i+ ^
pDC->RoundRect(rc, CPoint(3, 3));8 K; x4 w, H) w, X! T2 [0 p
rc.DeflateRect(1, 1, 1, 1);
5 D8 X: S+ u* } pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);9 J9 u  E' [& ~+ [. f
pDC->SelectObject(pOldBrush);
4 L0 y1 u& l8 h}

7 N* u& N; l6 k4 X: l0 F, @/////////////////////////////////////////////////////////////////////////////, m2 W# q1 D  B' Q
// CHsPMEDialog dialog* Q) u8 s5 B; [6 [7 a
//-----------------------------------------------------------------------------
: T" b. L1 Q0 k: p// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
2 y( C. N4 B4 }- M9 a% s//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
. F4 X! n1 N( E//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口  @1 ?; \  {8 m3 d$ _0 ?: c
//   指针将其显示出来,然后隐藏或销毁自身
6 x- r* Q) G+ o( r$ q( `//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
" j4 ~  K* \. v& P6 _- C9 i//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
  r4 v8 o! D# H! F. G5 t//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
- q5 t6 [2 D) n8 I! ]* i/ n% U/ P+ `//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。) A# j6 S5 I! E* A3 J- T
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。1 X) H* r. D5 n8 L
//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框( U( t) t( }+ \
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。
9 e* j/ p1 D& k$ u/ `% n6 t//-----------------------------------------------------------------------------  t7 D0 E: z6 X3 B  h; h5 Q
// 注意:
2 {- p: a: r' w- j// 1、在构造对话框时必须给出其父窗口指针( ]/ e6 T; F5 `$ j2 V' ]; b8 L. s
// 2、在初始化基类时必须指定对话框资源模板ID6 f% x$ U, j8 ~
// 3、对话框资源中必须提供ID为IDC_BACK的按钮2 ~/ F( S$ I+ R
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
* }! ?( W/ r! G//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog% `2 p, A( F5 v/ ~" S3 f" M/ {  D1 g
{5 K, a: ^$ c! D9 L4 a
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能/ D. v! R* ?+ _; ?; e
// Construction
& p5 J, l( |& X6 S8 upublic:) s$ h  r  Z4 K) d5 z7 |. a
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
  P& n) @# v( B% Q/ [0 Q ~CHsPMEDialog();) [9 F8 }  R1 r4 D
BOOL Create(CWnd *pParent = NULL);
' H4 U# ?) s/ k0 |/ q) P
  ~0 {$ b4 [* v, g* }// Dialog Data' `3 @" ]' t3 K
//{{AFX_DATA(CHsPMEDialog)) N$ {+ Q$ Y% r/ b
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };3 D& y- t) J  c- a9 A0 i
  // NOTE: the ClassWizard will add data members here6 R+ T/ @8 U* L6 k1 c3 ]9 X
//}}AFX_DATA

% x# p5 |- R- ]) j7 }0 r+ i// Overrides
) i1 Z- M& i5 a6 V" E // ClassWizard generated virtual function overrides
$ F  S: `5 F) Q //{{AFX_VIRTUAL(CHsPMEDialog)
) s$ \4 i4 b9 o5 @# t2 _ protected:
3 o$ p) }1 W/ [; i2 j! S( ` virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support& F6 T+ w3 l3 @1 K! h
virtual void OnOK();
, W8 ]( M9 t: Y- T+ W. T. Q virtual void OnCancel();
9 N1 ?3 U. j* X) _ virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);% d2 Q( |6 M" T: x6 n' p0 P/ V# h* k
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);9 _! ]$ ^6 k2 j4 y) a4 I) V- N0 ~
//}}AFX_VIRTUAL
// Implementation6 u; p4 }% Z* ^8 ]  e+ f* _% N
protected:
// Generated message map functions
: O/ T2 u0 w0 c  G$ e* m; T //{{AFX_MSG(CHsPMEDialog)
* Z8 T" i' W4 d4 }& J! n afx_msg void OnBack();
! `* a# y$ h9 H! D3 C virtual BOOL OnInitDialog();
% f2 U8 P/ f" J( {. ^& H afx_msg void OnDestroy();: ]+ O4 Y: @2 Y- D
//}}AFX_MSG
9 M6 ?" C! a: o2 d+ Y& P- P DECLARE_MESSAGE_MAP()
protected:
8 y2 O' Q# x" X! K // attributes  D  [9 w, N- x/ e) I0 R
CWnd   *m_pParent;     // 父窗口指针
# r" K6 V5 o. B  `: | HICON   m_hIcon;     // 图标
$ F, a# W/ s. _" I: J UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
! p) D) m1 V; M- _* N4 a CHsPMEButton m_btCancel;
" m  V" f7 F% y  p- C: I CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
- c- c3 }, [# n: a9 E HHOOK   m_hkCBT;     // CBT钩子句柄$ _. ^* p2 f" d

! i+ `8 y' [* M, E" h: V2 g //-------------------------------------------------------------------------& \. C# v: |4 ]; |9 Q" m
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
. l* \5 V. [# C2 j // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
8 O% j, T1 C- W! o" R // 链表的头及下一个结点的指针
4 u8 j5 ^: ~" t1 G  V3 e static CHsPMEDialog* m_spHead;
0 @3 Y3 w9 c/ i! @3 Y6 K6 x CHsPMEDialog *m_pNext;
// operations
& Z- O1 M; d- ?7 c  ` // 键盘钩子消息的处理函数
8 _; |0 |, C0 S& N9 f- q8 }- C* { static LRESULT CALLBACK KeyboardProc(% }5 V2 B6 r; }* {6 C$ j
  int code,       // hook code/ ?( z3 n9 b+ P; h0 i' j
  WPARAM wParam,  // virtual-key code2 D# g: Q0 o- J3 s4 `4 y2 m
  LPARAM lParam   // keystroke-message information5 y6 w8 |8 D9 P$ P3 n* @+ _
  );. n. a, H$ X- o1 c7 n3 G# |
// CBT钩子消息处理函数& X5 ^  A4 U3 Z0 a
static LRESULT CALLBACK CBTProc(
$ O  ^; Q( O7 p( i  int nCode,      // hook code. X" L% ~* I! R) ?- i1 S* D5 L
  WPARAM wParam,  // depends on hook code6 V  s+ G! R& Z- g: e/ V  t2 E
  LPARAM lParam   // depends on hook code
; F& N7 J( ~* y5 N; v  );/ c) \# l2 i6 b1 |6 ~8 A
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口! p  p( e- v' z" ~
static BOOL  IsWndKindOfThis(HWND hWnd);$ [! z4 n6 V$ x! A
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址): [' G6 ]0 r9 _8 D" @- W' S: u4 g. C, V
static HMODULE ModuleFromAddress(PVOID pv);+ ?$ l9 X7 R9 _+ z$ h
public:
. ~8 G/ m! K/ t9 @6 S/ D // attributes
// operations! _- V) l1 C! Z9 N
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框
* e+ z0 V- B2 E8 I# D- V BOOL CreateChildDialog(CHsPMEDialog *pChild);: t8 W* P' U! W8 M/ D
};
* J* E8 r/ j- p7 B. Y
CHsPMEDialog* g_pHsPMEDlg = NULL;5 Y4 r7 w; ]7 D* |2 u4 e
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;4 _, p( o- V2 m7 U" U3 M9 e
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/). S* L$ _& w* i, w' D# t
: CDialog(nIDTemplate, pParent)
& z* W% z3 w; }9 ~{/ K' B7 t2 {) y" s! t8 y5 y
//{{AFX_DATA_INIT(CHsPMEDialog)
( o4 H3 Y0 _/ S& D  // NOTE: the ClassWizard will add member initialization here
. P9 t. W, w1 V# K  ]5 S- o //}}AFX_DATA_INIT' W1 v- I8 I. w* O  N5 i0 a
m_pParent = pParent;
# r0 ?' m5 c. Q m_nTemplateID = nIDTemplate;4 {$ ?& B1 E- j' O- l
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
9 d: `( }7 `5 i+ _4 e0 g m_pNext = m_spHead;
" d6 X5 r' P& @& W m_spHead = this;
" ~) _" ^( [+ z3 @- Y8 V7 W# P% b. s* n' H m_hkCBT = NULL;. o  O4 C, f$ A8 y+ _
}
CHsPMEDialog::~CHsPMEDialog()8 _& e: G) V! \  U- _
{
) H  _  z8 H% I2 Z6 b // 从链表中删除本结点/ p2 F. o$ ~9 m; \
CHsPMEDialog *pTemp = m_spHead;
0 ~3 e8 D0 l  i. y" d  o if(pTemp == this)6 x; i2 E% u" E( Q' N
{  y' i8 G+ [: [$ V
  m_spHead = pTemp->m_pNext;: P. a4 u) G" H, C7 r
}
) c9 @+ p, S+ M* t# A6 v, l else; K) M6 Z1 ^8 `9 K
{
* Z$ N! G: u: @& r/ D, b) n  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)2 j. F# P) J: F, m) ]) t, H, Y
  {
; d( U; @$ G$ z   if(pTemp->m_pNext == this)1 `1 w  w- y* f% T' Z
   {/ i# y) z, m' E8 l5 t
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
% u0 r. y8 }$ L0 q( a4 K    break;
0 O4 [) r4 R2 c  y% l$ M  |  F   }
, W1 r! w6 F7 _" Q  }
; u8 J2 @: h( o0 y, W0 s }! X* Q* |: K2 Y/ }' ~
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
8 e5 y* Y$ W9 C" t4 `{
/ H6 C, d; m, ?, @" K CDialog::DoDataExchange(pDX);
& b; Y! @2 e4 J# M, e: g //{{AFX_DATA_MAP(CHsPMEDialog)
7 h" ^# _9 [, S8 W* l DDX_Control(pDX, IDOK, m_btOK);: g" x, S$ T7 G" a2 A5 C
DDX_Control(pDX, IDCANCEL, m_btCancel);7 Z( @4 D3 @* s! f. L9 S' R$ ?
DDX_Control(pDX, IDC_BACK, m_btBack);4 _2 J9 L4 R" H7 t3 O; F$ Z
//}}AFX_DATA_MAP0 U' \# O) b" M( }8 p/ H
}
- k: d8 ?7 W& F! L
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)/ P# Z5 p+ n9 a% [" Y) R  S
//{{AFX_MSG_MAP(CHsPMEDialog)
5 A0 D" R7 ^& P# L% G& ~$ i ON_BN_CLICKED(IDC_BACK, OnBack)
  d/ n) p# q1 i# ] ON_WM_DESTROY(): C5 [: P; W4 o
//}}AFX_MSG_MAP
+ T3 I. ^6 R8 ]) i# |3 L$ P0 N8 FEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////. N7 G# U0 ?5 t* S
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)' z9 ^# B0 N' f6 ^
{0 n  \5 p* O2 u
m_pParent = pParent;3 v( Y+ X. X& ?& S
return CDialog::Create(m_nTemplateID, pParent);! f/ o2 R5 C  l# X- V/ d8 {
}

$ U0 d" J' s: A$ ABOOL CHsPMEDialog::OnInitDialog()
$ \3 K5 G, |# [/ D( r& i{$ l6 ?% Z9 j8 {+ P. e
CDialog::OnInitDialog();
// 设置标题栏图标
/ ^5 H# F" n- V+ `) s& H3 A SetIcon(m_hIcon, TRUE);
% a$ i" H! ~) H9 R  i% a% n SetIcon(m_hIcon, FALSE);
# h5 G) r9 l1 o/ b
6 c) S3 d0 q- ^  K$ Y // UG的对话框的几个标准按钮没有TAPSTOP0 _. v# \% @9 X0 E
CWnd *pWnd = NULL;
+ n# a7 }1 {0 ]6 n! h9 |6 R pWnd = GetDlgItem(IDOK);( C# C) i7 P2 M- ^
if(pWnd)( q( M( i9 @1 N4 T& N3 d! x& j
{. l5 v% V; c- P0 W& u/ y0 J: n. Y2 c
  pWnd->ModifyStyle(WS_TABSTOP, 0);
0 D5 Z, G- q1 Z' U/ ~. Y+ X; N9 O9 s }6 P0 W4 w# Z0 T1 o( x- O
pWnd = GetDlgItem(IDC_BACK);
5 G) D& H! _' B3 C1 n9 ?% O+ n if(pWnd)( R6 [6 N6 P( k
{* h! _* W& [) Q, K: }- h4 b) j5 E
  pWnd->ModifyStyle(WS_TABSTOP, 0);
' s3 L1 H' `% I }' F. \0 v$ g5 _. p
pWnd = GetDlgItem(IDCANCEL);, u) l' f7 z. G
if(pWnd)
  z8 h5 d( e, a9 W, J9 A4 { {
0 X' q9 ~# l: Q  pWnd->ModifyStyle(WS_TABSTOP, 0);0 P7 _6 `1 e* e( a! i/ n1 T* G& h2 v
}
( W# f" R* w! z. B" Y1 `6 V  L ( X* T0 G* O0 T7 l* S3 s2 B
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子, c( w$ O: _$ @" z7 s- Z, p/ d
if(m_hkKeyboard == NULL)
, N1 g& x& ~% d {( `7 M& S/ a/ L& X2 q. Z
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());- C9 O, Q% W7 y: n  e' E8 k+ t1 m
}
) W4 H% R9 R6 N" _) x if(m_hkKeyboard == NULL)$ u9 `* F" E# ~1 S8 U/ N
{$ M! u* s# ^5 p! _
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());
3 t. @5 G& ]6 x/ p# n' x }
if(m_hkCBT == NULL)
3 J6 w# e8 I1 _- o {
, `* X8 ]5 a; `  n' l/ G- ~  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
; _6 I( B" l2 \2 h' ~4 l2 a8 f }- ?& C1 t- w! Z( r
if(m_hkCBT == NULL)/ T+ R/ s  g1 c7 z1 m
{1 ~! Q( _2 Y& }( ]0 X
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());
9 E( [3 `% D  |2 W }% V6 C  n0 A" _7 w1 H

0 J5 W* B- a; s9 N return TRUE;  // return TRUE unless you set the focus to a control0 ?8 ]! X, H9 R
               // EXCEPTION: OCX Property Pages should return FALSE* j& B8 e( v2 W: f5 j
}
void CHsPMEDialog::OnOK()3 O3 j1 y( N( \# S" k% j/ A
{
) B5 {7 K$ U' P4 L4 C/ B8 c2 S CDialog::OnOK();
0 [( t9 }6 x+ t/ D9 r; M if(m_pParent)
: E; \1 q* Q) i* B+ H# }( v8 d {
# `6 T" W+ [) Z/ B0 b# ?! `  //m_pParent->DestroyWindow();
( I, t1 q- o& Y8 Y  //((CDialog*)m_pParent)->EndDialog(IDOK);
* Q+ G: N  e( U' L! p. h  ((CHsPMEDialog*)m_pParent)->OnOK();, v& m; E1 }2 I5 O( v2 a1 C
}
, X; t! P1 u- ^7 u" ?8 S  V}
void CHsPMEDialog::OnCancel()
6 l9 e2 A! i$ w: z  D) k% F% k{
* [( Q7 j9 x: \1 u3 N: @$ A) R3 X CDialog::OnCancel();
* a3 O; D$ @6 Y" t5 U' q if(m_pParent)
2 H2 {5 I. {1 o4 J% h {
' M, L# d/ k% q- E8 U6 T  //m_pParent->DestroyWindow();% W0 X* B! T  _
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
! O( q) o4 w! O% _/ p. K3 b$ f  z  ((CHsPMEDialog*)m_pParent)->OnCancel();
6 n: f7 D  \7 A' v& M$ e }2 @7 N5 H, G+ P1 y
}
void CHsPMEDialog::OnBack()1 l2 S7 h' i" Y* _
{
% E7 d+ e; I* D$ m if(m_pParent)
. q  [' C3 |! a, L/ K {7 m. Q. ]- l" T6 s6 ^
  m_pParent->ShowWindow(SW_SHOW);; Q5 x  P: P% f: U
}
5 [/ c8 N2 J" N, Z' s% a5 Y( ?' ` CDialog::OnCancel();
* Y6 T" E( B' Y3 M8 @7 _}

  T5 B5 X- M7 Z" T3 v3 |BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)% q9 q6 X  i" f. I
{
: `( i7 Z) J2 R9 } BOOL bRet = FALSE;
5 ^1 h" j3 e$ O  ~2 ~# ` if(pChild->GetSafeHwnd() == NULL)  X: O( v. M! R
{
1 W) J( R+ F2 _  bRet = pChild->Create(this);0 `. k" L& \# o8 ]
}& T' K# u" c  k! h0 o
bRet &= ShowWindow(SW_HIDE);
0 o( o. N# a3 t  l" ^- U bRet &= pChild->ShowWindow(SW_SHOW);
' p3 p" D9 x; W1 ?7 W return bRet;
+ d* Q% g7 f" d9 K; g2 ?; p! K2 h}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)7 _* v5 [1 h& l! C) Z! O
{
! P0 B1 A1 U2 k  { if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup# J& O' m* a& m+ d3 H3 b
{: E/ q/ I8 d1 V! k
  //TRACE("Key down/n");  t  U9 k' q* ?% Y! |8 ]
  CWnd *pTopWnd = CWnd::GetActiveWindow();
3 N1 d7 C" l; Q1 D$ b1 {& U  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))4 j8 {  x6 o6 C. R
  {
( i( K' }7 C2 e6 F' P% m4 H   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
3 v' G5 j2 j( T( ?) d7 @7 V   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)! H8 C9 j8 ^5 p
   {
+ j7 g- l' H* q& C7 h/ Z    // 只截获tab、esc及回车键
* [( T. T; G! ]; O0 D# \3 E    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);) }, A( V5 Z; d( X: [1 m( Q
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);2 T4 m& Z  T1 X, u( ?" E
   }
& n# B4 d# q9 l' ?% H% F# U, T1 _% o8 K   switch(wParam) {$ y3 F' m7 H( G0 r: h' A, f+ |3 a5 W. D
   case VK_TAB:
7 m- S6 s* L7 ]; v' q2 }6 h: v! F    {
" T1 }% h6 g  R2 p     CWnd *pWnd = pTopWnd->GetFocus();9 R/ d1 @# R+ W$ Y  E. t
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
$ V( T1 M& g3 E& _! V2 e     if(pNext)
" u8 _1 _# z! {6 b6 B! F/ l% T     {
( r( O3 R7 x& g  U3 V3 F      int nCtrlID = pNext->GetDlgCtrlID();
; M5 R8 o9 ]/ f7 u' L: v) U/ x      //TRACE("CtrlID = %d/n", nCtrlID);' d5 P1 l6 w3 W; _7 x8 d
      pWnd = pNext;! s- S/ S0 C" L2 e: j7 [
      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
, {- K+ c! Z+ p; X, b      {
- _( g: _) D3 Z: F0 @       // 根据UG对话框的属性,这三个按钮是没有焦点的
5 b7 v+ W3 a) ~1 W       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
0 c0 `# h1 G1 F" c       if(!pNext || pNext == pWnd)2 i* r! A# [; O: c0 M
       {
9 I! P4 W$ y3 v% i" x& r! v" ?& e6 D: A. k        // 对话框上只有上述三个按钮
- m& E0 w5 g8 M        return CallNextHookEx(NULL, code, wParam, lParam);" L6 i" s( N, L. }0 M. Y7 x
       }; |7 D; c- o( v
       nCtrlID = pNext->GetDlgCtrlID();' X. G. u' l/ w0 M& b, K* t$ S
       //TRACE("CtrlID = %d/n", nCtrlID);
3 R" z! U' E: {, ~8 f) K- _$ ~- \: m      }7 ^5 e8 I' U5 U5 S  R! _( P
      pNext->SetFocus();% g6 s* f2 g7 q. S, j
     }
/ Z0 J  k  {2 b9 j     //return TRUE;7 C4 P( a4 r/ W" }
    }
4 N- l$ i- D6 s5 T    break;- Z, ^0 ~$ `& G5 V5 s
   case VK_ESCAPE:, V1 {* G" G, \' L
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
$ }# O: J+ [2 R6 U    //return TRUE;4 Z+ [, a; T' X* E. c5 v
    break;
0 B5 G( T+ t" Q9 F4 x0 n   case VK_RETURN:
4 [5 f  H; o4 K! R    // UG实际上并不处理回车键  `4 a  F7 _) q* x5 o! q; G
    break;8 V2 m" s" `- C# T! s; K+ t+ p
   default:4 q- {3 U- G! a0 N
    break;
* a8 v  }% t" U6 R: E$ ]   }
: B/ q6 ?7 o# ~# @/ w1 ^% W  }! `8 M( F" [! f/ x$ |
}$ ~. X/ n$ E1 s) Z
return CallNextHookEx(NULL, code, wParam, lParam);
# X' E5 J0 [$ ?6 M: z- J9 ?2 ^' y# C}
void CHsPMEDialog::OnDestroy()
$ u' \' i% f) n  ^{" L5 k# {2 n! m6 F8 V$ D
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子7 j4 k; ?5 t& W# Y( Z
if(m_hkKeyboard)
, Y( x' L( u- B5 `0 ^. ` {
' Z' u. |* n. k6 t% C! b  UnhookWindowsHookEx(m_hkKeyboard); 0 l* v+ t! B! M+ E9 ?
  m_hkKeyboard = NULL;
! f# ]6 N) P8 r& n1 B/ \. z }
if(m_hkCBT)
1 e! o3 R# h) b5 l- {; l+ R6 D9 W! e9 H {
6 f1 \7 @6 t1 c3 A7 |, E6 u  UnhookWindowsHookEx(m_hkCBT); ; I( k: `* x2 x9 ]. j
  m_hkCBT = NULL;$ u+ m/ j) {( `! i
}9 U. k2 ]/ H; O& _9 H" _
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
# g" R* c/ e) N( n5 S0 D{. {" ]8 x* `0 q
CHsPMEDialog *pTemp = m_spHead;
- d4 |3 v( N! c2 O, Q! n0 z7 ^ BOOL bFound = FALSE;/ B3 B1 }) [; \' F6 q8 X
for(; pTemp != NULL; pTemp = pTemp->m_pNext)2 l- A4 K: B9 m! i
{. W8 r! r7 A& _5 `- d/ r$ P# Y) ]- C
  if(pTemp->m_hWnd == hWnd)& H: V- `4 s1 h4 T5 v0 I- G3 M
  {# E5 @+ s, T1 e! y# ^6 t" `# @2 R
   bFound = TRUE;
5 P! C) g8 C& J: W. J( X9 H" Y   break;! g/ P$ p5 u4 W1 t: U5 v4 j# E
  }5 H$ l$ O' ?+ ]5 |0 f; F
}! z% m: R5 ~5 I( y7 M' g0 I  Z7 Z( n
return bFound;
8 [; G3 f" {. j/ S# f}
// Returns the HMODULE that contains the specified memory address
  g/ _7 S4 B6 C* wHMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv) 0 L7 c- i8 H6 f8 \/ n
{  w  X9 b7 R6 u/ h7 _
* G: [; w$ B9 L7 a; p# G8 M
MEMORY_BASIC_INFORMATION mbi;
, ]& x0 b+ v0 T return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
5 @* ?+ ~5 `( I# J! s  ? (HMODULE) mbi.AllocationBase : NULL);- u# \( H; `) n, [0 q
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
6 Q! J% V7 Y5 k( a( L# X{
( ]; F3 a; g9 @' {, M& k2 Q6 R if(nCode == HCBT_CREATEWND)
0 n6 h$ ~" w. E! B1 {! ^5 [ {
- W  ~0 M! m- W- k. A. a; k6 C  //TRACE("A Window is being created/n");, Z1 ^* \4 g! Y0 M8 a7 z' D
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;/ m3 x2 |+ W& G/ u7 E3 ?+ K' x
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
  |; _# l6 F: H0 {. Y) D  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))# d- J2 ]  D$ ~% @, e8 J
  {3 `7 }% R' w0 d/ t8 o2 v/ y
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
% L6 Q  i6 n0 Q   // 取得窗口处理过程内存地址& r1 T3 P3 m/ j/ t2 S. W* r
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);& y; w( B( j4 W6 r% d, h
   if(dwUserData). ^/ L0 Q9 ]2 [) W: e% a" |* w
   {+ G! `& q- W6 ]6 y- n3 p
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
. [, ^7 x- N$ B4 {    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
1 p$ e" u; G9 @+ Q8 Y" g    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
6 Y. N6 a. A1 ?7 g( B  L) R. ^    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
  d- V0 p, d4 D    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
" F7 J* M; x: A6 o+ ?0 A& t    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);- S" s% s: ?) C: w
    if(stricmp(szUGPath, szModulePath) == 0)
& I$ o( T. x' Y, Z6 c& p+ i    {
  R% _) o, P; w" h8 t1 J) n     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
, j* a. n! B" ^3 \# f4 i0 r3 c) u     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)/ ?( V! i/ a! K" g" B% m
     {
8 {9 v6 z1 F' k/ p      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)) Z6 C" L5 Y+ C. U0 {& M
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
0 A. K, p: v7 s4 n1 Q6 S% x       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd): g& J7 g0 G# ^) n: @4 |& B
      {# a% I& _3 H9 j+ {
       // 窗口非本窗口或其子窗口
% H2 ~% p, |9 A4 h" l% z       g_pHsPMEDlg->OnCancel();
  P/ b  h7 L- b2 h6 E$ f. V9 r6 ]9 W      }) ^3 W4 v+ u* J/ P
     }
3 i0 c) j6 z8 o$ [/ S8 b5 W2 [    }
) K4 @5 ?" S7 v1 c" K  t* n6 `   }
& O, V: O, C. r. j  }
. B( Y8 ^$ `/ |1 Q }. h* X( y9 C$ M& N1 ]# Q  v
return CallNextHookEx(NULL, nCode, wParam, lParam);
# g1 i2 h$ r2 U5 I" d}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 5 E( g8 Q6 F4 o/ s$ @0 n# O0 j
{
4 F/ M2 O* M9 E4 u // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
" N$ q1 s8 c) H
! N. b# G% j$ C: A9 ]! ` return CDialog::WindowProc(message, wParam, lParam);
% G& s% r8 m" c2 g}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
' A7 F" A3 g6 F0 [2 G{
6 k4 }. z, l* U' U) r, g  U
, S) z; \3 I' T; k  O return CDialog::DefWindowProc(message, wParam, lParam);
) e; \/ L+ J+ q}
7 g8 Q9 ?+ Y: I  l8 h* }$ C  J
上海点团信息科技有限公司,承接UG NX,CATIA,CREO,Solidworks 等CAx软件,Teamcenter,3D Experience等PLM软件,工业4.0数字化软件的实施\二次开发\培训相关业务,详情QQ 939801026 Tel 18301858168 网址 doTeam.tech
回复

使用道具 举报

发表回复

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

返回列表 本版积分规则

  • 发布新帖

  • 在线客服

  • 微信

  • 客户端

  • 返回顶部

  • x
    温馨提示

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

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

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

    我知道了