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

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

[复制链接]

2017-8-31 13:24:24 3336 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------, [9 @- S- z7 H0 ^: {
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类* [. O$ l" |3 i4 A9 f4 P1 M  G6 C/ n; F
//    该类来自网络,稍作修改,版权归原作者所有& ?: _1 j; ]) s6 I3 z7 \3 g
//-----------------------------------------------------------------------------
% ?9 _+ U4 |7 {1 I7 M. pclass CHsPMEButton : public CButton
8 d- q# r* O* A" ~4 z$ w{
( p2 p3 Y7 Y( r$ `9 w // Construction. _" w1 I  }2 C3 v3 i  e
public:. d( Y, R  }, t& Q% E
CHsPMEButton();
: {6 U) b+ C" t8 y7 c2 {- x 0 i* Y- R: o4 G2 u0 [' O& R
// Attributes
5 {3 L$ ~5 r; D# h; P  P$ Q8 \public:( z$ o- N# V) T4 b' f# G
0 c# Q1 [2 n* [* U6 `5 R. ~2 @
// Operations$ T  h$ d. j5 Z! W
public:
; L/ t2 }8 J* \% `% s% t! ^2 b inline void SetNormalTopColor(COLORREF color)
# Y* y) Y* ~0 X+ o% ~  R4 e {, t. ^+ F0 [# w. j
  m_NormalColorTop = color;6 p) p1 ^2 Z2 X2 D* N5 c; I. S& o
}  B2 H  c2 l8 J" |) R
inline void SetNormalBottomColor(COLORREF color)
- E6 K, s  B* \' u* o, N" V* p {9 F0 g; }2 O4 S8 V' l
  m_NormalColorBottom = color;5 U6 o6 r8 G/ ]& \
}+ X$ R/ j# ?( B3 H/ k6 j# |! J
inline void SetActiveTexTColor(COLORREF color)
, `0 O; F% D* @ {
( c; m/ P$ ~- \" I4 Q  m_ActiveTextColor = color;
4 h5 K5 d" x+ ~ }' D2 ~6 d: d5 B
inline void SetNormalTextColor(COLORREF color)6 m+ M. n$ B6 F. N* }+ F0 h
{
5 _% o; C0 F0 N9 [, D0 y  m_NormalTextColor = color;" w: j4 @% f9 [$ h
}
; Q% }, m) n/ \ inline void SetSelectTextColor(COLORREF color)" @. |8 ]/ k& t
{, m& l4 p7 Q( X
  m_SelectTextColor = color;
) L: `: h8 w- j1 _( i% |& e0 G7 n! C% Y }6 T! F5 D0 y8 Z) U# K# A9 B( k
inline void SetFrameColor(COLORREF color)* U  T$ i* }- }" s' Y. }& q
{
! m+ V7 T+ V1 p  m_FrameColor = color;) Y/ \" K0 I' i9 I5 w
}5 z+ }( L8 o1 m
inline void SetActiveColor(COLORREF color)
" X0 S2 f+ o- y5 E+ a  ^+ A, D {
+ a& }1 B: F; I  m_ActiveColor = color;
$ \) [2 E( Y8 C7 n, O+ m }8 s; o; j- G# m, f2 X) [
// Overrides2 x8 E3 K& @) `0 E3 k8 R
// ClassWizard generated virtual function overrides
1 F+ H0 Q" v1 h/ K+ z* T //{{AFX_VIRTUAL(CHsPMEButton)" C+ s0 L6 v7 \
protected:
" I- Y+ S# S. k" O( y virtual void PreSubclassWindow();# _2 X5 A% Q* O1 }
//}}AFX_VIRTUAL" R* u" F4 g) F1 V/ @

! V! J" N: i! V/ | // Implementation% m! |8 A1 e( v( q/ V$ E
public:
# f7 ]5 h3 T) U1 c' @" v, F virtual ~CHsPMEButton();
8 J+ l) R7 U( U$ J . t( |/ D/ e" k
// Generated message map functions
- b& `0 G- J+ u1 M# r% Sprotected:( D% a) @" ^& H# b% c3 x' C4 ]
//{{AFX_MSG(CHsPMEButton)
& I/ E7 ^) y" V( a afx_msg void OnMouseMove(UINT nFlags, CPoint point);+ R/ Q) Q& f& f/ e4 W
//}}AFX_MSG
) O; \% m, i" ?3 h
: z2 L- O+ k7 g void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
) d! w# C# C# ~ void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);+ t8 a! B! u# N7 y
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
+ b# X: V2 W' g7 p/ L LONG OnMouseLeave(WPARAM, LPARAM);+ a) h+ x  c, Z+ q9 q
BOOL m_bIsMouseMove;& z$ p" w5 Q7 ^8 ^
6 i; m* x( M( B' r' |
COLORREF m_FrameColor;
3 {5 B- o" w( N; m, x" X COLORREF m_ActiveColor;/ S5 d5 `- p" G& `8 n1 A

5 h  [% R9 ]: y; [0 { COLORREF m_ActiveTextColor;
/ m- H# i' ?0 O- i COLORREF m_NormalTextColor;( G7 z3 t1 d8 K$ V& N% r
COLORREF m_SelectTextColor;
9 }$ _7 t# `, C" T, r
# p( X9 d/ I5 |2 ?# a3 Y1 W COLORREF m_FrameHeight;5 H, f& f) Y, d0 L: ]) o/ I
COLORREF m_FrameShadow;' g, f/ a% Q8 @; C" U

8 _  u3 ]0 b$ b8 G2 @ COLORREF m_NormalColorTop;
5 P, U' j8 ^3 \+ K: x COLORREF m_NormalColorBottom;" G" H: Q, p) K  ?* L

6 q4 U5 K6 x7 y DECLARE_MESSAGE_MAP()- u& p6 y) M; _! V- {
};
/////////////////////////////////////////////////////////////////////////////5 E1 M& c4 D' S, ?. T( e
// CHsPMEButton
CHsPMEButton::CHsPMEButton()  P; n( n# G+ H
{
% D3 G% Q6 t$ _2 } m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
3 I8 m: z0 t1 ^( f7 s! T  @ m_SelectTextColor = RGB(0, 0, 0);
, Z% b! j/ c' d/ Y& r' t" z9 k m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);: Q: w3 o% n, q0 K# t5 e
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
6 \. H% H( T' h; z) d6 K m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
* C0 n9 d1 D* B% `$ x1 {$ t; h m_FrameHeight  = RGB(230, 230, 230);
/ M- m! b8 a$ f6 g  O1 d m_FrameShadow  = RGB(128, 128, 128);
; g( F) q8 s$ u; P9 a: P1 W6 Q9 B! l/ I}
CHsPMEButton::~CHsPMEButton()1 o& ]5 z7 O, I: J& L1 V6 h! p$ ?+ _' x; B
{
/ l) B/ N6 R5 R: K$ T5 ?1 Z7 j}
9 b" W) J: H9 m) w) R- n% I: o
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
) @( f: _& P: q. `+ S' r //{{AFX_MSG_MAP(CHsPMEButton)
) ?* U( L, o" V& _9 W! H' `! t ON_WM_MOUSEMOVE()" i+ X! I9 R* W, }( E- `8 n8 u
//}}AFX_MSG_MAP5 ]  k0 Q0 `8 P% R' D
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)* W( k9 m1 Q4 X% b4 [* |
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////9 b! O# r1 r& u# @3 [9 K( ?/ `0 M, d* L
// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ), C, ~8 ?8 ?" {1 t9 F/ t9 U! g
{
' J* z9 f' B4 h$ I2 f //*5 I4 I. n, a0 x, a, }3 T" [
CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);6 o# e# e- q" u0 e  k' U
DWORD nState  = lpDrawItemStruct->itemState;: k8 C+ J+ r" w) g& {
DWORD nAction = lpDrawItemStruct->itemAction;
1 p1 `; T9 Z0 D4 ^ CRect rc   = lpDrawItemStruct->rcItem;
" s# {( n$ q* M& p  ` UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);! L/ W" x% }7 x. {! {
CString strText;' \  O* t9 n0 m% |% m0 |
GetWindowText(strText);
if( nState & ODS_SELECTED )
( h  g) o3 t0 y6 K- A% B {1 v0 r8 d+ g5 s+ B2 c. i; c; e" c/ F
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);# {% b$ y( {& H
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC); . |3 T- I2 R; s1 R7 y
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);+ U6 v' B. j& f: g( b6 V
}# b* B2 Q2 G9 r4 F
else //Normal
) a& r5 l6 I9 b7 t( z9 |- N  [, ^) I {) X# ]2 b; A/ k; `' Q' N: s
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);  e3 P" O+ Y! Z  a% K
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
/ e1 E# V' i/ n2 W2 y& i }
if( m_bIsMouseMove ); h; D, b! x9 N2 L  P8 o
{
3 ?+ N/ {7 t6 T9 w0 F9 i8 S  CRect rc2(rc);. Z: o  V# ^# R6 I8 J. N5 T6 [
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
! S8 v% r' P& f* S3 }   m_ActiveColor, rc, rc, pDC);
9 M  ]" |1 U. J- d) x8 ]% S0 e  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;; A! f& X+ f' b1 S- k" D
  NullBrush.CreateStockObject(NULL_BRUSH);8 |2 f' J, D0 t* K- }" ~
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);/ |- [4 k' B5 {, k& V9 m
  + `$ A+ Z8 e( o5 @7 t( M
  CPen Pen;
  Y2 J2 Z! h9 T" ~  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
4 P: x8 k" t9 y  o1 ~" Q  CPen* pOldPen = pDC->SelectObject(&Pen);
) v' K% `9 G1 i% |  rc.InflateRect(1,1,1,1);' V* @6 e0 V, i/ b5 `) H
  pDC->RoundRect(rc, CPoint(3, 3));
* y& t+ Z, o0 t& o7 E, M  //rc.DeflateRect(1, 1, 1, 1);
* ^' C0 ]/ z* v  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
4 g# u/ g( S- [* |" k' q! U  0 w/ u3 _1 E3 e7 B2 m* M
  pDC->SelectObject(pOldPen);
5 i9 f5 e$ S2 G4 i9 n1 V1 ]& |7 U: T  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
: |( T" H; Q# T8 l( Q( Y }
: {: [( R8 u9 I8 B4 ^8 U3 I3 L
. m/ P7 k8 T; T0 T4 a+ F pDC->DrawText(strText, strText.GetLength(), , T5 \, d: W4 d) C' y
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);+ @7 W2 u: L7 Z/ B6 h; _& ^9 D
//*///
$ R; ~1 ]  G" M" c# c! S. [}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
' j% x, ^( |* _$ F  P{. G) b: d3 C* C7 ~/ R
// TODO: Add your message handler code here and/or call default
+ e  B& @' X# y/ M' H, b! w if( m_bIsMouseMove == 0 )
/ t# @/ }- l6 U' m6 ?: S$ {  _ {( ?  U; j. W4 w; b5 W; }
  m_bIsMouseMove = 1;+ U8 R0 V& K9 O! J
  Invalidate();9 \* u" t% Q9 ]9 r, n8 U( V6 ?
  ; ]$ s4 ?- Q) A0 z3 e! f+ U2 X6 ]
  TRACKMOUSEEVENT trackmouseevent;, J" v( q, {3 r) t+ |. ?; g
  trackmouseevent.cbSize = sizeof(trackmouseevent);6 l7 s8 x. @3 t* S" G* q
  trackmouseevent.dwFlags = TME_LEAVE;
+ z# X. r- C5 [( C$ t/ `  trackmouseevent.hwndTrack = GetSafeHwnd();7 N. r( y- e6 G8 U( ~
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;1 }5 f. O4 F! B: v7 A* f. u5 B$ a
  _TrackMouseEvent(&trackmouseevent);
, ^2 `: h2 L+ t }
" \9 O% c% P5 C' m1 _/ Q 0 q+ J" p+ `! f6 j9 f
CButton::OnMouseMove(nFlags, point);
# x( m4 x( Q/ B/ _- i3 h}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
9 S) \' K+ ]4 U( z9 H{
5 C7 B$ g' f9 H! ]1 a m_bIsMouseMove = 0;
* Z! [( p! f6 ^2 G Invalidate();
return 0;- T2 `, v: N3 V" {3 F
}
void CHsPMEButton::PreSubclassWindow() 3 Q. \/ V/ N# \  h4 D
{
) _, M! K8 V! Z" D4 Y/ }' k& H( e) L; W // TODO: Add your specialized code here and/or call the base class) H5 {) V, D. [$ z& l+ F# o
UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style9 `3 Y5 k- W/ l4 Q. D6 @
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();- f2 f  T% O0 H
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC). k, w1 f4 @+ }# G2 I! @7 P
{8 T. l/ |$ Z3 F! l& d
CPen Pen;, ?2 k3 x# ~& J% C. P1 B. e) D
CPen* pOldPen = pDC->SelectObject(&Pen);9 s+ m9 `# O" g  b1 ~8 f1 C
7 r9 B4 Q; V$ R% r/ c
int R, G, B;
5 g! M! s7 Y0 i% N* z% g# f% k4 ` R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();! {. c3 M8 H  B5 r
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();( o" N( m, X# I! T
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();2 e& }3 |# q- d0 y( J

) _8 x7 l* H' H4 p6 L //R = R>0 ? R : -R;
7 ]- A0 l6 q* M0 \9 e6 p: j/ V //G = G>0 ? G : -G;4 ^9 i  n! }& I3 G" u" q
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
8 X6 e& x. t7 c- g$ B( g6 N, j# x COLORREF ColMax = Top > Bottom ? Top : Bottom;
4 S; \) o+ N. ~) s1 n- Y" ]0 K COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
6 @/ R% K2 I9 g( q- ?9 F" g {5 B7 ?: H. o/ }- p" `
  ColR -= R;; f; K% j  f5 _$ B2 p
  ColG -= G;8 I" J4 J  j" {
  ColB -= B;
  /*
2 `1 s) O5 {8 N9 ]) O( E6 C  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
) _( i, J2 N4 h! `- q5 o, Y   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||7 a! `& N. [, E! W
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
1 b# `" u% G) u1 E+ |# B; G  {
0 h1 p1 d5 H& o4 e/ p/ P   R = G = B = 0;, ^5 K, J' G% t% h  ]+ n
  }///*/
+ k) P, M" }% v
  Pen.DeleteObject();  ?5 Q  `, S- L4 X$ k0 ?2 o
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
. w% z2 ?! i5 G6 v2 h! a   
0 _* c! j* a* q2 `6 u: Q  pDC->SelectObject(&Pen);
$ {) X+ U1 X" F  5 `: N. U" ?  c9 r' q
  pDC->MoveTo(rc.left, rc.top+i);( {* f2 z) u; x# r; K$ K; f( a
  pDC->LineTo(rc.right, rc.top+i);' V! N, |% o" Y) o% R" ^" d
}
pDC->SelectObject(pOldPen);
9 d/ s$ l! z. _: _}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
, x( K5 N0 _( g5 T. w7 s6 d{9 Z, B, ~( V! g+ G5 D
CBrush NullBrush;7 k- }1 [7 u# V' K, o. ~7 B7 J
NullBrush.CreateStockObject(NULL_BRUSH);3 h8 U  X: `  ^% Z' [
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;) ^4 ?5 Q8 h! ^- S8 W( |
Pen.CreatePen(PS_SOLID, 1, FrameColor);+ z& T& E1 x, ~9 P
CPen* pOldPen = pDC->SelectObject(&Pen);
* t% w' m9 L. ~. I " [0 c3 P. Z4 O+ N: A' H# ~
pDC->RoundRect(rc, CPoint(3, 3));
5 ?9 @; u; S7 G# z, p! X+ X4 ^: L5 H rc.DeflateRect(1, 1, 1, 1);   |: ?0 R: Y, V. Y5 P3 {4 U
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);4 l; u  h: X; Z, A9 F" }
pDC->SelectObject(pOldBrush);
; }) F! G2 M$ A$ D& k, C3 a0 b}
1 }& U! u- L& A3 n' b& H- Z" Z
/////////////////////////////////////////////////////////////////////////////
1 r4 d% q+ k, x  g: c// CHsPMEDialog dialog. e" r$ r% A! i# [- Y+ ^
//-----------------------------------------------------------------------------6 g/ Q, ]( c4 Q9 X1 p
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:; V- A% l2 X8 C9 @4 T$ r
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级) `6 P( r" `3 K1 T. ~( e
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口( w  s9 O. K# w6 o- n. ?1 Z
//   指针将其显示出来,然后隐藏或销毁自身
- s$ o# T$ W! H0 D( o: p//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。- U& S2 y6 `4 O* g! G+ j/ M
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
, c/ h: w: ]7 s+ `" r( q, U& C//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,2 T0 I  u* F0 i& g6 a" Q* I$ E
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。2 Y6 \$ S' t" J& W3 u2 L; ]
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
7 P  X+ M3 K3 {0 |2 d//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框  L7 f, ?2 Z+ e- o" E1 S: _# z
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。1 Q; H4 P! B; O3 D4 P1 n
//-----------------------------------------------------------------------------4 W- b) Y2 Y! a9 e/ T3 Z
// 注意:( C  A7 G  E/ [* t
// 1、在构造对话框时必须给出其父窗口指针
9 o/ _. ?' S! c5 g( f8 t! q* V// 2、在初始化基类时必须指定对话框资源模板ID
, ~0 s/ P; B% _1 k// 3、对话框资源中必须提供ID为IDC_BACK的按钮
( d" d# D) }8 W1 E# Q+ F// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
$ x7 ]& ^; V& u0 V! A//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
6 ]+ }8 n! e8 T. [  y) e7 W{( x/ k' L) j) U7 a
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
: u; W" [- p8 k// Construction
: k  ?+ `9 j( U/ m9 ~- |! E5 v  f7 Lpublic:/ ?( ~: n& b. N: A5 E4 y& ]
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
6 L2 ~/ c( O' H( e% Z8 G7 T2 I4 H6 Z ~CHsPMEDialog();# N$ h7 f' \+ K) o
BOOL Create(CWnd *pParent = NULL);
' v! K0 r. {/ g. S6 S6 y. G4 {
8 L! j- b/ |1 x0 N// Dialog Data
( A9 m( x" k: Z& d //{{AFX_DATA(CHsPMEDialog)0 _6 W( ~- G4 L; W$ k2 ]
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };4 J( {( K8 M8 |
  // NOTE: the ClassWizard will add data members here
; e- E+ V" ~% o: x; c) F //}}AFX_DATA
( [7 O) y3 o2 i7 C. W2 \
// Overrides
+ G' G8 T. Y6 y( m6 v+ @ // ClassWizard generated virtual function overrides
+ ?/ e3 r2 G6 H- L3 S; r //{{AFX_VIRTUAL(CHsPMEDialog)
/ `* T( l% l% J# [+ I& D; x protected:# s; U4 H1 ^5 h; Z# |: q0 ~
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
/ d& L" o" n' K% B virtual void OnOK();
9 l% h  d. z% H# s virtual void OnCancel();' m$ g' ~5 `5 J. a( l
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
6 p$ k4 r1 z5 X5 W2 f virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);. F$ r; a' I9 W: D* M' E
//}}AFX_VIRTUAL
// Implementation4 f6 |- R/ j  ]0 I- k
protected:
// Generated message map functions
! r9 G" S+ J8 j+ e3 E4 x. h, \, J+ P! x //{{AFX_MSG(CHsPMEDialog)
" a5 ]& Z: t! ?/ b+ O3 ~ afx_msg void OnBack();
5 D: m. ^2 [' K9 y* `" K: L virtual BOOL OnInitDialog();, {7 T4 f9 D$ M6 s( L
afx_msg void OnDestroy();# `0 f  a" V8 z- R; u8 w5 T! b
//}}AFX_MSG4 z9 z1 t9 ]. c7 _3 g7 j" ~  W
DECLARE_MESSAGE_MAP()
protected:! s6 ~! L( v* f  @  x8 |% L$ X
// attributes
3 ^# x8 y" U3 r4 a$ } CWnd   *m_pParent;     // 父窗口指针
% Q9 L  d: J  S  }0 Z. d9 P HICON   m_hIcon;     // 图标
  F* A0 \) S5 u/ _6 z) z( F UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
& g/ U) V, S6 h1 |5 T CHsPMEButton m_btCancel;# l8 _/ w) A8 R2 v& ~6 n3 e
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
: @, o# H! `( H3 t7 m- l. g HHOOK   m_hkCBT;     // CBT钩子句柄
& y; K$ o! c) V 9 X* Z2 A, M9 A- @
//-------------------------------------------------------------------------
7 x* ^4 s; X# M) y' m. [' { // 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog2 e* i3 g! \1 t3 n7 G& E' q
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
" o- L: {0 x4 r3 D  V. F0 ~ // 链表的头及下一个结点的指针
" k9 I! u6 o1 e- ~ static CHsPMEDialog* m_spHead;
0 f9 C4 J3 U8 g4 E CHsPMEDialog *m_pNext;
// operations
6 Y  L% i$ {1 _6 L // 键盘钩子消息的处理函数
2 ^) V4 Z4 k7 H: g) v: C2 ^! V static LRESULT CALLBACK KeyboardProc(1 K9 z5 y: r2 S
  int code,       // hook code1 V$ s# m! V8 B
  WPARAM wParam,  // virtual-key code
* d* a/ f! N% Z3 V& G9 x  LPARAM lParam   // keystroke-message information2 m$ m* `1 c7 G2 u5 ?( T7 ]/ [" p
  );' }/ i: M5 ?: {; g% R% Q
// CBT钩子消息处理函数
7 J! q; b' f5 ]# A static LRESULT CALLBACK CBTProc(9 |/ }) Z6 A7 L$ P% f
  int nCode,      // hook code
9 S) `/ V; ?% d  WPARAM wParam,  // depends on hook code! s# x0 f+ F2 b
  LPARAM lParam   // depends on hook code9 c  E$ A6 Z- W: u" j9 D' Z
  );3 l* K" f: h8 c2 h
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
6 w, h! S: @. H7 `% f' U static BOOL  IsWndKindOfThis(HWND hWnd);
! S, w$ r0 V! @+ _2 f- z0 g // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
$ I' _1 r2 X) v( t static HMODULE ModuleFromAddress(PVOID pv);4 w: v, k3 c. M
public:
8 L% v2 }  f# t1 c# \ // attributes
// operations- K# ]) H8 X, w
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框  a% |. V. s2 ?8 s+ W
BOOL CreateChildDialog(CHsPMEDialog *pChild);
) s6 s) a9 d& v* o1 m  H};
: O$ h. K: n0 T+ V5 j4 n) q0 b
CHsPMEDialog* g_pHsPMEDlg = NULL;8 i2 L- F4 c: l
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;* ?0 G9 J& [+ [
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
* ]; T: ^, T' C0 R/ d : CDialog(nIDTemplate, pParent)9 B! e. P1 p* X& v; t1 I
{
# J, x3 D8 R& w: | //{{AFX_DATA_INIT(CHsPMEDialog)0 U! K  A- K2 p
  // NOTE: the ClassWizard will add member initialization here
! P: `5 L2 k. L9 U, p  R4 v$ R- S //}}AFX_DATA_INIT
! k( R. x! P! j" O/ @ m_pParent = pParent;2 R8 Y/ _  H  j0 A3 Y$ c6 y
m_nTemplateID = nIDTemplate;
- K; I& M# w2 q! x  | m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表( f9 H# v/ @8 d& Q! \
m_pNext = m_spHead;/ G2 T! [/ `  r' t/ f7 ?
m_spHead = this;
8 |) {. c: d  e4 t m_hkCBT = NULL;
# h& t" v3 D! r! Z( W3 _6 n. w5 E}
CHsPMEDialog::~CHsPMEDialog()) W0 P1 p, Y" C2 o2 v, U9 ^
{
2 @  Z5 B( s- ?: E // 从链表中删除本结点
0 H  X3 t+ P% ?: [, v. K% H CHsPMEDialog *pTemp = m_spHead;7 T# h" a; o" e8 X6 L1 {! K# U; I
if(pTemp == this)8 f+ z; E3 U3 x* p$ a
{) q' H7 o. Z- p1 }" a
  m_spHead = pTemp->m_pNext;" L3 \3 q: ~( ^2 P$ A( G& x+ K
}( l# }* |# H4 g
else
7 I  q; l3 W  k% m {
0 v" P% Z2 x, V6 [$ `  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)& }7 @  _4 {7 P* j
  {6 E. v+ Y3 [5 L5 M
   if(pTemp->m_pNext == this)8 V; E$ P/ M6 D% ?
   {
( @# l9 q" }1 n  m0 J    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
# M: r2 v  M7 n% o4 V    break;$ L. o, r& J# m$ m
   }) a% }$ B5 Q7 z! U# t
  }; Y3 ]- K8 [' }" w
}) b5 W, W, n& `
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
  U, `0 \7 ?) F8 Z  I{/ p0 K  N% p1 N2 |1 m9 I
CDialog::DoDataExchange(pDX);
1 n5 c+ _, G4 _2 w3 @( B6 L //{{AFX_DATA_MAP(CHsPMEDialog)
. n0 v: P7 M( t) P! A DDX_Control(pDX, IDOK, m_btOK);
7 I! s0 `# j6 G, s DDX_Control(pDX, IDCANCEL, m_btCancel);: _5 [* O' o" v  n
DDX_Control(pDX, IDC_BACK, m_btBack);
3 c1 i$ N* P) q //}}AFX_DATA_MAP: F* I0 q. e1 v8 `; w# l! g
}

; u, z6 v) Y+ `. SBEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)2 d* S+ E& V7 I1 ~8 u
//{{AFX_MSG_MAP(CHsPMEDialog)
# d% X6 i4 h/ t6 j ON_BN_CLICKED(IDC_BACK, OnBack)
; G1 o9 @" `/ r4 E' A ON_WM_DESTROY()8 T! h3 T$ J* w; P: Y  i4 ~  J
//}}AFX_MSG_MAP
4 J1 {# ~  @, I' o1 XEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////: t2 m7 g# q: ?  I; X; l. G
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
+ _" W5 l: z+ i: e{
! X) f2 H* k* { m_pParent = pParent;
0 i9 n" N8 ^! @5 y" m8 H6 F return CDialog::Create(m_nTemplateID, pParent);
1 L5 z2 W. ]& c' q/ _, I; {  H}
/ M# d% D7 d. ~; D, ^$ j
BOOL CHsPMEDialog::OnInitDialog()
: U, O* @' L3 V' L; A5 r{
7 W5 I( m6 k( B CDialog::OnInitDialog();
// 设置标题栏图标
9 Q, h0 N; z5 H$ t SetIcon(m_hIcon, TRUE);
/ s' o+ l1 S9 B8 |) ` SetIcon(m_hIcon, FALSE);
( y- g( `; T) z7 K! Z
. ?( Q1 \3 i" E2 r1 @ // UG的对话框的几个标准按钮没有TAPSTOP5 G% B6 c# j+ P( @  U, z* f
CWnd *pWnd = NULL;
! O2 H( S/ b/ V' o2 X$ F% y pWnd = GetDlgItem(IDOK);
2 i. M9 ]( N, {+ |% p* x$ R0 Y* [5 R1 a if(pWnd); ?. Y% y) D/ f( [( C% W
{
' P2 W8 l  m3 n! L- z4 H  pWnd->ModifyStyle(WS_TABSTOP, 0);7 Z, R7 F" H) m  P2 K
}
+ ?# S- F" ?6 g! s) p. F- V* H+ { pWnd = GetDlgItem(IDC_BACK);' [$ u. ~( M; k# @* e3 t2 Z1 w
if(pWnd)
! C6 L. T0 p% _; { {) m9 E" |) E  O8 C1 ], R4 X( ]
  pWnd->ModifyStyle(WS_TABSTOP, 0);
5 b  C. z! C3 Q7 i+ x: H+ t }
9 d  N" W0 a8 e pWnd = GetDlgItem(IDCANCEL);" |. `( u% Z  {; S( d; x
if(pWnd); J8 p9 K5 n8 D- D
{6 B7 [. p* m% X1 u& X
  pWnd->ModifyStyle(WS_TABSTOP, 0);
) N: u1 X- l5 V1 E! ]  Y8 R2 d }" r- a; o8 w2 o
& ~/ L9 H& h9 d, W6 c5 i* q
g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
) C* z( t1 J- z1 T7 d if(m_hkKeyboard == NULL)5 j8 q3 O9 T* Y4 X9 j. p8 `& [" H
{: A+ n5 I: Y9 `7 J  K# f$ I
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());+ {6 {6 Z6 I; G  j! }2 p9 y
}, j  X' D1 o2 K' Z* T$ U2 ?
if(m_hkKeyboard == NULL)) }3 j! ?( k  y" j) I
{
/ U8 z% I% D4 I8 c5 O9 A  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());0 i* O$ l; c5 B
}
if(m_hkCBT == NULL). n+ i8 f  o4 ~4 Q
{
& F. t/ K5 \3 ?  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());0 g0 Y& S8 V8 I
}. g/ z2 l- `& n& W! n: @$ c: O) M
if(m_hkCBT == NULL)/ b6 h: ?6 Y% M
{( v$ s1 J# X7 ?% C6 u6 S
  TRACE("Set CBT Hook Failed: %u/n", GetLastError());
8 Z) K7 B9 Y3 O/ [% P }/ Z0 n! }6 S. e7 l+ F* K8 {3 \
' t4 N% c" j& e
return TRUE;  // return TRUE unless you set the focus to a control" R# z& Z( V9 Q& x! ^/ X
               // EXCEPTION: OCX Property Pages should return FALSE
; N$ z2 L% w1 L' Y}
void CHsPMEDialog::OnOK()  f# J& y' e6 V; d6 @& }  p% B
{+ Q* ~! `/ [9 h; h: e" h
CDialog::OnOK();
4 e. Z# r4 u9 C/ s6 ]9 Q0 Z1 t! v% N3 K if(m_pParent)7 A1 ]0 {. V8 }# y' X( c6 f7 T+ C
{
, K4 D4 b: [& x. n$ q9 R( k* x0 }: k  //m_pParent->DestroyWindow();
0 g9 p  T) \5 W1 e, K! \  //((CDialog*)m_pParent)->EndDialog(IDOK);
1 H4 }! C! j3 ~/ e) o  ((CHsPMEDialog*)m_pParent)->OnOK();
! n+ ]) t# t  U+ G3 `' I" l: w }
/ T$ [5 E) ]8 u2 ^2 k}
void CHsPMEDialog::OnCancel()
2 ~8 X% p1 Z# z3 t. K* a{  o& ?5 ?% J, e9 P! V* {5 ~
CDialog::OnCancel();2 B: F$ ~! r2 T" x
if(m_pParent)& z( J( c) ~* {' v  }' v! B1 a
{
6 N/ Z; x( X# P7 f% {  //m_pParent->DestroyWindow();
* u) r7 _2 i4 V- r9 {6 F  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);. H9 N( P$ L# s) A
  ((CHsPMEDialog*)m_pParent)->OnCancel();
' b, j1 u8 h- e( E% ? }
) y9 g4 a9 S& j2 V7 Q3 h4 t- ]}
void CHsPMEDialog::OnBack()
) e8 o* g0 L9 g, W  \{' F  c# Q% b0 |: K( B+ ^3 ?
if(m_pParent)
. N, k4 C1 t. H) a% _ {9 v- t, L6 ?  `4 y) |& l  |
  m_pParent->ShowWindow(SW_SHOW);& G* J+ H: ]/ q
}
! E  |9 Q5 l# @: v2 W+ L, ^ CDialog::OnCancel();) R: D3 [) A1 }) U
}
& y% Q3 P' `0 X/ Y3 q/ r$ G& Q
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)6 e1 |( J; E2 H0 U" s. h
{. n/ d9 A: E! M1 s! E$ k  ]9 _
BOOL bRet = FALSE;  d* s9 {, ^- S& y
if(pChild->GetSafeHwnd() == NULL), }7 F! b# D) E" |! W
{+ c/ S  _& p9 _7 J: l; a
  bRet = pChild->Create(this);
" R' H4 e* m4 i8 ^ }: L5 H% F* X+ ?' V
bRet &= ShowWindow(SW_HIDE);
. o. S" y' ?, O& j) t' A bRet &= pChild->ShowWindow(SW_SHOW);) `/ F9 r8 T, @9 Y1 x: R) M
return bRet;
  I, T- j: J  W# p}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
5 F& ~; ]0 O0 w& A- s3 X{
" }- |6 q% m+ _/ @$ x% B if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
& K- U+ c% w# Y" p( y: P {5 p6 V% k- ?: O( [2 z* X: c
  //TRACE("Key down/n");' r" F6 r+ c  Z: w3 F, K- H: Y
  CWnd *pTopWnd = CWnd::GetActiveWindow();: a6 G1 R. z* \6 M9 H- p% p$ N
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd)); ^% q7 b% q$ Y& H$ w# c
  {
+ C/ E! D: j7 q2 q4 Z5 q   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息2 C) S: {! L: t. \4 ~1 V; k2 z; _
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)/ V' {8 n+ ?" w, [
   {" B9 u! r; G  M# r% u/ J; `2 C+ U
    // 只截获tab、esc及回车键
* E# j# n; S1 C9 P* |    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);2 x; V7 l% R# ?' H; q5 V1 v% m
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
. u" X1 `7 W! Q2 b9 ?" a   }
% ^* e# d# W$ s) n8 O2 R   switch(wParam) {
4 E' m+ s4 Z& w* R; p$ I- ~   case VK_TAB:9 r$ d3 Z: [8 K! N
    {; W* Q$ O8 U0 m% \$ V, Q
     CWnd *pWnd = pTopWnd->GetFocus();
7 {: P6 i( ?% V% c/ {1 g, m  F' i- c     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
8 n, D/ R7 j+ D  e7 r     if(pNext)
  W8 p3 |% t( R     {
4 D- t0 G) i* q3 F5 |      int nCtrlID = pNext->GetDlgCtrlID();. M4 S; G# ?; U0 }+ Y- j
      //TRACE("CtrlID = %d/n", nCtrlID);
( r. Q; l1 p: X      pWnd = pNext;
) Y2 E( T6 `/ i& L, C5 X7 Q      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
; ^: K1 t6 Q5 q1 w4 Y      {9 @* |; t, \. o% Y
       // 根据UG对话框的属性,这三个按钮是没有焦点的
7 |7 L' G  r! C% x! c       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);0 n" l; W- {/ @1 ^+ B2 K5 Z0 S
       if(!pNext || pNext == pWnd)
& l0 x! [* M$ C+ T3 P       {
) g) `0 M# A  s/ @; d$ n9 I        // 对话框上只有上述三个按钮
- }9 G" @, k# k) i9 i. `3 y        return CallNextHookEx(NULL, code, wParam, lParam);# }+ g3 k1 V4 R3 k& l
       }) K/ r6 w% N1 t
       nCtrlID = pNext->GetDlgCtrlID();# Z' k! F, u# y6 L  Z8 u* k5 H
       //TRACE("CtrlID = %d/n", nCtrlID);8 u( ?# [  A0 v/ |9 g# T
      }
7 k0 o- n& l! T6 K  Y1 n# e6 [      pNext->SetFocus();
- J$ a: H( n* N     }
8 w' R* a' K+ i3 J' b     //return TRUE;
6 f) ?( U. d) s! p    }
2 l  s8 Z  [, H- k    break;
& h  ]$ [1 Q0 j; L& Y6 T: R; j9 ~   case VK_ESCAPE:$ x3 k, ?/ _8 ]! l
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);1 v1 E" J% k8 B( E' B, }6 ?
    //return TRUE;3 {+ J0 Q* y3 q7 r
    break;
# L. Z/ d% R( Z! K! p   case VK_RETURN:; o) F$ ?* R+ x! c0 x
    // UG实际上并不处理回车键
% t. o; _) P. P/ g* {    break;9 s7 J+ Z, Q, E
   default:
- \8 K, {2 m9 z4 }    break;
( R8 R9 |7 }& m1 R9 N- j   }5 ]; y) E5 H7 k
  }
8 W8 f' X0 r4 N4 u; p }
* Y$ m0 D0 n$ c" z, b- {& U1 R% ^) E return CallNextHookEx(NULL, code, wParam, lParam);
/ N! H2 g6 ]; X+ @/ D1 N, c0 K}
void CHsPMEDialog::OnDestroy() $ b4 [/ r7 u. T( H
{7 h  N% a. k. A) j; w' A4 A# J* x
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
6 L5 }3 f8 t" c7 o- x: f if(m_hkKeyboard)8 I. J, W/ j9 U' Z
{# q9 e, e1 k+ V7 t1 T% s) r$ O
  UnhookWindowsHookEx(m_hkKeyboard); + l& g% `- I; \
  m_hkKeyboard = NULL;
# `! _+ P& ?0 Y+ T }
if(m_hkCBT)6 |9 t6 Z6 C- i4 M7 d
{! z5 ~# R  a. @- C# x
  UnhookWindowsHookEx(m_hkCBT); ( O7 r' i7 V& v, j  Q5 C
  m_hkCBT = NULL;
/ W: O8 z# _0 \5 J" D }
% K2 S; l+ Y1 F0 f8 Z+ P% a; U3 S}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
4 n4 p% W* X8 T: l{
/ Y& E. a' X2 C* J6 t. E CHsPMEDialog *pTemp = m_spHead;6 ^( \6 c, @  o
BOOL bFound = FALSE;! r2 _6 Y( Q6 L8 P
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
" p4 b4 `  |1 U$ \7 _ {+ G6 T" K* T: Q& }; S; n
  if(pTemp->m_hWnd == hWnd)
! A* u6 {" W: \0 q, C, y  {
$ e; P" Q8 `, C' _   bFound = TRUE;  `4 ~, k. A" @1 `! @' m4 s* ~; d
   break;& ^! ~/ B3 i% @8 T
  }8 E8 ?3 o  m1 q' i: D6 v5 u8 z
}6 y2 X: {% b  s5 K1 _' n
return bFound;2 V$ m7 A3 L7 m) q. c  S2 f  g
}
// Returns the HMODULE that contains the specified memory address& q" d& Q  C; ~9 V& p
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)   l- M/ g& ?4 f- c! H, Q0 @
{
0 \+ y' F* W# l' m" I . L0 v9 v# Q# j6 c
MEMORY_BASIC_INFORMATION mbi;
& o0 h( d2 ?0 n( t return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
, F- M8 _, H* M( b: V! O  ? (HMODULE) mbi.AllocationBase : NULL);0 f* F6 _+ X/ Z3 j. [# L9 v
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
) r3 y( X9 D( Z# B' B1 {; }{
" |5 F! [# f4 O8 _3 v2 [# { if(nCode == HCBT_CREATEWND)
; U+ w- ]* N( n* [ {* k; w: C- x4 ~1 a/ g8 W) q) {
  //TRACE("A Window is being created/n");5 L: A! g" b0 R( `( t8 [! s
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;
0 l+ W% Y( b; D" z' l  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
4 g2 \+ d# b5 T+ x1 e+ T5 K3 _  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
4 f+ x8 B! C& m+ U) k4 K  {/ X  D4 x8 J. _+ E. X$ ?& q
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应0 K* S5 r1 g# g2 M- u' m
   // 取得窗口处理过程内存地址5 I/ k7 c2 r8 {$ V% t6 W( u% ?
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);. D9 y8 i# B. n
   if(dwUserData)+ p9 T& W. _4 ^+ z* k3 P5 n$ E8 J' @
   {
+ p: N' x9 ?: s) F" q8 O0 U( `: L    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
7 N; k( H, F! z) W+ j2 {0 N1 G$ G. s    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};% l  C" ?" K& [( ^
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);0 L8 @" U+ C! d
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
/ P: y% G! v/ G0 u* W; f  _    TRACE("CreateWindow Frome Module: %s/n", szModulePath);1 ]* p) z8 P4 H% ?, x
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);1 E$ }: x! d8 a3 i* z8 Z$ Y& k
    if(stricmp(szUGPath, szModulePath) == 0)
8 S6 b1 f9 o  z% a5 f; Y    {
) i" F- ]' k0 a6 h; d" B+ Z: r     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
0 |% r/ c" q7 f# I4 J     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
( `% Y# x; x! U  g     {
3 K3 p  {. I8 J7 t! ]' W      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)( M5 \1 U3 P- W5 [7 b9 i5 t; s
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
* @1 z9 r1 q* ^- i5 S; d       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)$ M5 F% m: [9 ~* W) |5 x8 e
      {) {6 j' W- ]5 _: M8 j6 a
       // 窗口非本窗口或其子窗口
) |; x% N$ j/ s- T% o3 B* O       g_pHsPMEDlg->OnCancel();
- P* a0 q+ _5 \+ a' R2 Y! L# T      }: E  Q8 p; l" E9 P+ P
     }7 G$ q: _& o& K! O. p# W' w2 o7 [
    }
3 n3 I9 A: V2 M/ i$ K   }
% j# n9 Y# b7 _2 G  }
# G2 B6 W! b$ v }
  K6 s( D" |/ w/ l4 m return CallNextHookEx(NULL, nCode, wParam, lParam);" V  ^1 ~+ c, y  ?: g* `" s3 \
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
# U8 V! {* S' R/ I{, @6 W6 F% A8 D4 {5 u! a
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来% ]' V- ]4 ~) u" z# H0 k0 I
& r  ?1 e' _% n3 m) E- }
return CDialog::WindowProc(message, wParam, lParam);) f( `' m# \# a0 B9 s
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) ' Z; Y* e" ]7 Z' v7 j. \) S; @6 E
{
. t2 G* w) b% _ 2 q1 N. I: ]* ~/ h' V, L9 p$ ~1 \. W
return CDialog::DefWindowProc(message, wParam, lParam);1 F: ?% r! ?# [% N
}
6 o. ^/ p) C/ b  l, a: m' x0 U. e
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了