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

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

[复制链接]

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

2470

主题

1275

回帖

8万

积分

管理员

PLM之家站长

积分
82168
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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
0 @0 v0 Z3 F1 p// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类/ s8 B. T7 k8 X. ?7 g# N) y
//    该类来自网络,稍作修改,版权归原作者所有
3 M& x3 \/ B6 r6 N' K# p9 N8 Y8 U//-----------------------------------------------------------------------------: K- E9 N% y, ]: f
class CHsPMEButton : public CButton
  E/ \7 T- J6 t. M' x{2 I6 |  R: v: O1 L% T6 O
// Construction
9 E( _9 L5 F! y5 @% U, o3 xpublic:. Z/ @+ S) Z: m, C" E( R) v- Z, ~0 F
CHsPMEButton();
# c5 V' A; a  D) \  d8 j" ^2 T ; c& c1 t4 T" `/ C% N
// Attributes  M/ J: O8 x8 s( M4 C
public:
0 z, p' _7 D4 r) {) [
* ^4 o& a) Z1 L1 X* i& j; _ // Operations
: j/ f+ f0 ^0 ?4 p1 Y8 J! C9 Ipublic:
: a; L6 @* p- ` inline void SetNormalTopColor(COLORREF color)
3 M7 M' v5 K! t1 T {
+ S, S& z# P* C4 d  m_NormalColorTop = color;- Q! v+ _% K) i$ A$ u, g
}1 a  U$ w: [  d6 {
inline void SetNormalBottomColor(COLORREF color)( T2 ?+ d2 J' n5 e9 L5 i, C
{
5 w# l9 Q0 _2 A  m_NormalColorBottom = color;$ d* U* B/ x/ W: M% H
}
* c& _5 z4 v  J6 z4 {5 C( m inline void SetActiveTexTColor(COLORREF color)# l9 P$ A3 ~" C% c# [) M
{" X3 f! H+ i* s& i7 u2 q
  m_ActiveTextColor = color;& b1 y* q% P+ M- U
}
7 w% X5 F* s. `1 I9 Y( p5 C inline void SetNormalTextColor(COLORREF color)7 D! P/ L' u( L; p7 P- [( T
{
' m% E- [& L& Z- J8 O  m_NormalTextColor = color;
7 s+ s6 o! M: b }  O9 D2 U2 |* U/ a# r2 m. e& V
inline void SetSelectTextColor(COLORREF color)
$ [& F" ?- G# D {
. E( ]5 v* w# d9 ?  m_SelectTextColor = color;0 ?8 g2 ~8 i" v% h: U" Q* x) Y
}% M! f9 p- m# S' p/ l$ z
inline void SetFrameColor(COLORREF color)5 I1 L( i& m5 S) K0 b7 w0 {
{
$ g6 ~/ c, q+ ]9 p1 ?  m_FrameColor = color;+ c' I: [- t* C" N4 r
}
! o5 S2 J. U$ g inline void SetActiveColor(COLORREF color)
4 P, Z  x2 p! |6 ?$ H/ Q {7 y! O1 N5 z2 K5 ?: l4 `
  m_ActiveColor = color;% K( s; b6 t% N, K! j5 ?. P4 W
}
4 N: Y! T: d- Q& \& g // Overrides4 e! i# L) x  c2 z+ \" [
// ClassWizard generated virtual function overrides: j3 b4 u" U8 }' g/ f/ @% H
//{{AFX_VIRTUAL(CHsPMEButton)
4 w6 W# ~: K4 f3 R4 K( Kprotected:& O3 X* U: b  V/ g2 q9 h
virtual void PreSubclassWindow();
' T- a. H% {. i2 F* v! A //}}AFX_VIRTUAL
* F. i' u% O( H6 s; a5 l . r+ ~9 L, l  u7 ^0 D
// Implementation
) Q( i) ~* g& e6 Mpublic:
! j) q5 s. z0 R: M3 e virtual ~CHsPMEButton();, A$ b# d. |. [* k' U2 g2 B. s# Z% O

% P) L. h4 O$ o' _) |4 t // Generated message map functions5 j( Z2 S3 r1 f! }" u
protected:: |# [  T; N' O. P+ F
//{{AFX_MSG(CHsPMEButton)% R1 J! M3 c, {* k! W. U" q9 |
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
# E! ]& F: a3 p. f, U5 ?* s //}}AFX_MSG
* R" u% S4 Y  H. s8 t1 u   E1 d7 M# @' g/ D: b
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
+ l0 y5 x3 E' X: N) x! r void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
) S0 w9 C3 i4 J" R9 q0 M' ~ void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );; S0 w" Z2 C+ C& N$ i( ~
LONG OnMouseLeave(WPARAM, LPARAM);
' U0 D. N; |" k' G BOOL m_bIsMouseMove;4 U( i  S5 Y, d0 t; R; J4 n; [0 P7 E

' ~8 h0 ^7 _$ i9 n! g! ` COLORREF m_FrameColor;
1 F- a1 [. ]/ ^( W  X/ L COLORREF m_ActiveColor;
; L% p* {+ v% l. y& W2 x ' D: s" Z- ?% C+ s2 i" p% O
COLORREF m_ActiveTextColor;: T. Y# A3 n# W' {% K% P
COLORREF m_NormalTextColor;
& ~( j- i7 t2 d. S COLORREF m_SelectTextColor;& P/ N" k# h) f6 S1 l' U$ U

2 w* ]6 o  k0 h" a& y COLORREF m_FrameHeight;& M3 w% }' D; C: q- m9 |7 O5 R
COLORREF m_FrameShadow;
8 Q3 S* v: x: o& \) e# {$ D # M  L9 x' v  C
COLORREF m_NormalColorTop;0 p# M$ j0 z4 B5 B5 ]- Y1 {
COLORREF m_NormalColorBottom;9 B. {5 |% _# C& |. J

$ i- G7 A  b& j4 F4 v* F DECLARE_MESSAGE_MAP()& [: R. r* O9 O  d4 |
};
/////////////////////////////////////////////////////////////////////////////
/ C  [5 h& U! {- C% A; C9 ]/ L3 N) i// CHsPMEButton
CHsPMEButton::CHsPMEButton()
& f$ P( j. e! r. |& ~{
" a) n2 r% C  M: x4 M; u2 ^ m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
0 j9 O/ Q' c! v* T/ N8 _% ] m_SelectTextColor = RGB(0, 0, 0);2 ^! O% \2 _8 y& ]" p0 W/ U& g5 W
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);, {( k6 n$ B2 m5 `' I* Y
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
4 m- l, L, v9 `, j1 N" d* X. r' A m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
% Y7 |# W. R3 j! o/ v m_FrameHeight  = RGB(230, 230, 230);* T6 S3 s$ i5 a) i& m" Y8 f
m_FrameShadow  = RGB(128, 128, 128);' t; Y% e% P$ r! z4 e
}
CHsPMEButton::~CHsPMEButton()# u- e$ ~4 R1 j) A
{
$ w8 Q( K7 k$ i' n' W; n2 S. o$ `}

% T; W! U; L) s$ M. R: o- YBEGIN_MESSAGE_MAP(CHsPMEButton, CButton)3 Z! m$ i* N' i" A) z0 @5 g; J& a
//{{AFX_MSG_MAP(CHsPMEButton)
4 V. Q- ?9 c+ W! m4 i ON_WM_MOUSEMOVE()
+ C/ ], p) i; h" s //}}AFX_MSG_MAP: q  E; ]& g) u/ ?9 p
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)3 w7 x1 L- u# e. c+ u; V1 M9 i
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
, R5 t* a$ v: j3 _5 n* K// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ); ~8 H7 t# j$ K7 {
{5 n- `5 v9 Q$ d
//*
0 W1 c" d. _/ A  ^* x! W% n CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);. I: |1 m+ I* E' ?$ h( B
DWORD nState  = lpDrawItemStruct->itemState;, N# m+ i1 g8 b% O: t5 E# x; J
DWORD nAction = lpDrawItemStruct->itemAction; 7 y- Z, h5 l" v7 v
CRect rc   = lpDrawItemStruct->rcItem;( u+ A# W% \, K( w* J6 t- T
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);
" v* L; r7 }' a& V8 d5 Z5 V% [ CString strText;1 O4 y' K) Z. d% U6 J' s0 Z" d/ @' z
GetWindowText(strText);
if( nState & ODS_SELECTED )
0 q: z( A; s# p: j' \8 w7 \% @ {% b5 N; x, D) v* m- _$ V: ^
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);4 _0 a+ @( [9 Q" L9 D# N
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); - o. L1 u/ T9 K9 U
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
; x4 W, P) J, o' p7 x) x }0 n  v3 _$ V, I- m; ^4 k
else //Normal
$ C5 w5 K% j' c {, t2 S1 p" W( R$ S+ O1 h
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);' w. x) n( t) e
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
% _% ?. }% G, l }
if( m_bIsMouseMove )% i) V2 }( p4 e6 x
{
% V% b& @, H  M9 x  CRect rc2(rc);
  M( H2 u/ y2 @8 x# k! |3 n  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
  N1 i6 }" J' o' e7 o8 K( n: _   m_ActiveColor, rc, rc, pDC);0 e6 W$ E& W: V3 {8 u2 ~% Z6 _
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;( t( R% b. X/ ~) E0 ^! e1 C
  NullBrush.CreateStockObject(NULL_BRUSH);* `, i6 p, H1 H6 N
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);# g6 P8 |% g0 M3 q" J, e# Y$ z
  
9 A) t3 \- Q$ g' r; x  CPen Pen;
+ D% j; h1 j0 m- a: \& n  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);7 k1 a& a1 B) b# N" M
  CPen* pOldPen = pDC->SelectObject(&Pen);+ L5 D# s: P8 I- d2 W' t
  rc.InflateRect(1,1,1,1);7 G, I  C7 a7 T  Y! `6 w5 m
  pDC->RoundRect(rc, CPoint(3, 3));5 r+ i9 X5 z* c, c4 }# Y
  //rc.DeflateRect(1, 1, 1, 1);
! F. \3 L7 c( f  n6 D: k: S  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);  B8 k5 h8 A2 ]. R7 J/ Y0 i- A
  3 ^$ ^/ h9 F; J$ m3 o
  pDC->SelectObject(pOldPen);. f8 B$ w& ^( A% a8 H. K& q: @
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);( T3 R9 l: `/ l8 |
}
1 B7 W* J7 h, W9 D9 Z# p8 f- n2 d / j; V* r0 k+ D7 }4 U; v
pDC->DrawText(strText, strText.GetLength(),
3 h$ R2 ]% R( a, d1 ?0 h  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);' f; I8 s, ^0 y! f6 P
//*///
8 d6 G8 T; {( J& r/ I}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
7 H/ J2 b- y5 `3 r' w2 E{
4 A% w4 C; g/ ]& s // TODO: Add your message handler code here and/or call default6 Q% H+ n( d/ k9 l/ m) b4 C
if( m_bIsMouseMove == 0 )
0 {* J5 b4 O1 F7 I {
. n. I$ ?( q+ F$ B3 X  m_bIsMouseMove = 1;
7 W: M) M& I$ x) v  Invalidate();* M) A7 Y2 T+ ^
  
; U" U0 `6 B) v- N) l" w5 Y# P  TRACKMOUSEEVENT trackmouseevent;
9 Q3 m8 A  h  \1 Q3 \6 A4 m  trackmouseevent.cbSize = sizeof(trackmouseevent);$ b& ?4 e, q9 E) Z* `. J5 i
  trackmouseevent.dwFlags = TME_LEAVE;
1 l+ }6 u- _8 r8 ]; s( X  trackmouseevent.hwndTrack = GetSafeHwnd();
4 Z6 `) e! _$ t! E+ N0 W+ Y  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
0 T: `; ^" t+ C9 Q8 k: S  _TrackMouseEvent(&trackmouseevent);( A2 P' Q4 G4 K$ G' d! l9 Z
}
5 u* d. d1 P# d$ X6 q
  m% i6 p  q: ]4 u# L CButton::OnMouseMove(nFlags, point);! ^/ B% Q/ Z6 U* @9 V" h5 r; _
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
, J  ?3 ]5 ?& r6 o7 {{! ]8 ^/ u! `+ d" S8 U
m_bIsMouseMove = 0;! O/ L. ~+ V. s% D
Invalidate();
return 0;
  J1 X, J) B6 ?8 s/ W8 l: N$ V}
void CHsPMEButton::PreSubclassWindow()
! ?2 K( `1 T7 j) _6 X4 Q, i6 _. G{
, Q; ]9 c! a9 I // TODO: Add your specialized code here and/or call the base class
0 }& b! y, D$ t& @8 {' |: Q UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style  q% V: H2 o0 Z+ D
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
$ O* i" a, K& z5 k1 P$ o3 S2 H, [}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
  R3 U, s; Y2 x{7 M6 a1 L1 _6 ^3 y. L
CPen Pen;$ r- o5 U% v& \0 I9 _( r/ S5 X
CPen* pOldPen = pDC->SelectObject(&Pen);: c- {7 \1 u, J/ R' M, g  _

$ e' ?& e0 N4 m/ t' P5 R int R, G, B;8 \6 ], d6 j8 I% q, s* ~+ d% h
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();  m6 [  q+ {% Y% K
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
% n% L3 r3 H$ ^ B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
: `: S) |: B7 J; M% M & x; L. H6 s4 `9 m3 o
//R = R>0 ? R : -R;
5 R8 J" N: M0 [ //G = G>0 ? G : -G;$ s1 j* V0 z& d  H
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
6 t( Q# Z6 ]1 g) E  m6 {% N+ f COLORREF ColMax = Top > Bottom ? Top : Bottom;( R' k: g. X+ \; N
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
9 L: G  J  C5 g4 O+ F  Q {
( X* F/ n  j- C2 g# f7 p" q  ColR -= R;
' W  x: E) M9 i; [  ColG -= G;& b' V, H2 y1 [0 i: c
  ColB -= B;
  /*0 ^$ f; ^/ L& V
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||0 t+ j' M0 \  Q3 Z: H$ }4 U
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||/ X$ D, o% n8 A) A
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
0 e( c5 J* o9 N  O% j$ r9 M  {4 b0 }3 q) X* C) ~9 {7 _
   R = G = B = 0;0 `8 O" ?6 T. D! s0 l3 S
  }///*/

, k) i* s' b) @- ?' r9 G  Pen.DeleteObject();
$ n8 F- [- V. J% `  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));- J6 E; [/ n3 J) y1 K$ G$ I
    # c8 Q+ f- a- l1 g, [
  pDC->SelectObject(&Pen);
" C7 o5 [1 C0 c3 |5 L4 V  
% I6 N6 L( n) o5 U$ X+ m$ g8 F9 ~  pDC->MoveTo(rc.left, rc.top+i);5 }. `1 E  ?  X% j5 z
  pDC->LineTo(rc.right, rc.top+i);& E6 ^8 Q, q1 d
}
pDC->SelectObject(pOldPen);
, v8 n2 @$ P& w" O}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)- S7 y( X  A9 s; E' o) G. s! N
{
8 B* p  `+ p% H( ` CBrush NullBrush;. d/ J( Q. f, B! R  p( j# c* ], p
NullBrush.CreateStockObject(NULL_BRUSH);1 u- x# g# c0 w( H7 z9 w
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
4 C1 @/ Y+ R  @" D" P Pen.CreatePen(PS_SOLID, 1, FrameColor);
0 q7 R2 O7 Q8 M9 f: d3 Y7 ? CPen* pOldPen = pDC->SelectObject(&Pen);
! b$ E4 @+ g0 C- r% c2 f  ]+ j) v + g, f% X. u/ Q- A. r# c
pDC->RoundRect(rc, CPoint(3, 3));0 C+ L4 J$ p, S( S/ J, v# `
rc.DeflateRect(1, 1, 1, 1);
! K- U8 p% x0 S" j8 {& N; Z3 j" F pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
: K+ V7 \, M6 Z! A: R8 u pDC->SelectObject(pOldBrush);0 R0 L9 c3 z: _2 j' x+ n- E0 c
}
3 c! J* A1 q0 a# J6 H( _4 _
/////////////////////////////////////////////////////////////////////////////
% P- c- a- H# Z% u( d3 D// CHsPMEDialog dialog
/ Y7 z% T4 R3 r- X" h5 Y8 D: ]//-----------------------------------------------------------------------------8 T, }: d: e  J3 ]
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:# I% t: K+ e! W( D9 e
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
# K/ L* Y" |# \4 F2 D$ U% x6 L//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口) `; p8 P. t1 c0 F: ?" w& q! q
//   指针将其显示出来,然后隐藏或销毁自身
. s  B+ o2 x( E# o: o$ U, ?//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。0 E$ @; o$ T0 y; y2 x
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
5 \1 o$ h- l; _3 J) e( `//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,& \) _' c: z1 l# F' H. z7 i; V
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。- m) H' f$ f( e  W/ _& q1 ]
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
- ?) g1 l8 v! L( S; n9 N- D3 k* B//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
- q1 C! S0 o  X% I//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。* V# h* i0 r" y6 b
//-----------------------------------------------------------------------------1 i/ A) r. f' o* `( l$ Y( L
// 注意:2 J2 ]  z) o) ^, n* p6 X: y
// 1、在构造对话框时必须给出其父窗口指针
  M1 `/ E5 f2 T% z: \// 2、在初始化基类时必须指定对话框资源模板ID) c. T; v+ t" E
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
0 [1 V5 x* E5 l1 i// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel% T* e" F, Y! O6 _8 b0 e: J
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
4 k; q3 z$ \8 D* g# w0 o+ c; z8 R{& Y6 o. R& [! k, w$ t+ }
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
- V3 A1 j0 K/ r% o// Construction8 f7 S2 X- V' B: ?
public:
, N/ ^* q. a) K/ ~: H5 m5 i CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
9 E$ M4 e" |( x% [' e* ? ~CHsPMEDialog();
( }% }. o8 Z: J: \ BOOL Create(CWnd *pParent = NULL);
  x: ?& w& I6 W4 e  Q( c' z2 m 1 d+ r5 A; S% G- M) Z3 m/ Q  K
// Dialog Data2 W, }, d) b4 S, r# y4 v: a6 U
//{{AFX_DATA(CHsPMEDialog)
% k' @  h* g7 Q( k' x //enum { IDD = _UNKNOWN_RESOURCE_ID_ };
. O$ z& D2 c+ a& Q7 }% O  // NOTE: the ClassWizard will add data members here* ]* D1 f- z) e; b
//}}AFX_DATA
8 m# u" x- z8 S( |4 o
// Overrides5 y. S, ?- Q% f
// ClassWizard generated virtual function overrides% n( \* [& T1 R
//{{AFX_VIRTUAL(CHsPMEDialog)
0 _1 ~/ }6 M9 W/ U/ O! I2 z protected:! s- T+ {# {* _7 ?! b/ L( p
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
. B3 w/ v+ x4 V6 S virtual void OnOK();% M) g; a+ S2 ?; I
virtual void OnCancel();) r7 b6 _/ t  ]! k+ p' t  C# Q
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
6 T* p7 E$ t7 R; [# g7 a virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);) C; L; V9 ^: i+ T% c% w
//}}AFX_VIRTUAL
// Implementation
7 }$ s  r  o2 Y; i. G! H2 W# aprotected:
// Generated message map functions
4 a! m1 z- P. ^) v0 y0 D: o6 U" Y7 N& @ //{{AFX_MSG(CHsPMEDialog)& a5 W( ]3 C  p1 R% {4 N  U
afx_msg void OnBack();
' P6 m# r' K, |3 [- b virtual BOOL OnInitDialog();  f, y) w0 f! b/ W  _0 p  }! Y
afx_msg void OnDestroy();# D9 `  k! _+ c- s1 ]
//}}AFX_MSG
/ R6 O9 f# k8 u, Z DECLARE_MESSAGE_MAP()
protected:
2 d0 {# G8 O# J9 r) I! \  O // attributes
! t" z! l" S. \- K CWnd   *m_pParent;     // 父窗口指针
8 }6 O: ?/ |7 z HICON   m_hIcon;     // 图标6 D: R* P5 O8 V; u
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
4 n  B; T0 n3 n CHsPMEButton m_btCancel;: a. J2 f" ?8 i7 W  M/ J0 Z
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
  t1 h/ S0 e- y; V) _) O# G. z! r HHOOK   m_hkCBT;     // CBT钩子句柄
2 W8 o0 |5 c" M( n; Y, }4 k. K 9 b* K( A( q# ?0 z
//-------------------------------------------------------------------------* D: a- W8 b( T6 b0 i: ?
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog. r$ v3 P6 G5 @/ @" z7 K7 r  a
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
5 c  ]) l: q/ |8 t* E9 c: K, W; A // 链表的头及下一个结点的指针: q8 S% r3 G7 Y4 U" ~' j! Y
static CHsPMEDialog* m_spHead;
1 J1 V3 o1 ^; m: }: H2 o: N& X% O CHsPMEDialog *m_pNext;
// operations! W( x/ ]" Z) a9 n. J: @
// 键盘钩子消息的处理函数& A% m9 o+ C) p  ^) W
static LRESULT CALLBACK KeyboardProc(
0 D: [% R, O, J- l7 I2 `% m4 h  int code,       // hook code
% g. J) n. q9 w4 g  WPARAM wParam,  // virtual-key code2 G7 i* v. I3 s' Z2 K# G
  LPARAM lParam   // keystroke-message information1 Z2 P' e9 ~) ]% r5 |* o! k
  );" ~8 p( y3 d( v7 f
// CBT钩子消息处理函数" u% o9 \% q; q- T9 [. k( t# W
static LRESULT CALLBACK CBTProc(
9 M8 ~- M7 d' }# E  int nCode,      // hook code
- H& D, j% |, b  WPARAM wParam,  // depends on hook code6 U/ Y  A) ?/ e, b6 C$ F/ p+ I
  LPARAM lParam   // depends on hook code
) C: |5 b: f1 m  );
9 G5 b2 S! @* [. F8 x
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
. \$ p: ?2 }; k! A7 m( Y& f static BOOL  IsWndKindOfThis(HWND hWnd);) L% X: p# d9 w) k, I1 C. d
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)5 E0 t% d' C% E. l7 ?( U
static HMODULE ModuleFromAddress(PVOID pv);- _& }# \: M4 j4 E0 N. A1 @4 e
public:
9 i4 W! D+ A8 C  X2 q, F // attributes
// operations
& X5 x1 ^; Y) s2 }8 J1 t4 o // 用于模仿UG的创建一个子对话框,同时隐藏父对话框. ]0 C) c4 |$ k2 X$ n5 E
BOOL CreateChildDialog(CHsPMEDialog *pChild);
9 v  D7 @# q0 O/ E6 X' O: }};
% r% h6 v1 P. _$ i! s
CHsPMEDialog* g_pHsPMEDlg = NULL;: }) s$ L; }/ E1 @$ o0 }( }6 \! m! j
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
4 o4 l5 ]3 W2 L: sHHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)  c9 _& p. B; Q* k( Z% q
: CDialog(nIDTemplate, pParent); C9 |; S! ]6 i& i
{$ i% I$ ?" _' j3 d
//{{AFX_DATA_INIT(CHsPMEDialog)
9 a6 i6 b' U) k5 V  // NOTE: the ClassWizard will add member initialization here( v, L3 o" O& K! X* t
//}}AFX_DATA_INIT- p& S, y) _* p/ U
m_pParent = pParent;
7 `/ i9 o0 w& {& n! Z0 L* @% G m_nTemplateID = nIDTemplate;# C- J" y* ?% o( Q) q/ P0 f6 m
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
2 g6 I+ S: w4 c) z/ F* u5 ^5 A2 Y m_pNext = m_spHead;
" t# {! O, T) b( O: U' z# M m_spHead = this;
0 O9 M9 U" P& s; b m_hkCBT = NULL;
8 J- b5 J  y5 }}
CHsPMEDialog::~CHsPMEDialog()8 l1 j" x; c) Z3 V, g8 {7 R: `
{& E/ y. F4 T# Z
// 从链表中删除本结点
3 ~/ }! d$ J* X" {) j CHsPMEDialog *pTemp = m_spHead;$ ?& Z: b+ ^* `
if(pTemp == this)
; v- K9 ~  U# X8 x* R9 L {# a" _( w3 E% K  M1 r! P$ s0 c
  m_spHead = pTemp->m_pNext;4 R" L* z) n$ c6 }
}
5 h# k2 C( w& Q" l else1 t5 m- |$ f  `5 U" }1 g
{
% F* a# c. n# L, d4 R  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
. o2 A* s, n* A% [2 b1 e  {
! _/ L' H  P5 r+ l: t0 @/ g* z   if(pTemp->m_pNext == this)
9 L. \* Y2 ^7 o. b   {
, m# P: ^5 w& w. Q# v# d$ Y; \+ G    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
( H( h: w1 X3 x) q# K0 k8 p    break;
7 G. I6 S) q8 d. P' q! J   }
6 O; b2 O2 g* R# E4 F# S  }
8 t; g. s7 ]/ F+ z5 s; m  Z; e }
/ x1 p3 m# J, D}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)- [" y/ u! ]% [% \/ b. n
{
% J% |5 @' W* ?6 ^3 l CDialog::DoDataExchange(pDX);, X/ i) t7 e. {9 ?3 |
//{{AFX_DATA_MAP(CHsPMEDialog)9 c6 L' i3 @  I5 S' N: }
DDX_Control(pDX, IDOK, m_btOK);
5 R. `  }3 K" s2 g DDX_Control(pDX, IDCANCEL, m_btCancel);. _+ h7 O3 G) F. ^, E4 P
DDX_Control(pDX, IDC_BACK, m_btBack);3 N' Q, P) J- q" r2 k# K( v$ P
//}}AFX_DATA_MAP
5 d/ J/ e4 _6 v* s4 b+ N. f; J}
3 @0 f: P1 y6 ]
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
$ i% P3 S# w; u# a' M6 P' r6 j //{{AFX_MSG_MAP(CHsPMEDialog)
6 j" L0 a, c' f: v9 H$ s ON_BN_CLICKED(IDC_BACK, OnBack). B$ m5 M$ L5 ^# W
ON_WM_DESTROY()3 Q/ x1 r0 J, e" \3 r8 Y
//}}AFX_MSG_MAP
; p! w" t( R2 b  d) F7 SEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
/ d$ G- T* ^" |) {4 u1 ~3 A// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
, `# j8 Z2 ]7 R, s9 a# `) N; D{
, q9 P8 E: C3 P# _# @; r7 J7 V m_pParent = pParent;8 g# L& m  C% q$ z$ R
return CDialog::Create(m_nTemplateID, pParent);
' o, x7 m% v% @}
7 B* s; R& T; \- o
BOOL CHsPMEDialog::OnInitDialog() ! R! G  r$ a+ i' G1 |8 q# o
{* e% L  H, o1 q; A4 \8 i8 q
CDialog::OnInitDialog();
// 设置标题栏图标
0 Y0 o) j5 ~2 |1 N1 p/ N% w$ H SetIcon(m_hIcon, TRUE);
1 o6 G& Y: M+ _( J% U SetIcon(m_hIcon, FALSE);. q# L4 ?- A8 [! v3 T( w$ e6 X2 ?* x
$ Y1 y/ {. D0 u) [9 c/ ?7 {
// UG的对话框的几个标准按钮没有TAPSTOP0 L3 A0 w  b2 v
CWnd *pWnd = NULL;
5 Z5 Q( E+ q3 F! T" g pWnd = GetDlgItem(IDOK);7 v; G3 C" G( m% Z( [
if(pWnd)# m8 y' G; Z. [# {  H
{: P8 A/ d9 o/ R) O* {( l; R. Z
  pWnd->ModifyStyle(WS_TABSTOP, 0);
7 P% R. \3 A9 }# F3 E }
, S% X! ]8 a) d" b& h2 u' B* `$ g8 d pWnd = GetDlgItem(IDC_BACK);* h  \; i' h$ O% c& G: V( e
if(pWnd)
6 u8 @* Q- I% F% R* b6 S- } {
, a2 g$ e! b, N) I  pWnd->ModifyStyle(WS_TABSTOP, 0);
' T0 b9 c* a6 B& ~, F$ L7 c }
/ C& L( x9 S$ P6 d) d pWnd = GetDlgItem(IDCANCEL);/ Q3 `$ K- X! R/ w( e6 V1 w$ o
if(pWnd)8 i$ o  |: k- n. Q5 O  M+ b
{% f* U' v3 ?8 t3 k* c; Z9 H
  pWnd->ModifyStyle(WS_TABSTOP, 0);
# |6 V$ z- ?2 g) D* G }
: r$ ]' y3 c( X  y) _0 A+ l5 a0 ` . o3 _  S- W+ u/ k9 s
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
6 N) ^, N, y. F$ V7 j if(m_hkKeyboard == NULL)
8 Y( X5 Y6 n0 \5 N {, r: W5 i; u* V  M% h$ g: i: E
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());& T) w1 W8 e2 }* o7 J4 y
}
  H8 O/ ~! Q. _* Q* X if(m_hkKeyboard == NULL)
6 L0 Z2 w$ y, x5 O$ L4 |# @. | {
- l2 M/ s; i' y  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());2 m* p" {: A! R# b! v* V0 p
}
if(m_hkCBT == NULL)* N1 n1 v  [: x
{: \5 q8 S$ z* D# w( f6 \
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());: I2 C- }" o$ G! j" B
}
9 {& r) h: l& H2 y( i: V8 W if(m_hkCBT == NULL)7 @/ A' M% x0 I
{( C7 I' y; S7 k' E% k8 ^/ {) {
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());: J! Z, k' a& e9 S- s% A
}
3 G, p3 Z! W4 G: e, q " a* Y. K6 G; x2 e: z
return TRUE;  // return TRUE unless you set the focus to a control
/ y/ D: Y1 l5 N" ~               // EXCEPTION: OCX Property Pages should return FALSE6 d; b& Y0 C5 X3 K. y6 c
}
void CHsPMEDialog::OnOK()
" Q: D% L3 x0 o% V{* J1 v8 q7 n5 r! s& o* t
CDialog::OnOK();
9 V9 U$ l0 S2 `6 v0 {) F: X# g' E if(m_pParent)
* d6 x! r6 V0 G; h/ ^* }  X- R3 e {
6 `5 Q; r  C0 f8 U5 [  //m_pParent->DestroyWindow();& B6 Y" \. K5 y( i3 F9 w9 q
  //((CDialog*)m_pParent)->EndDialog(IDOK);
& i. `( n0 G* Z% |3 S  ((CHsPMEDialog*)m_pParent)->OnOK();; _$ J4 R$ m, T" G! _
}! R' K* q3 {. u/ f9 A
}
void CHsPMEDialog::OnCancel(); ~# }1 d' L" `# _& X1 _, G
{
9 R2 `6 \2 v  l. N4 w CDialog::OnCancel();2 `  G+ t1 m. q) H) M. {
if(m_pParent)0 I5 @) q' h+ p" _3 X% r
{% b: b$ c# I* R
  //m_pParent->DestroyWindow();$ f- {' w) v2 `, L2 X2 K
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);$ W5 l0 R/ p* m' f3 x! r- P, S
  ((CHsPMEDialog*)m_pParent)->OnCancel();
2 y3 d! c$ S% A) M7 N$ F; d }
# E' P( t4 E  b6 h}
void CHsPMEDialog::OnBack()( K* K  U$ n8 J3 G3 G$ b. b
{0 Q3 V+ a* @3 Y# s$ Y) Q3 W
if(m_pParent)
0 c% n9 K+ r- _5 t: \ {
3 ~. V( t  L% z. w; {, `8 m  m_pParent->ShowWindow(SW_SHOW);6 v; N# O' T5 Q# T7 c! o) v
}
$ n" I0 K( U- Y& L CDialog::OnCancel();* Y4 r5 L) |$ d
}

5 c; @! z7 J9 K8 I3 o* b' A9 b2 k) bBOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
# h- F1 `) V% X) R2 F! ^{
5 \4 M$ |0 }9 m0 |' Z, z7 s( ?" g* S3 m BOOL bRet = FALSE;
4 x" K% W( d" e9 Y' N if(pChild->GetSafeHwnd() == NULL)
3 I8 Q) B1 \4 f0 B/ t {. w) J$ r) V& `
  bRet = pChild->Create(this);
5 h/ F  z8 b) p  k* l' Y }, _) \! |6 k' Q# g: l
bRet &= ShowWindow(SW_HIDE);
3 }7 t9 p4 y' X$ e bRet &= pChild->ShowWindow(SW_SHOW);' N( V8 W! `) F: _
return bRet;* I, f% b. k0 ~" d. R) t7 G* ?
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)7 P2 E' w5 T3 F
{# }# H  J+ [  A3 E
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
& R$ b6 G4 y2 ~2 Q {/ }; @0 I' R1 u* P' r; Z6 i! \
  //TRACE("Key down/n");
& |7 J1 D' s2 _$ w* P5 f4 a9 j  CWnd *pTopWnd = CWnd::GetActiveWindow();4 W9 K) e5 ^7 {  V+ P4 F; f
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))$ C1 b( p4 i5 d: b8 X  [$ [
  {
& y! i8 l# q, y7 F7 R$ N   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
: v/ E" G' k2 }* R4 R+ |   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)1 }2 g  r% h' N: D
   {/ S7 e  O( d8 d8 W2 x
    // 只截获tab、esc及回车键
9 `6 w& }' b) `4 _8 D+ {. F- O    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
7 Z6 q) ~3 W3 |9 S    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);+ P  H9 N$ m7 I+ m* ~
   }
9 L& Z, W/ r# W+ p; ?; t   switch(wParam) {
7 I6 N/ R" J  U' l, G9 [0 g   case VK_TAB:
& O6 N4 f0 c4 V# G* U5 X7 K    {
" r3 r  E5 {, [+ F0 K" p# Z( y. M* h     CWnd *pWnd = pTopWnd->GetFocus();! ?' u: a$ X2 e( l" l  a, f. E
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
7 x2 D: }+ R" P9 z8 [$ @* P. p     if(pNext), D( O, ~$ q/ j. s5 T' [$ R
     {
4 V5 C- z  X* h9 W) t3 L/ ^- l% ~( Z2 [      int nCtrlID = pNext->GetDlgCtrlID();
* b& S1 O% n* o0 I. Z# r      //TRACE("CtrlID = %d/n", nCtrlID);
  U; j9 R- j1 B; M9 E0 i- M      pWnd = pNext;
& V. y7 U( V7 ^+ d      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
- p. a* ?% B- j3 }$ U      {
/ F) O6 T2 t# P- `) b2 }' [- x9 J       // 根据UG对话框的属性,这三个按钮是没有焦点的! I& o& \, X0 ]) w( g( K5 G
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);0 F, J* r0 a" f7 R
       if(!pNext || pNext == pWnd)
6 |' g, l8 x" N% F$ B, N4 a. g       {
8 N( x$ Y0 a: O- z  n* }7 ?        // 对话框上只有上述三个按钮
7 ]3 x4 J% W! d) R8 @        return CallNextHookEx(NULL, code, wParam, lParam);
1 V  u5 m" L4 Y% |       }
, u5 |4 ^( c+ e. ^/ ~/ I, w       nCtrlID = pNext->GetDlgCtrlID();
. _5 u2 B9 F! D9 U7 g: ?; b       //TRACE("CtrlID = %d/n", nCtrlID);
2 O  i/ t+ l& P: i      }" g. D2 G" T5 v, |
      pNext->SetFocus();
7 q8 k* ], K$ g  q+ H0 W     }$ _5 x7 s5 s) T% [' r8 L) R% S; L
     //return TRUE;
! W: O2 y& p, `" T8 ?9 V    }
+ q9 h  R- s" e9 i. B1 M, t6 W    break;
3 ]" [& j/ G- I% ?  E. u' k% D   case VK_ESCAPE:& Z; p7 m8 ], z0 V. _* K3 k1 F
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);" _) V, E! n( t- a7 n1 v/ p
    //return TRUE;: C& @8 W7 h+ Y
    break;2 e8 T2 s+ Q4 o* {& x
   case VK_RETURN:
% b; y+ @: y' W2 ~6 U    // UG实际上并不处理回车键3 z8 y' C2 i& f8 u! s& J7 t$ R8 U
    break;( ~1 O$ @" p! u* N6 Z& O
   default:( A- {' W9 e# B' |( j: b6 p
    break;% B! w3 B, ^! b
   }5 T* h9 q( S, h! J: e* x4 P9 A
  }
5 g# j$ G8 z/ K+ T8 w; S# u2 g }$ q9 O0 w: q7 ]
return CallNextHookEx(NULL, code, wParam, lParam);4 j% T# n7 z* T
}
void CHsPMEDialog::OnDestroy() 2 h3 z$ u) M. b: N4 Q1 x. t
{0 U3 j5 D) h% @8 t
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
1 ~# G+ S- R5 _ if(m_hkKeyboard); Q/ l' Z0 a% {' ?
{
+ m2 x6 F" T# q  }( t2 ^5 }  UnhookWindowsHookEx(m_hkKeyboard);
1 p( w  c+ u' i( S, V: V8 Q+ a; d) l  m_hkKeyboard = NULL;  L  ^% ^7 g" v+ X2 J
}
if(m_hkCBT)
: R( N- g9 E' P1 v! K1 ] {- z: ~% P$ M) T4 g2 n. z
  UnhookWindowsHookEx(m_hkCBT);
! o6 `5 _7 r* t+ k1 e1 x' y8 k  m_hkCBT = NULL;
5 q! F$ _+ o- w  S) a- r1 v }
: n4 O9 L- ^) T3 ^1 }. h}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd); f+ Z( Y. ?0 B4 v9 G
{& @! m8 t0 M: _1 J
CHsPMEDialog *pTemp = m_spHead;9 S: F/ w9 z9 Z3 k
BOOL bFound = FALSE;: H3 E3 M/ ?, [' P4 |
for(; pTemp != NULL; pTemp = pTemp->m_pNext)/ h" G* Y0 i* u$ b
{, Q) H: x9 T: d$ Z
  if(pTemp->m_hWnd == hWnd)
  D6 ~4 }3 Q5 V3 I& G/ P  {
: b* M2 e( x& |! p) [" {* I   bFound = TRUE;
  q! a; D- i  i7 J3 b   break;
9 V9 o. I! d. c) `9 g9 H  }% T8 d$ D( L4 f$ ~; k
}+ I3 H% f9 h( z( l, \
return bFound;
& _1 g1 @( W4 t9 S+ t}
// Returns the HMODULE that contains the specified memory address: L- ^" u# a9 ?& |
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv) ( b5 z! @# S1 }2 y6 T$ D1 `
{1 C( ?1 J# \1 {2 g( {1 q

. G, }3 [: z2 k: J( G/ c MEMORY_BASIC_INFORMATION mbi;
+ O  Z# @2 O4 N( H, B/ x$ G% ] return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)   C1 p; C0 u1 m# b
  ? (HMODULE) mbi.AllocationBase : NULL);! s! K9 @  Z/ m4 V0 }4 R. R9 ]
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
) n  Z' i% E( T{# [5 W$ W3 |& K1 V
if(nCode == HCBT_CREATEWND): U7 H, G# F$ ]) W& E
{
: U9 S, @7 s( n) @7 j- e* J  //TRACE("A Window is being created/n");
+ H; Q, ?1 y: y" X  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;
. b( Z- `* m, k4 E. O6 Y  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);6 E% ]6 B$ x* n+ a5 O
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
* ^' \+ |1 A7 d& H/ {5 R  {
/ h7 X" u- N0 D# s: Y6 C   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应) J1 X) I. p" Q. S: }0 H
   // 取得窗口处理过程内存地址; I4 n( L. E# F( p" y1 x' s
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);; ~: A& ~! p1 |1 A3 ?( ~" i! Q
   if(dwUserData)6 ~; f* Q, ]: O/ Q, f( k1 Z
   {
; @# `! T! }4 t/ {" r0 F* k* y    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
- N- X8 G5 s) L) m  @" {    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};: K. ]* Q( ]1 @
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
  o: |. i1 h" b    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
) d" W% \- u# D) F* Z' `+ p7 G    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
: N' y, a% ^$ g$ O3 D2 Q3 S( s    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);3 A+ H; ?6 j6 E5 Q0 C
    if(stricmp(szUGPath, szModulePath) == 0)* e+ Q" M3 v: f; o, p4 g1 S- e
    {
. u. W% C9 b3 _( C* k+ ~4 ~0 T     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
& C& H. w: X5 ~) ^     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)! M' Y( K( @+ a! S4 d4 J. Q
     {
: V1 O/ q( B, z7 V! ?      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)2 p$ S& I1 v* H
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd && 8 @. y3 h; i& A/ @( X8 [
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)7 o; B6 e$ r2 P, b& _
      {
' d. O- n; l: d$ h7 g       // 窗口非本窗口或其子窗口: f% V( D. o1 E
       g_pHsPMEDlg->OnCancel();9 e, I2 M, }3 i9 h: p2 R
      }1 c" w: R( c: U+ E
     }
8 N; ?# U* [2 W    }
2 @. T  g- Q4 C! k$ U3 X: T   }
8 R8 J) e. j7 W: F. m3 J  }
$ y* a! L9 o  m. ~  N* q" j }
' ^9 l4 c. _9 R' r# O9 v; e$ |: m- {: B return CallNextHookEx(NULL, nCode, wParam, lParam);2 J9 [8 Q, A: P% p. c
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 4 ~. g3 X. g% k8 T& X+ F5 G
{
6 R: \1 j0 V- \! h( [5 m // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来
- x6 e, n8 G# X9 D! } ' P8 \9 ^6 v3 t' `( M
return CDialog::WindowProc(message, wParam, lParam);
- k+ o/ _2 f7 @8 t: E' p0 L}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) + v  s+ Q6 I- I; y8 u
{
, G" ~- y/ v1 M+ h; _/ x+ E
3 @) f% f& A9 d4 f return CDialog::DefWindowProc(message, wParam, lParam);( b  X7 _: D8 C
}

4 D) ~& \. I+ a6 t4 C1 _* y; P& H& ^+ R4 C
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了