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

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

[复制链接]

2017-8-31 13:24:24 3214 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------/ A# k9 }& ^5 z* Y; b) _. r
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类/ w/ L6 k- j( h( Z
//    该类来自网络,稍作修改,版权归原作者所有
5 I( Y9 k2 n% Y" l! U9 v* X//-----------------------------------------------------------------------------
! \  l+ o$ X* x8 o* c* Fclass CHsPMEButton : public CButton
$ h  ?( T2 A. U) g4 a) a0 `{9 o9 M3 G+ S0 A4 y! l- l' R. _
// Construction. d1 {+ W3 t& Z
public:
4 {' O: I& p* F, B CHsPMEButton();) t/ ]0 m0 v" q/ |" u
7 d0 q6 A: h- r& Y0 V3 ^' W
// Attributes
; {" f' s0 U2 R0 r; Q/ [public:/ q5 H1 T2 B& S0 T7 [

) T- X! \9 m' l; t // Operations
9 v9 G' h' u; g% apublic:
2 E- t6 [0 L0 y, k: f inline void SetNormalTopColor(COLORREF color)
9 K& S# g3 n. X" Y {
; b! S! i2 X1 w* `  E9 l  m_NormalColorTop = color;
; a( T3 {' }; m2 i }
# X6 Z9 Q/ ~8 [) {3 S, Y inline void SetNormalBottomColor(COLORREF color)
9 t7 a7 K4 ^. o0 `$ N* K" x {" t8 a8 t: _5 F. @, E* Y) }' n& g
  m_NormalColorBottom = color;
/ s& N7 I7 E! `; z0 E  u }$ m, C% p3 E1 Y9 T; ^& S' e
inline void SetActiveTexTColor(COLORREF color)
3 S1 ]9 N$ f) v3 }) p8 o4 z  D1 _ {: q  d3 C& D0 [$ _1 T& E
  m_ActiveTextColor = color;
6 N0 P% M# z3 _: l3 m! [& ^* G }
3 _  R8 M' T! y8 o inline void SetNormalTextColor(COLORREF color)! n1 Q+ i9 L. [' K" |3 p. L+ t2 W7 x
{
  V  w; o$ P  C/ V2 I& @- t/ O, V7 ]  m_NormalTextColor = color;
* o- b/ i, Q; |" n- _( [: w) i }( L8 x+ B9 N1 ~. n) X" o
inline void SetSelectTextColor(COLORREF color)' }5 v2 h& G9 U5 P1 m& M3 i
{
; h4 L$ F. U5 ~! y0 b  m_SelectTextColor = color;! a  V% P: e3 H3 J9 Q3 D
}; Y. F: W4 d! Z% \  m" q+ n: X4 P5 D
inline void SetFrameColor(COLORREF color)4 A" a1 h; e. p: c! M$ Z& e; W
{1 a8 [! a4 ?- g4 D: K: j5 ?0 Z* d
  m_FrameColor = color;5 w. @, Y# R( R8 l2 c
}
! n% R3 O" D8 s2 p9 u inline void SetActiveColor(COLORREF color)
6 l& f5 w: E* A, f {; }+ I) j4 F+ T
  m_ActiveColor = color;, f6 r4 k" U, \8 n% j
}
, \1 @/ D8 ]% x, H // Overrides2 d/ x0 n% I, s3 X6 l+ Z
// ClassWizard generated virtual function overrides
' a, @7 A3 Q: U  i! r# K1 @ //{{AFX_VIRTUAL(CHsPMEButton)/ O, t1 |6 x9 x* ]8 h
protected:
, d- {3 W: J9 O' S9 V7 | virtual void PreSubclassWindow();: e. ]$ d) G: q
//}}AFX_VIRTUAL
# \2 ^# S- a* |- B. C% C9 E) b( K# j 6 c. N5 M! e3 d
// Implementation
( p7 @/ m1 J! }public:
7 E6 X  y! i9 t% V, V$ \ virtual ~CHsPMEButton();
3 `; A2 Q; h& ] ) D1 `" g9 a$ Z" z
// Generated message map functions3 ^* E# H5 ?: G% K$ k. y; g
protected:
  {8 O9 P, t- e/ ?, j, [5 ] //{{AFX_MSG(CHsPMEButton)
6 g/ H: V' {) I: g+ e8 I afx_msg void OnMouseMove(UINT nFlags, CPoint point);
" c" G7 n0 Z2 k" G8 M  _ //}}AFX_MSG1 H  M) Q" j* T. k* c

# m, ~" O8 r: A4 }- @ void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
3 X. I5 \& Y5 l- e8 I3 S void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);; ^% a4 V: Q, ?) Q
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
! G/ k1 J; m; A4 t; S0 T LONG OnMouseLeave(WPARAM, LPARAM);
' }( z. e* f+ k% T2 Z: Q( H  ^0 ~ BOOL m_bIsMouseMove;
) k' Y7 [; h' ]- ^3 U  Q" ?0 }/ o - \( o0 f: ~) ]0 Q$ O: T
COLORREF m_FrameColor;2 l' e: l: a4 W! d" q& G
COLORREF m_ActiveColor;
* F% O# w. w, k! a / f# O6 R" K2 g3 s4 ~& f8 o! E
COLORREF m_ActiveTextColor;: C" ^' U! C8 p& E1 E( q2 F
COLORREF m_NormalTextColor;
- D% T- N& x0 L COLORREF m_SelectTextColor;/ I  h4 ?( ^% ~# V0 k, f2 D

, f$ C; d. w3 w# d# b8 W" U COLORREF m_FrameHeight;) ^9 g$ ?" _* B% C: P4 `' ]
COLORREF m_FrameShadow;
' S$ c- N  y! C% t; @ 8 T7 B# u( ~% p. F
COLORREF m_NormalColorTop;. _: d! K4 P0 Y) i2 [
COLORREF m_NormalColorBottom;$ e3 }! x9 J) u2 q9 Q: q3 }1 W6 F

  M; n: Q& K# ~) | DECLARE_MESSAGE_MAP()
+ c4 U4 `: q$ N};
/////////////////////////////////////////////////////////////////////////////& i$ `4 J/ W# P0 C8 y& z1 n; h
// CHsPMEButton
CHsPMEButton::CHsPMEButton()' Y3 I; F5 n4 Z
{7 S) N# a7 i7 t3 }; G: ^( o0 J
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);  x& P, i, P9 j8 Z' E9 z" t
m_SelectTextColor = RGB(0, 0, 0);( o; k& m% d: m, r
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
: \) ~& @" P1 X' t- I" s$ Y1 r m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
# Q6 a) a2 e; {2 N m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);5 D0 N! e6 `- W- O. j  o
m_FrameHeight  = RGB(230, 230, 230);1 B! r6 U, k/ G8 E1 l; t: V8 Q
m_FrameShadow  = RGB(128, 128, 128);4 N0 C/ c$ `7 x; l8 Q" J7 i
}
CHsPMEButton::~CHsPMEButton()
; O. ?) J' i& L9 u4 H7 o, N3 Y3 i{0 C4 b+ H1 F* W; i5 y4 a1 q
}

+ {6 {8 S% R& Z+ S' b1 MBEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
0 m; K$ J% A: g  J //{{AFX_MSG_MAP(CHsPMEButton)
) L9 D& i/ n* {5 p/ v: {% D" \# Q ON_WM_MOUSEMOVE()0 l1 I4 A5 f( l
//}}AFX_MSG_MAP
2 h1 f2 N5 m2 W( b( s( O$ N6 k ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
9 `' J$ Y1 k/ K  }% kEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////$ \4 n1 g, W& y0 _( t
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )2 Q, q5 f& Z% |6 p0 M
{7 z2 z. l! i$ h; L, ^7 Z" ], z
//*
! d' h+ c7 t. ]6 W! f% R. R CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);" r2 Y) Z' b; X0 v' c) }. I% j6 O  w
DWORD nState  = lpDrawItemStruct->itemState;
$ a( ]2 h+ b% M: a/ H, K9 F DWORD nAction = lpDrawItemStruct->itemAction; 7 ~2 T+ ?4 ^* _& F. t
CRect rc   = lpDrawItemStruct->rcItem;
# L8 K4 E0 p4 l! z* ? UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);
' k. L, \) _5 R4 C9 k CString strText;
5 l; Q2 Y5 W2 k. Z$ l0 N; c! E GetWindowText(strText);
if( nState & ODS_SELECTED )- q. p$ {4 d# U
{
( V& u( b& ~5 f( Q$ t  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
6 I( ^  f9 @" T4 k/ E& N5 h/ s/ y  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
8 W4 h+ y8 ?: o+ |- V! K6 I  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);: Q! Z' Z# D/ T2 p" x
}7 y3 C, q. W% j3 O. ^
else //Normal
: M+ o+ l: L3 |/ f- b {
" ]7 X5 g& X/ j( r7 D, R+ n  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
5 ^* [! b- d9 U  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);  G" E( K5 E; Q
}
if( m_bIsMouseMove )& v# g1 v: B) o+ e
{, {' |( B% ?3 ?% K& t1 Z* R
  CRect rc2(rc);# ]+ k  k6 [- ~" [" ?) P; o
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
' ~' I9 x1 M) j% A) C& ^; w, g   m_ActiveColor, rc, rc, pDC);1 L' w0 h. H; H3 T
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;) p% l( z- ~; r7 x
  NullBrush.CreateStockObject(NULL_BRUSH);
5 G% O( d& ~( I8 z9 U* D9 E  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
$ {/ d- ]$ F, h* I  
* U6 B7 ]% ~6 d: `0 r/ m5 V& t. ]  CPen Pen;5 u" f* E% Y, }2 b  G# y$ G; V* _9 m
  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);# b+ e1 Y' x, X. ]9 f
  CPen* pOldPen = pDC->SelectObject(&Pen);& M  M' p1 T8 s
  rc.InflateRect(1,1,1,1);( {' U! F1 X+ C
  pDC->RoundRect(rc, CPoint(3, 3));
9 }" N; a3 N: S  //rc.DeflateRect(1, 1, 1, 1);
0 j3 y# q4 C6 r) _, I  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
0 u8 c4 a# K8 d" x5 C8 `8 D' I  
) n6 @, Q, A% t# t$ y- G  pDC->SelectObject(pOldPen);
8 s9 E# [% P( d( ]! F3 I  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
# S0 {- e8 Q9 P- Q6 w/ O2 b }' g# F+ `. J$ a" X

  v' l6 I: ~* | pDC->DrawText(strText, strText.GetLength(),
7 G. [) P9 S, V  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
) s2 p/ _  Z- E. Y //*///
: `8 n/ b# I/ m: G. F5 P3 e7 |}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
9 n/ ~. U$ x2 z0 z, U4 R0 i{
# O$ p$ u. v- K. c9 d& g6 B$ M( a3 O // TODO: Add your message handler code here and/or call default0 f2 E2 \+ m2 O! l& B" Y" G% M
if( m_bIsMouseMove == 0 )
/ n6 B7 U' ^2 g2 c: a( ~2 E/ [ {
0 s8 m; F1 n# h2 y( }5 K- M/ G0 K3 W  m_bIsMouseMove = 1;" J+ X; ]( ~2 X# b/ I
  Invalidate();* G0 L* D# P, [( _) L0 n% z2 t
  
( K" X0 ^' j7 H* U) }/ O0 B  TRACKMOUSEEVENT trackmouseevent;' R2 c& u( ?1 e
  trackmouseevent.cbSize = sizeof(trackmouseevent);
0 V) x: o; K1 I7 {  trackmouseevent.dwFlags = TME_LEAVE;; |- h1 F9 z' F. T
  trackmouseevent.hwndTrack = GetSafeHwnd();: W+ v0 w& }+ D0 x7 B* v: C! F. x
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
6 p5 |# Q0 B% i, i  _TrackMouseEvent(&trackmouseevent);
) V  Z$ ?+ s6 B) O) \0 L  I: i }1 j# [% U5 n$ [  |; T

/ e" V1 i) s9 S7 |( s6 R1 t$ s CButton::OnMouseMove(nFlags, point);8 b. A& q( }8 o, V5 K6 g6 ]
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
$ E  k# c" D5 i' E' E! z{
8 V1 n$ v- ~" `' K; z( ~! W+ W m_bIsMouseMove = 0;
) `: J. E% E! n- N7 D' | Invalidate();
return 0;
# M! t+ Y) w0 F/ j" \& O}
void CHsPMEButton::PreSubclassWindow() ' p8 F7 e- n5 j# I" _- ^- F# R2 O  u
{
+ G" N' ^8 y" `# E1 Z; @ // TODO: Add your specialized code here and/or call the base class5 Y! W! \/ c0 j% ]2 {# ~6 ?" k5 @
UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
) x  t0 M9 q$ x6 G) ] SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();+ d+ }# H, A) y
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)1 A( D6 @, K& f" N$ Y
{0 A9 m* m" h% P9 h  {9 h$ Z* s
CPen Pen;+ D2 b. H/ n5 g0 _
CPen* pOldPen = pDC->SelectObject(&Pen);
+ W8 ]2 H1 J! c; H0 E) e% i; n 4 \$ L& a3 Z3 N; G4 R# P
int R, G, B;8 r) g! m! ~; }/ Y* g, z4 y* x
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
. Y7 u; v$ R" e4 p7 q G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();! j/ B$ b" g* Z' B; F) J
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
" Y% B$ t- D8 {; k+ p- l 7 m# R1 m! `4 w$ z$ O6 R3 C
//R = R>0 ? R : -R;4 P# I3 }! c7 ]; d- ~0 C# b, O
//G = G>0 ? G : -G;
3 }$ G% q+ H: F) d6 i% N2 K  b3 ] //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
7 W2 ^0 c( ]; b/ a, c/ f COLORREF ColMax = Top > Bottom ? Top : Bottom;( S6 F9 v+ m* Q& z' x
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)6 n7 d, ?( B6 o( [$ Q
{8 |  C) F% A' C& N5 {/ |$ b) ~% B
  ColR -= R;8 p( Z7 x. G+ ~1 f
  ColG -= G;
6 h- C" X4 ^, T9 S4 m5 ^2 N  ColB -= B;
  /*
. g+ x6 h1 ~9 w6 l5 f8 O  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
) E) f  j: K' G* h6 `9 v3 ]   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
, E+ j/ C' X# b- p   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )0 J8 u7 |# a# X; }
  {) L* N5 A1 T# v: t6 v* M
   R = G = B = 0;3 p( ^* L. w( \5 {- L* t; u2 w
  }///*/

. K+ d! _4 M; D  n1 |# L2 _9 K( l  Pen.DeleteObject();( }3 \3 p" p* I
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));* M( J, s4 R( u; w: ~# r  @+ {
    0 q' t* _5 A. N, l( Y
  pDC->SelectObject(&Pen);" X. x! W1 b% \
  
* x7 r; r  V5 W9 }  pDC->MoveTo(rc.left, rc.top+i);& s5 ]* J6 M$ d. f; E* O6 c
  pDC->LineTo(rc.right, rc.top+i);
: I' T$ e' R' ? }
pDC->SelectObject(pOldPen);
" p- h& \$ @2 r6 z* @/ g$ m& [}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)* U. H$ U% N/ q, h7 c. l4 [
{
( `; ?' ^# h$ ^8 H3 R5 a6 d CBrush NullBrush;
" q/ H+ z* E: c5 ` NullBrush.CreateStockObject(NULL_BRUSH);& @8 ^( a$ F1 p3 ]% i, c
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
7 J2 o7 P2 N1 _; m Pen.CreatePen(PS_SOLID, 1, FrameColor);
) h0 Z4 F9 I5 u+ o2 H CPen* pOldPen = pDC->SelectObject(&Pen);
  k( d' b  V8 t7 {) W! @  G: V5 N
) t+ u' z9 s9 A% d( a pDC->RoundRect(rc, CPoint(3, 3));+ K, R& R: h1 H/ S. I  d
rc.DeflateRect(1, 1, 1, 1); + J5 X  j9 M2 z
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);$ r+ }4 c9 x& I
pDC->SelectObject(pOldBrush);
5 }1 m; K- @* U& G/ @}

) N  f- M8 Y8 \* X( ]& W% X/////////////////////////////////////////////////////////////////////////////
+ u6 G% U1 p, [% i4 {/ {  r// CHsPMEDialog dialog: ?* C4 Y7 P! C# O
//-----------------------------------------------------------------------------5 K3 I! q1 t3 Z% @3 f1 r
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:! j8 {) t6 ?% ]" u' c# X
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
+ s  h, b7 v" w7 t: o//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
9 l2 X% V- ]/ o//   指针将其显示出来,然后隐藏或销毁自身
, g9 ]4 k$ {  e//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
/ E! p0 e/ w2 }3 V$ h//    采用的方法为使用上面的CHsPMEButton作为按钮的基类5 Z1 \. N$ w8 x; l5 x! @
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,- F- ^4 {" R- e: j+ v1 M
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
# S2 z7 C  z+ N; K//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
% C/ k. E/ W0 U- B5 V1 p//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框' z" _1 p4 Z; T' l4 ?8 C
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。# J1 B% B$ o- y7 S% W; i/ Y/ e
//-----------------------------------------------------------------------------
* f+ I' k. e. ]- u// 注意:7 v* a5 Z( R8 w1 y) f' j* V
// 1、在构造对话框时必须给出其父窗口指针& O/ G" O7 i8 ?9 n
// 2、在初始化基类时必须指定对话框资源模板ID
/ T2 Y- I3 H, C+ B5 r( x- f// 3、对话框资源中必须提供ID为IDC_BACK的按钮2 [4 [8 `# v7 a; P
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
# H; q. x; f2 j/ _6 D) D4 ]; |. i//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
5 m2 J; U. W. k1 q{
- @/ B  q: e9 x5 R( @# u DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能1 N5 f  s, M- N. U
// Construction
: e3 _: K( l2 W6 H* Z" [public:
5 ?% x3 L3 ^& o CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
& c& e3 Y! y7 A ~CHsPMEDialog();" y& H3 e4 z$ C8 ]; f+ a
BOOL Create(CWnd *pParent = NULL);
. j% U: V( ?/ c# O6 { - B0 o2 u( ~+ K/ F! k' e+ i: i' V
// Dialog Data
- a5 A; M( I# Y) M //{{AFX_DATA(CHsPMEDialog)
! ?  W7 v3 U6 G, z //enum { IDD = _UNKNOWN_RESOURCE_ID_ };
) m- |" P  G( V) u  // NOTE: the ClassWizard will add data members here
* _7 v' {6 g0 F //}}AFX_DATA

4 W% D3 Y. V) w# m" v  R% R// Overrides9 W( y5 G  X( d, b/ X5 m6 \
// ClassWizard generated virtual function overrides
* l/ S9 o! t: f" m6 C //{{AFX_VIRTUAL(CHsPMEDialog)
- [8 k" G+ W, y  a8 T+ T* d5 a% R& @, [ protected:
+ g8 ^$ K+ D: l& J/ q" H9 e+ r' b virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support+ _, g# S- w/ H5 C. J' w" k
virtual void OnOK();$ F, _! w& P* q5 B+ |
virtual void OnCancel();
+ @& h) L+ K, `8 C& v, _4 X( v, e virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
6 _; Y0 Z( C! t/ n" H7 i5 ~1 G virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);! a( r% I5 u) \/ M1 A  ]  {2 E; R
//}}AFX_VIRTUAL
// Implementation
* T' j  s, @! b( b# w; [protected:
// Generated message map functions% _' B1 j7 ]: l' j( k  o" ]
//{{AFX_MSG(CHsPMEDialog)
4 q$ ^. X# A7 ^8 {1 q afx_msg void OnBack();0 |+ y4 B9 w" U: Z4 ^; R9 S/ H
virtual BOOL OnInitDialog();
$ w* z( l4 _# Q6 _  _9 e# h: l1 P+ y$ o afx_msg void OnDestroy();
4 ~. z% w, |9 Y+ w$ t" | //}}AFX_MSG
7 i$ w. I5 |& x) c8 I+ v DECLARE_MESSAGE_MAP()
protected:
2 _& B1 H: I' v: X/ Q" n // attributes5 i6 z- p# ~  }' t% R' ~
CWnd   *m_pParent;     // 父窗口指针
/ A4 f, N  L! F! \- v! P/ C HICON   m_hIcon;     // 图标$ V) M# l2 |* H6 i
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;9 m+ d! [9 p2 l' Z! ?
CHsPMEButton m_btCancel;
5 Y* T# a* A, [' d% a. J: \ CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄6 o/ q$ c$ J0 J9 T- W0 E  _
HHOOK   m_hkCBT;     // CBT钩子句柄" Q& f) H: v, M; X$ ?( x' i% M
3 C0 i0 t5 M1 a7 A
//-------------------------------------------------------------------------. p+ j# N  \, \* i' B
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
8 X9 X" b4 c+ A# k // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
0 G) c2 N$ U. m7 P, d# J1 y2 q // 链表的头及下一个结点的指针
# N& f$ Q. h! [8 @( b, p# @$ r static CHsPMEDialog* m_spHead;
# ?. S: N6 U- @6 ]! v6 q& S CHsPMEDialog *m_pNext;
// operations
$ U! {7 M6 j" z // 键盘钩子消息的处理函数# Y( y& o# m6 N, A5 p5 l
static LRESULT CALLBACK KeyboardProc(
6 z: N+ s2 U% y% e$ i  int code,       // hook code* j2 E! e; j- T6 K3 I- h
  WPARAM wParam,  // virtual-key code
$ d0 l8 T! j% S) g( B  LPARAM lParam   // keystroke-message information
+ \& P. f; C/ Q  );
; l4 A, U4 I% i$ n- H; N // CBT钩子消息处理函数
+ y5 O- P0 O& {# _8 u static LRESULT CALLBACK CBTProc(( f. j8 E; L- T* {! d- \2 n
  int nCode,      // hook code! ~, b5 k$ |  l  s
  WPARAM wParam,  // depends on hook code; P3 u9 j0 a8 I! `( b2 U7 k
  LPARAM lParam   // depends on hook code: F8 Z; P; O+ O5 l) c1 A& T
  );
. K8 q; K+ r' p0 k* S. t+ |" f2 f
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
  p% ?  w& _5 ^5 g5 S( ^7 { static BOOL  IsWndKindOfThis(HWND hWnd);
- ~" F; P' g1 ^) T' c // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
- G7 D  a6 W- |" Z( E+ H static HMODULE ModuleFromAddress(PVOID pv);4 ]8 [5 _  l5 r# O0 X5 N* I+ o
public:
5 F4 [7 `" M! W; U$ R- E // attributes
// operations  Z* y2 f9 y+ D3 a4 _" j- }% s- [2 W
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框& @# s' \8 x6 B$ ~
BOOL CreateChildDialog(CHsPMEDialog *pChild);3 l3 c! |  s. x
};
9 B, l4 r; g9 [: z9 Z) [; z' J( s6 p
CHsPMEDialog* g_pHsPMEDlg = NULL;: n6 l9 A/ {$ B/ V7 J1 j) ~
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
1 g- {$ f  f& p! i* o$ Z7 [% ~HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)$ ~+ ~( O1 o9 b  Q/ I
: CDialog(nIDTemplate, pParent)/ _, ]1 u* y6 r' @
{
7 Z8 C8 Q+ O4 L- ]* Q! f: K //{{AFX_DATA_INIT(CHsPMEDialog): E, E& }% j: _, D6 ~- t5 r
  // NOTE: the ClassWizard will add member initialization here
& _  \7 I& b8 P8 w //}}AFX_DATA_INIT
6 c, l. j) n3 M9 U& W; p- _ m_pParent = pParent;
5 J; C" J) ^& q. R0 m m_nTemplateID = nIDTemplate;
6 I( s* `2 X) Z. E" ^& ` m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表( {2 N  e# I5 l& r; S  b
m_pNext = m_spHead;% d9 I' M2 W3 _. {  I9 P; O( X) z% q) H
m_spHead = this;2 D2 \- F& S) _" f0 V& ?$ [
m_hkCBT = NULL;3 q7 |* g/ _4 z, I- a
}
CHsPMEDialog::~CHsPMEDialog()
5 k1 |( q4 z- P{
+ C3 t# A& u0 i$ [ // 从链表中删除本结点! ?3 d+ Y8 K3 R$ I' q% l3 V' q
CHsPMEDialog *pTemp = m_spHead;
0 u- _& }& n" C- l% K$ }9 k' \/ I if(pTemp == this)5 R; O3 n' h, T5 L
{
& W& n; H+ L4 _4 r" C  m_spHead = pTemp->m_pNext;* ^" i' l5 }8 O' P2 A
}  I+ A- l* T! E8 \2 L4 x
else6 v0 m* H6 Y5 ^) U0 l
{' a" w! v' y. T& g% l4 E
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
( A8 M, Q. E' P9 v& X  {
+ d, a8 _! G$ z$ w- L3 P   if(pTemp->m_pNext == this)
; I6 p# D# K. u: H( g+ [   {5 z6 C; d# k0 K" o& E7 Z3 l/ k
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
+ O4 j5 q6 Y( J& D4 X) s7 t8 `+ q    break;
( L. K/ N$ U: K  H: @! o( a   }
/ K  x. V+ v$ ?, @1 x$ p  }# F: K5 I. k: G
}
$ M+ I$ F$ I2 _9 C2 [}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
4 l- m% V2 o; x! L4 s# h{! r, L) r; {7 R0 h: I; u( r$ s
CDialog::DoDataExchange(pDX);' v2 Z4 @/ d" u" @; p
//{{AFX_DATA_MAP(CHsPMEDialog): f- S8 C8 w2 ^7 w) Y' c
DDX_Control(pDX, IDOK, m_btOK);) p  r; g+ @- s3 H- Q
DDX_Control(pDX, IDCANCEL, m_btCancel);
( s. K* V4 _- ]/ F2 S: V' c: l DDX_Control(pDX, IDC_BACK, m_btBack);+ p+ h+ H1 s: o5 b/ o0 }
//}}AFX_DATA_MAP
1 P4 H8 I5 ~2 k8 Q# N" U/ I/ U}

8 _9 H: A" U2 Y& l; h3 HBEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
" }1 q# e; w0 E: S6 X //{{AFX_MSG_MAP(CHsPMEDialog)( I) z) Q8 Z+ i1 v" G1 v
ON_BN_CLICKED(IDC_BACK, OnBack)! p% O# y5 a9 a1 }6 R2 r$ l3 g
ON_WM_DESTROY()
' ^$ `$ x! E: B //}}AFX_MSG_MAP
) N# i4 [$ U' M2 N6 VEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
. s9 a4 O; H( a// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
4 N, C3 ~: E5 M# p$ ?% L{" v  |5 r! {" t
m_pParent = pParent;
" o: [* A( \% m8 T: q return CDialog::Create(m_nTemplateID, pParent);
" V" r; ?( W  t- ]5 g( c}
6 N; T  S0 h' j2 P+ M5 m2 ]3 V; F
BOOL CHsPMEDialog::OnInitDialog()
9 K4 I2 F" a+ N' X/ |/ x' u# g8 ~- d{0 D. }( w: o) m4 x' b: x, f
CDialog::OnInitDialog();
// 设置标题栏图标
. A5 b5 B% G4 ?/ o6 } SetIcon(m_hIcon, TRUE);& G' P( _* }# R
SetIcon(m_hIcon, FALSE);4 m( A( `8 q( ^8 m
8 P! @0 J  l$ B, x. e- {. G
// UG的对话框的几个标准按钮没有TAPSTOP
6 X+ b& [3 o: [: O CWnd *pWnd = NULL;8 W5 @+ H9 _* |3 ~# a7 @" K* Y, b( N
pWnd = GetDlgItem(IDOK);
, `' v0 @- E; i if(pWnd)
  d, a: Q( u8 K* B! E0 t {
2 _2 Q' u7 j3 t+ \# C  pWnd->ModifyStyle(WS_TABSTOP, 0);/ H* E, X  A, a& `
}" N/ R, Q' s1 R- ]8 c7 n1 T4 y( [+ Y& h
pWnd = GetDlgItem(IDC_BACK);$ G* K2 ]6 }: o  w
if(pWnd)
5 i- q. G( O. G$ m {& I( d- w$ v  A9 V* f6 O
  pWnd->ModifyStyle(WS_TABSTOP, 0);
: x$ S# R5 V0 w+ ]/ g! V# z }3 z. b! w* n% U& A# e/ x
pWnd = GetDlgItem(IDCANCEL);  s' s: S$ D4 W/ L- n
if(pWnd)
0 P2 y5 e5 z! {. L0 Z+ \& s {
2 y: ]# O- n5 O, h  pWnd->ModifyStyle(WS_TABSTOP, 0);8 g$ q) R* a5 A- Y& M$ l9 y. N
}
2 v( F1 n7 ?& }/ \" { - f: s& I) Q. H: e3 g0 b
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
" X3 a: u' D2 w8 t2 S if(m_hkKeyboard == NULL)3 e- C& s' e6 J, W
{, `  ?% Q! F. v  C  o
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());& m. Y8 C, U7 ?
}
5 o, M6 k6 r; }- [ if(m_hkKeyboard == NULL)
  G. |  r$ `, d7 Z {3 q1 q5 \' A* b: d
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());+ W: S- C% [# b1 v  k  h
}
if(m_hkCBT == NULL)
- D7 e. W) s  n/ c {
* x- Z9 T+ r# P; C, ]: J3 K/ v$ W. I  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());+ P+ @# a7 s; y( f4 Y0 M9 |
}
) N8 E6 R( d6 T3 e  y; G% Z if(m_hkCBT == NULL). P  a) h" |9 r; _$ H& M. f
{
  \# H; ?& H, r  TRACE("Set CBT Hook Failed: %u/n", GetLastError());
8 t% y' Q0 ]1 Y( c( b }
7 T: h8 x5 M/ g% u: J, ` 7 V2 I4 n; s3 U( U6 x  F  Y
return TRUE;  // return TRUE unless you set the focus to a control2 S/ L0 }' N0 m" P
               // EXCEPTION: OCX Property Pages should return FALSE
  x2 ]* {+ D2 p2 x) l4 W}
void CHsPMEDialog::OnOK()* X; j9 J+ K' J. \
{
" w7 ~7 T7 h2 t( Y( E* O  P; q. R CDialog::OnOK();9 D7 H# Y( t' S& t: V  [
if(m_pParent)
9 P" D6 H$ H: z4 u" r4 n1 G {( F3 }; |, m: o& K& G7 J2 K% m: x
  //m_pParent->DestroyWindow();
; L9 h; T# O' `( Y; r3 q  //((CDialog*)m_pParent)->EndDialog(IDOK);) i1 l6 k2 x' N0 R. i
  ((CHsPMEDialog*)m_pParent)->OnOK();
/ W. g$ L5 L" S) M- R }
0 V; D, {' Z% V* ~: O}
void CHsPMEDialog::OnCancel()5 I0 M$ }! X8 N$ \5 Q7 V+ V# J" k
{6 K4 S9 g5 k' E- F. S$ I
CDialog::OnCancel();7 f0 t% Z8 U+ e, @! U' }
if(m_pParent)) q5 v% y; c9 l4 u8 d" x. i, T
{
0 v% n" d% `- F! Y& S. Y4 `7 F  //m_pParent->DestroyWindow();' R9 U( i; u, w" U# C* j
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
, c1 {- m0 R9 ]- s6 R  ((CHsPMEDialog*)m_pParent)->OnCancel();
; z: e3 v! T; D. \, { }' v( X, I& ^9 f( u" s8 N/ T
}
void CHsPMEDialog::OnBack()2 u! ?$ L2 ^% q, q
{- j' \. \7 [7 p2 _9 p7 B
if(m_pParent)
/ j1 R/ q! T: }  t$ }( ^ {
% {* U$ q4 w- d' A& C/ a# h/ v  m_pParent->ShowWindow(SW_SHOW);
8 ]" D: F+ f1 u: j }2 r  O8 W5 r! @9 o
CDialog::OnCancel();
! h, g' j  E' W  I0 [% F}
; I5 ^4 s/ ?) O6 b
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
3 _* Y3 j9 N" |{6 b6 _. m7 A' a2 h/ v" I
BOOL bRet = FALSE;9 d2 u% i7 {; @. [4 m3 ^9 H: X
if(pChild->GetSafeHwnd() == NULL)+ t& ?, Y1 P; U: y; F
{) A  ]2 B0 d/ _/ }: y4 p9 h
  bRet = pChild->Create(this);$ F9 d$ Q( y/ c/ d) I
}
& N: c8 j% r2 |! |  |8 L bRet &= ShowWindow(SW_HIDE);+ w) z* @6 H1 j& m4 c0 P) Z9 S* R
bRet &= pChild->ShowWindow(SW_SHOW);$ Z1 \% r  o. C4 x9 v
return bRet;7 g" ^8 @7 Q+ I# ~
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
0 B7 {8 U9 P8 F5 R$ w- }{
; v6 X8 w/ J  V if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
+ Z% {5 a: m5 y& O0 b0 F {
1 e1 u8 Y/ r$ P- r  //TRACE("Key down/n");2 o' r, o+ z3 K% s
  CWnd *pTopWnd = CWnd::GetActiveWindow();
5 Q' A7 I9 m: p0 h  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
  j5 ^  t$ z" C8 r  {; D9 {& j' G- P4 D4 C6 x1 P
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
0 L4 t1 Q8 f: `: _& O/ R+ V   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)) L3 R# J& H& Q* o; @
   {$ y% q0 g$ g2 K) G" ~# ^+ {2 z
    // 只截获tab、esc及回车键
. l: [* `" b% e2 [! r    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
; W- \0 B4 K, n( B" w5 I    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);1 c; f2 t& n2 \; E8 s
   }3 u! E8 }, I# ^3 S
   switch(wParam) {
8 l5 C7 q/ x* i- l   case VK_TAB:; `" f" W% o" r* b( r
    {
) Q' k" q8 |7 W7 ~8 T! ]     CWnd *pWnd = pTopWnd->GetFocus();
  M4 L# a2 |$ r. W; @2 t     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
. `9 Q0 y/ u3 ?1 i( ]! f5 f     if(pNext)
) a& i$ L( \# m4 o5 x! b. e     {
* Q4 x. H( C+ r( T' e/ g      int nCtrlID = pNext->GetDlgCtrlID();3 S' W1 H3 I/ M7 |
      //TRACE("CtrlID = %d/n", nCtrlID);
+ W" ]% S  }3 L2 ~, u; l      pWnd = pNext;
% c; v/ @) [( T8 I* _/ R+ x% t      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)0 Z1 R- ^( X8 {8 ?) y9 T, ^, r( J8 x
      {3 N3 U; `5 W, ]% b0 Q( B7 k
       // 根据UG对话框的属性,这三个按钮是没有焦点的
( S0 C6 A, d1 o% \       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
* Q7 x. i' \. M9 K" P       if(!pNext || pNext == pWnd)
# j, g+ e2 ?  j       {
6 }3 E/ ~4 O- z* n        // 对话框上只有上述三个按钮; Q* C* E) ^" k+ ^; f) G5 d
        return CallNextHookEx(NULL, code, wParam, lParam);
1 K+ [  k  X) @6 _+ v* S& w       }4 P, y8 H0 h3 S0 Q$ Y0 ^
       nCtrlID = pNext->GetDlgCtrlID();) n& D) O) y% k- A
       //TRACE("CtrlID = %d/n", nCtrlID);
2 n  e* X' Z- H0 W      }$ m# l( p* M% A7 A
      pNext->SetFocus();
3 j( _9 v! s$ l9 E8 ]* h     }: p8 d9 }0 }, m1 G
     //return TRUE;
2 p* a: C4 G% ]    }
- F  w, T% A  }* W. J5 Q& U; G    break;
2 C# u( I; F" s- v8 Z3 S5 y$ L   case VK_ESCAPE:
' c3 ^6 v: P* t" {8 Q  u    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
0 \8 v5 Y+ O3 S: u; @# j0 a    //return TRUE;- f- T7 d; ^9 l  Q
    break;( M. \: [0 @( p1 x+ `
   case VK_RETURN:) y: f5 n" d5 Q
    // UG实际上并不处理回车键
: m) S+ R( {- Y- ?/ h9 Y* e* {- m    break;" m: y. q# g% q3 t1 ^" ?
   default:
2 B) n( p( t1 z0 ^    break;, T' K1 [6 l' F% \/ f  p2 j0 @
   }" W! j: z0 t3 V1 v+ F
  }
. y2 b* N* d* Z! Y: w }! R8 g! N7 \( q4 M& K8 |' |9 H
return CallNextHookEx(NULL, code, wParam, lParam);
/ l  I& _8 n" Y}
void CHsPMEDialog::OnDestroy() " u& a, t5 [: H1 i0 {- Z
{% f8 k; B) O. F# p: T! s
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子" g4 [6 \/ k0 }) _% F
if(m_hkKeyboard)
- L' c- s, y- m. E0 A( G, `- m {
  b4 F; o& B1 b& a0 L. Q' H( n1 e. W+ L" G  UnhookWindowsHookEx(m_hkKeyboard); 3 {" m! m7 Y( i- |4 }
  m_hkKeyboard = NULL;5 i3 r3 a% z+ A& W% x% F* E! S4 C
}
if(m_hkCBT)  X7 H+ i) m4 N% o
{
- p- j6 K1 f0 r3 Y; U, V5 Z  UnhookWindowsHookEx(m_hkCBT);
: f5 e0 z; ~# z! L  m_hkCBT = NULL;8 z, U% c- W& M3 T& s+ ?1 ]
}( a! U$ l; ]. {7 d$ c
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)( `- j) \' [+ v5 z9 U+ \
{
% Z% n, S) V3 Z& K! g% U CHsPMEDialog *pTemp = m_spHead;8 p3 G( Z' \# D* h  g
BOOL bFound = FALSE;$ S- D1 y: V2 s( S
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
* R, F3 y  P8 }. @ {
8 Z1 v/ g/ J7 E" L/ B  if(pTemp->m_hWnd == hWnd)
# M) [: c- }& Z9 Y. l  {7 F% m, J; e3 a& m
   bFound = TRUE;) k' ]9 J. [9 x' _
   break;- S( U* V" Q) q5 |( |
  }  P! K) j% G& N# V
}, w0 L' f( q9 _
return bFound;
( k  |$ H& V4 ^) L6 n}
// Returns the HMODULE that contains the specified memory address- k( \: ]) v- @; W; L) l& E* v
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv) + R0 @- b6 n& A: z' i
{
2 G! O  P- T  T, E) }   Y7 m2 P! U  C1 s# f, V2 s
MEMORY_BASIC_INFORMATION mbi;
- |% b' k' M* F1 P/ k4 y return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
% L9 q9 l( v( L% Q) F, t  ? (HMODULE) mbi.AllocationBase : NULL);$ i) }8 A( }; B4 {1 [9 V1 E3 V
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)2 H7 K7 W! \1 H  d( V; F
{6 c9 P  z/ p+ l, `9 Z7 D
if(nCode == HCBT_CREATEWND)0 Y& j* y, C* [
{
6 u& S( z( {% N, l  //TRACE("A Window is being created/n");, O0 Q1 S( x8 s
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;. j5 P# A6 }2 O( x: U
  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
. Y# [. s" u  M2 V9 @  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
  `) j" ^* K0 d  {3 t( n, L7 D8 H  T- T
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应0 b7 W# R1 a/ w8 d- I) |( d
   // 取得窗口处理过程内存地址
8 i' s5 M2 s+ Q8 A7 [9 U  x) I& F   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
5 I, U4 V4 B) X   if(dwUserData)
% L1 n( A& [# f- ?   {
9 Y0 u' E! ?: F& ^! ]0 n    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);3 {' U; w' N  s. R, s: y# C. _5 L
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};% J9 U1 w4 b! q( b/ ?! K
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
& p9 S( z, `! T+ W    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);% v0 v* l' d* J9 D$ O# B! J
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);% V4 F1 @( w. t9 |6 K- N6 U2 g
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
: T. J) k  ~. a( c1 m    if(stricmp(szUGPath, szModulePath) == 0)
) k, E% G6 J9 k) Q    {; T' J# t; J9 {# H
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)0 N* Z+ o- r! x9 e- k; b+ S% V! O
     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
6 w5 L) h" a3 H$ O; Y     {$ F  Y7 ]9 w5 Z$ Q) G& a
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)" H% J9 ~2 p/ A7 m! a1 R9 Y9 i! @
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && * v( m! j  X- ~* Q. ~% z
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)' e  i+ j# j+ |" E  l$ E9 v# L3 I
      {2 \5 c4 x9 ?; ^
       // 窗口非本窗口或其子窗口
$ Y+ ^" n& c. I- ^$ N9 [       g_pHsPMEDlg->OnCancel();
$ X/ w' K7 Q; {0 L: {2 F      }
+ q6 r; s8 r5 a2 {% e     }7 H( F4 z$ |; x" L( ]% E- Z6 h
    }
; C7 }2 |  |! T4 ?& b% `   }
7 e3 [& C& t' V# h; ]5 A7 |5 U, i2 m  }' G/ k, p9 f  i0 @* y! \
}
8 p9 S5 F' D' b* Z return CallNextHookEx(NULL, nCode, wParam, lParam);. W" }8 X, S/ K' m5 L% q
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 5 B4 D% I  _# _
{) _9 S0 G! z! E8 X6 i4 [
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来- |2 R, P8 J0 C- d

" m+ ], y0 a5 D5 M, T) p8 _ return CDialog::WindowProc(message, wParam, lParam);0 c$ y) w% D; |( ~8 }' ]! m9 t& f  x  d4 y
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) + M, O  T8 s6 N8 J! x
{/ ~; ?, p# R$ n4 C- W) U. S
2 Q, J/ |6 S% e% W/ z; Q0 o* K
return CDialog::DefWindowProc(message, wParam, lParam);% P& T  E  }7 ?' d
}
1 Z2 g. \) V: 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二次开发专题模块培训报名开始啦

    我知道了