PLM之家PLMHome-工业软件与AI结合践行者

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

[复制链接]

2017-8-31 13:24:24 3367 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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
7 S3 n% b  d( ]$ k// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类$ s9 j. ^0 B6 x" u/ B
//    该类来自网络,稍作修改,版权归原作者所有1 W. B8 l; U& K  m' T. p* x4 Q& n( P
//-----------------------------------------------------------------------------& W, f  o7 [3 a  D: Z' F
class CHsPMEButton : public CButton
5 H& F# c: _' c% u; r. |: v, s{
( U. x5 b1 ^. x2 [9 e // Construction
0 }, y% F& w/ r) X' x+ }6 Z% ypublic:
# W% l. Y7 w: {- J+ O% v! k CHsPMEButton();
$ W. m% s; E9 t
8 e. p8 h! i, {# i! M* X' Q // Attributes
' g. N  U. z' ~3 i7 f. F2 Rpublic:
, [" P( j0 F; E, s! K# v+ c- u7 y
0 E7 S2 g  x3 p; k; F7 b% F/ V // Operations. w6 `4 z! v- x9 n8 E: B
public:
  T, u4 P% [$ N$ h4 H& z) I inline void SetNormalTopColor(COLORREF color)
+ o2 L/ _9 y; O5 P' F {
  `5 U7 k5 x6 f; D& ]$ ^3 e! ^, e* [  m_NormalColorTop = color;" C* Y- Z# s4 c
}
- \; T  E) y$ s" [( y5 X inline void SetNormalBottomColor(COLORREF color)9 W, P" v/ [, n$ W" R+ `' ?8 T3 C
{. {$ Q' [+ }7 n4 v! w& a
  m_NormalColorBottom = color;
$ `. L1 [0 @1 m2 X5 f1 x" v }: a( d9 v; n: O( S6 a" U( i
inline void SetActiveTexTColor(COLORREF color)3 P# S" G. f2 _0 m* D
{
) \+ ]' Y) t6 ^0 |' K4 n2 C/ |4 w& y  m_ActiveTextColor = color;
8 q2 M( b! V8 n9 T, ?7 ~* E2 z( V* u }" `( i" U- Y7 o
inline void SetNormalTextColor(COLORREF color)5 _; i; L- ?' a; h) x) k) `- T
{; i- X' C! B- p
  m_NormalTextColor = color;
& D; g8 p6 R! Z5 p  {0 E+ u }
6 G# r$ g) k( S8 J2 t4 y* N  c: P inline void SetSelectTextColor(COLORREF color)
2 m  B: D4 z7 V! s4 P- Q {
- R& B( o1 @6 a3 ~  m_SelectTextColor = color;
; }+ I3 c& d5 S$ i# x7 M }
# O3 A& i; E6 i/ b inline void SetFrameColor(COLORREF color)" V0 L# n# Y. [! F* f# X# ^! Q
{% W, `) l& }& ^) {8 a' H2 D& `
  m_FrameColor = color;
7 g7 u0 ~$ r! n( O$ l& j  ]/ d }
  H2 e) g, v8 X. |& o( N inline void SetActiveColor(COLORREF color)
( _$ b0 j) z+ G! l) u {
1 r% h; G" v8 i. s3 L8 t# U  m_ActiveColor = color;
8 E( T/ G& y: u( b }
  z1 c$ f5 s& I7 r* V // Overrides
8 b6 d7 Z2 x% m: y/ h6 Y2 h // ClassWizard generated virtual function overrides. n- _8 e7 H) S
//{{AFX_VIRTUAL(CHsPMEButton)
2 h) P0 W3 S) Wprotected:% U: G1 W/ k- J5 K3 j* T) @8 H  t
virtual void PreSubclassWindow();
0 \5 [( }$ e7 I //}}AFX_VIRTUAL3 \8 F- l  h, e; h% c; o7 k1 O+ u6 z

7 c( B$ r. C1 e* y1 A" ]- S // Implementation1 O( b+ z0 H( d
public:, j; G( L* M+ s* A) h) e
virtual ~CHsPMEButton();
; K5 v3 d3 J0 c; D4 A' [
5 ?: I5 Q' w+ ] // Generated message map functions% h9 G- W% ?6 ~! ~3 s
protected:0 T7 l6 d' |# m2 E6 l
//{{AFX_MSG(CHsPMEButton)
/ c/ `. H. c% G- M$ ` afx_msg void OnMouseMove(UINT nFlags, CPoint point);0 y2 B. C) ^- G# J. S7 _
//}}AFX_MSG
$ O2 W+ R+ j0 [& @7 M 9 j1 j+ S3 i: ^9 F9 I
void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
1 u6 Y' C: _- L0 m void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);  b0 C% i0 \# k4 y3 S+ G; S) {
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );1 u9 T: T7 H2 e% j6 f: S( [$ u
LONG OnMouseLeave(WPARAM, LPARAM);
+ o  n% ~  p* d0 c# W BOOL m_bIsMouseMove;
6 r6 T. R( ]) p  x9 ~# c, L
  @, u# j5 D* g COLORREF m_FrameColor;3 n  \  T% A4 H3 t* g1 z8 R
COLORREF m_ActiveColor;
- Q; [7 K; m' O
* L- m: D6 x; F9 }+ W COLORREF m_ActiveTextColor;& H) s& z, i; \# ?6 Y2 v
COLORREF m_NormalTextColor;
5 F7 c8 m8 \7 D* @7 A COLORREF m_SelectTextColor;2 w9 a/ }" `' ?* m3 ?

3 X$ u. H. g0 p COLORREF m_FrameHeight;" ~# T0 y# |3 S6 z1 F5 y% _, j5 k9 j
COLORREF m_FrameShadow;
, @; F& F& G8 o6 I5 ~ & h+ j; X" c" p  K% w$ p. q) i  d0 |+ ~
COLORREF m_NormalColorTop;
% e3 Z. K6 ^$ ]6 T5 |, k% o COLORREF m_NormalColorBottom;
- W: x/ T" g+ Q8 ]* Y* r # f  w4 V$ }! b. W
DECLARE_MESSAGE_MAP()
2 e. L2 o: {3 P};
/////////////////////////////////////////////////////////////////////////////9 {% e8 [# v4 c- ~# {, x% L
// CHsPMEButton
CHsPMEButton::CHsPMEButton(), ^; I: T% U  n, Z( [
{* o1 p0 |" |$ Y) E# X
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
2 m& ?& n# q; f7 d m_SelectTextColor = RGB(0, 0, 0);5 K9 I5 }  @: M, Z9 C6 d' @
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);4 k# v3 |- ~6 \0 x' g6 R1 E
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
3 V# X! t+ D3 j5 K: I m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);; a' b' M9 b3 r
m_FrameHeight  = RGB(230, 230, 230);
) |6 A; l3 l# G  A, _ m_FrameShadow  = RGB(128, 128, 128);
& g5 i6 [  e0 R1 r6 R0 H% d}
CHsPMEButton::~CHsPMEButton()* [' Z" ]8 C* G! s
{
6 [# m0 Q0 U& i}
( p5 M8 p- w- j
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)8 p* N1 a* l  D) T+ ~! {' U2 z
//{{AFX_MSG_MAP(CHsPMEButton)
% u! F* }0 ^+ H/ ] ON_WM_MOUSEMOVE()
; A! J$ K$ [# O. N/ [" |% F. r //}}AFX_MSG_MAP1 U, V# R0 h# E# D
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
! {1 D, z: d$ `- y2 DEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
5 B3 n+ |; b; W2 Z4 o4 k! T// CHsPMEButton message handlers
void CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ); a  d0 I: g, P) q' F8 d7 x+ d
{
* u' Y0 U& G$ S6 Z2 u //*
4 K9 ?" r9 X- z. v) ? CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
& ?7 ~2 w8 A& W) o) Z1 A DWORD nState  = lpDrawItemStruct->itemState;
! R' ]2 b5 U# i/ E  J9 u' o DWORD nAction = lpDrawItemStruct->itemAction; 2 H7 c$ m- ~7 @% J
CRect rc   = lpDrawItemStruct->rcItem;; G$ h8 d5 I* J- w/ D2 Y- f7 p* u2 R
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);* T0 p' i6 k) W" m8 a4 D" a
CString strText;6 T0 d' D3 n' ^& {: ~3 [
GetWindowText(strText);
if( nState & ODS_SELECTED )
0 D% N8 c8 _" H {
, z& Y$ U* b+ z  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);& H* _* ]" Z9 e- U/ E, _1 O: ]
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
" X4 q  M! C+ T7 r  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
: L8 C8 d" V) { }
: W+ L  k9 s! H else //Normal
! d: \; D! E" k4 E  C8 u8 b( b {+ H+ \4 r, r; p4 f' `
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
3 v4 y  T% `2 O! T& @# ]  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);  U/ F, I) G9 k( K7 q. }
}
if( m_bIsMouseMove )9 D! B, R/ m6 K
{+ k' C1 t5 ]* Q. [! r4 l0 }
  CRect rc2(rc);
8 ^, q" s" U4 c  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
% ^! c2 x2 h/ A. w   m_ActiveColor, rc, rc, pDC);! q" A1 ~' y( v4 U; s+ Y: F( ]' P
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;8 _0 g8 z9 \, w* a( Y
  NullBrush.CreateStockObject(NULL_BRUSH);; c" B7 o8 B7 Q
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);& d- l7 Q4 f. a# r% K0 r8 Q
  2 I2 Q4 ^8 w# m2 h; G& n/ X9 ?! X
  CPen Pen;
& B/ O" X! y0 }. n2 F/ r, Y  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);  Z, o* o7 o# u' _3 g6 T
  CPen* pOldPen = pDC->SelectObject(&Pen);" A& f+ {1 g7 x  I
  rc.InflateRect(1,1,1,1);
* G7 E0 W2 l3 W- @: T4 A. U  pDC->RoundRect(rc, CPoint(3, 3));
/ Z; |$ l4 W1 \0 L  //rc.DeflateRect(1, 1, 1, 1); 2 H; P; e: L; v2 B7 y4 `
  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);3 X! L3 u0 N0 R7 O8 V, h
  9 x$ F0 @5 ?  H2 Y3 ?
  pDC->SelectObject(pOldPen);6 y. [1 f6 ^4 X6 N" \
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);" G1 ?5 P* h! _6 W
}
; Z2 ]8 R4 Q. H4 I1 x 3 f, @( \" ?: ^2 S5 k6 g) T$ }
pDC->DrawText(strText, strText.GetLength(),
7 E/ `! f) u' C) s  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);5 o0 R4 n5 q2 w, ~1 c$ E
//*///
% G! ~( f" v2 S9 Z) x7 n}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
* U# e4 ?7 l0 c/ U, H+ I* |{
3 p" f  s9 u" H* X' {# d1 b // TODO: Add your message handler code here and/or call default
" L  t2 H% i/ B! ^2 [! B% b' p if( m_bIsMouseMove == 0 )4 v, _, t  i8 o7 ^& c$ f9 A, b0 k
{- ?* R8 o* p! D! D+ F
  m_bIsMouseMove = 1;$ ^8 y& k2 u5 N7 `* k6 y8 z$ ^
  Invalidate();- i% s) Q/ C  Y6 N( L  o" s" N$ Y
  * ?' `( ]2 ~+ T' [0 I, G
  TRACKMOUSEEVENT trackmouseevent;% H: M, M; g* y" K
  trackmouseevent.cbSize = sizeof(trackmouseevent);
2 k8 I5 z4 b  D  trackmouseevent.dwFlags = TME_LEAVE;
  H8 L8 ~$ o! \! u/ d# L( c  trackmouseevent.hwndTrack = GetSafeHwnd();' K( w; {2 I0 h# C# p9 w
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;* ?, g8 i, S, {! k3 V
  _TrackMouseEvent(&trackmouseevent);
! Z* G3 M  J" R2 K* u }
1 l+ g4 [2 r: s( d3 U/ U) n& x
+ I" e- n% i; x) M! b CButton::OnMouseMove(nFlags, point);
% f7 P, t! |: e: b}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)9 ?2 L# k, t6 X/ A
{
/ s' Z3 r% f: ?& x m_bIsMouseMove = 0;
! k& w3 V# {2 a: p! W, W Invalidate();
return 0;
3 ]6 |* o5 x  L$ ~6 [& w! }5 G}
void CHsPMEButton::PreSubclassWindow()
' h0 U5 H# Y7 s9 j{
( H# Y+ G* D$ n // TODO: Add your specialized code here and/or call the base class8 _6 g7 J- o* d/ f4 v0 L' ~
UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
+ h. E$ |* r, {" [2 B SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();2 u+ J2 a- T8 \" l
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)8 x; s; [% h4 ^0 x
{0 [' Q/ s9 N1 @7 X  Y9 i  Z
CPen Pen;( g8 i, o0 [/ M8 s4 A
CPen* pOldPen = pDC->SelectObject(&Pen);6 b; m# G4 @3 z4 Z/ ?; Z" B
( k6 B$ W0 d: ~: R0 o% U
int R, G, B;3 h1 t' y9 Q; I( r2 b* F$ P' Y
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
9 u" p% `" n9 L) n G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();8 X/ \( n1 ^  ^  x) H1 _2 F" Y
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();- f( d7 s/ R+ Q' G
3 F  f) g; p; b) e4 H
//R = R>0 ? R : -R;
7 \  `% j) H* t: m //G = G>0 ? G : -G;
5 ^: u/ z3 ~! w6 W- \9 G" w //B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
9 P, A$ |( V, u# J COLORREF ColMax = Top > Bottom ? Top : Bottom;2 c) X- O7 y/ p+ u6 F: p7 j1 G- Y
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
* Q" O7 S; [. @ {5 t, [7 }, ^. n& [% O% A
  ColR -= R;
) |5 e' ^, I- ]* P5 s6 y' U  ColG -= G;2 p( ]  H+ j* p: y1 o4 a
  ColB -= B;
  /*
- l. b# y  i3 i/ d3 ^  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||8 N. I0 ^$ ]$ M7 U# L
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||( L" a. g( x& l1 r$ j6 m, u
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )1 |5 x+ c8 a. r* D3 z+ q6 k
  {
2 M7 k; R3 M& t$ `   R = G = B = 0;5 U& q$ `$ t- J
  }///*/
0 M. c- f2 E4 n. {" `9 \; b1 X
  Pen.DeleteObject();/ K0 R8 z* g% @0 @, z- D+ N
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));) S( m- C! h! N4 a3 ]4 X( g! m
   
% o1 s8 F: C' R; ?/ j  pDC->SelectObject(&Pen);  p! f( l! V1 X. j
  ; z5 K# P7 U4 j' ~- C
  pDC->MoveTo(rc.left, rc.top+i);
: |( L) N, d1 u  Q" E  pDC->LineTo(rc.right, rc.top+i);
( C  o3 x5 }, @ }
pDC->SelectObject(pOldPen);0 a: w( `4 v7 P' d' U' o8 d
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
0 w; v* x* }/ i{
' G* u, q. R# \3 k7 x CBrush NullBrush;
, [) e+ b& k: [ NullBrush.CreateStockObject(NULL_BRUSH);
( @$ K2 U- @2 z7 Y CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
9 P5 v( r" ?# E* T7 ~# [. V! n+ i Pen.CreatePen(PS_SOLID, 1, FrameColor);
, _+ E; R- L4 _# r% e  j" K CPen* pOldPen = pDC->SelectObject(&Pen);
# j5 h: o- ?) E# H% }: j& G
9 W1 S' I0 h. X; G. t pDC->RoundRect(rc, CPoint(3, 3));
! u' d4 [) j  B! [* Y rc.DeflateRect(1, 1, 1, 1);
; x' P- N2 x$ Z5 F* n pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
0 V* O6 b! a0 W. p pDC->SelectObject(pOldBrush);
& J! `6 {  {6 F8 H+ w; M( ~}

6 O, i1 ^; o% x* n+ F5 a: x# d/////////////////////////////////////////////////////////////////////////////
" M# g& e" ~% }8 y3 y+ p/ ?// CHsPMEDialog dialog" Y2 h/ D2 w  i( o6 X* }! V
//-----------------------------------------------------------------------------
6 v" w9 k" s/ h9 O' ~6 `" ]6 {' @// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:% T& u$ p1 `2 n1 ?8 M% e( ]0 C
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级; p6 U: o! D4 \- Y3 d3 k
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
% q9 z) _' x6 ^//   指针将其显示出来,然后隐藏或销毁自身
9 h+ r, s3 L1 V9 l& T. U8 M0 t# G//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
  h. n- u# ]$ j1 I  b//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
# B5 a8 ~4 u% k. a' z//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
3 n# W5 o9 L5 x/ P8 Y//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。& q' U" V& t4 s/ f
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
. K$ c: f1 ~# d  @- h//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框9 w" ~$ o* W" A6 n! w9 N
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。
0 C( r3 y* H& B( w//-----------------------------------------------------------------------------
7 W2 E; o- K$ l( P2 S5 L// 注意:3 ^4 z. t& h$ n* h' A
// 1、在构造对话框时必须给出其父窗口指针; `( ^- i( O! E2 x  E: G
// 2、在初始化基类时必须指定对话框资源模板ID
" Y$ w) y& {8 h' v, a9 i// 3、对话框资源中必须提供ID为IDC_BACK的按钮
3 u$ I1 y3 ?4 H// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
/ o7 m3 t  O2 C6 B% U0 q//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog- E7 K. @5 P$ H: j* `
{1 q0 S3 X5 T7 }" G& d" |
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
- r, d, K) e+ [' Z9 ^' ]// Construction. ?6 _' [6 n$ m( u4 R4 A( H
public:
/ }* H, s0 Z; X, r% l CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
  J: ~0 p4 b! S% c" Q ~CHsPMEDialog();& b( i0 W0 w1 r1 X7 f; K/ B' |
BOOL Create(CWnd *pParent = NULL);
  O8 H: C8 _: O% n/ f/ a
# u& [8 g' D+ I9 h/ F/ j/ E// Dialog Data* `* R2 J; i1 D) x. p% B) _( E3 i
//{{AFX_DATA(CHsPMEDialog)! O- I" [1 a7 u: f% m+ |9 ~( z% T3 `1 E
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };
# z1 Q8 R4 s, t/ y" C2 d% @/ v  // NOTE: the ClassWizard will add data members here
/ s( l1 \0 v, M  O& V //}}AFX_DATA
6 \! U. b& b+ b! }: w, D0 {# f: U
// Overrides
3 @( f0 _+ g2 p0 ~0 e  h1 O4 f // ClassWizard generated virtual function overrides
. R7 o0 E- V% a! a5 H  D //{{AFX_VIRTUAL(CHsPMEDialog)
+ }: d6 a; `" ~ protected:2 i: e( E( P- K
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support% L9 f3 w) m" ?; o
virtual void OnOK();
* Y0 U0 e. E2 `  }( k* H virtual void OnCancel();* F8 B* v; |3 w$ n# p
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);/ ^$ ~0 F" f7 y; c! R3 P
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
$ F0 q1 ?' m: {2 s" J& _ //}}AFX_VIRTUAL
// Implementation
" N* u! @% `% l( Y5 A, Sprotected:
// Generated message map functions
; ^! f1 x/ u* W //{{AFX_MSG(CHsPMEDialog)
6 p8 e& i3 |5 S9 F" s+ K7 E& }1 ` afx_msg void OnBack();
6 I6 d, h1 J1 s0 \9 z& D3 ^' X virtual BOOL OnInitDialog();
$ t$ ?! G3 `  U1 ^" ~4 G6 j afx_msg void OnDestroy();
% ?) Z+ ?$ }( G) I //}}AFX_MSG
. O/ h' G+ B) \# P; _3 ~/ M DECLARE_MESSAGE_MAP()
protected:
* Y, e3 i6 _0 P+ ~  _0 x0 g' m // attributes7 G# p: u3 |$ A* G! U, S
CWnd   *m_pParent;     // 父窗口指针
# P; d( u' L, j2 ^% v HICON   m_hIcon;     // 图标0 w! k3 {8 W/ J
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;: R5 ]8 P4 m7 N8 l2 f; Z
CHsPMEButton m_btCancel;5 ?: V; }. h# ?; i3 V
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄1 U% Y& a9 M9 b, f  ~
HHOOK   m_hkCBT;     // CBT钩子句柄% c. f. Z5 m+ R- ~( H3 M* J

( d) @9 f; U" g! U6 g# R //-------------------------------------------------------------------------
* y0 W# U$ g/ D" m) v/ h9 U. s // 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
  a( \6 |" _! x; x // 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
' r8 Q* ~! |* L4 M // 链表的头及下一个结点的指针! b9 S1 Y# ~& d+ {" ?
static CHsPMEDialog* m_spHead;
' T: u/ }' l3 v, z4 Z( J: R CHsPMEDialog *m_pNext;
// operations& e5 k+ Q2 w& }! f! V! Q
// 键盘钩子消息的处理函数
5 e% I: b) a8 E8 L static LRESULT CALLBACK KeyboardProc(* _8 u! a" G2 q  b7 d) B7 E+ M
  int code,       // hook code  j, W2 b  `; Z' }" U; F
  WPARAM wParam,  // virtual-key code
. c4 {4 }7 [; y2 @* q  LPARAM lParam   // keystroke-message information
  Y7 o/ G  B  |7 F1 q  );
9 g9 {5 M" E( t // CBT钩子消息处理函数7 G% p( R* E& L9 J3 G
static LRESULT CALLBACK CBTProc(
6 I; W1 L8 O6 O1 x2 c4 W  int nCode,      // hook code0 u" Q9 ~( Y" M5 a  c/ E
  WPARAM wParam,  // depends on hook code) d6 `9 i3 l& e" ?  S6 S. e- X
  LPARAM lParam   // depends on hook code- ~; q7 B$ k6 S, s
  );& Z, y4 d8 @0 R7 g: N
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
+ K2 u/ ~& I; \( e5 i2 i static BOOL  IsWndKindOfThis(HWND hWnd);
7 h, ?3 e% c+ r7 {- ? // 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
: [" [4 Z/ F4 \5 N- i static HMODULE ModuleFromAddress(PVOID pv);) }8 r9 _3 X; F2 E
public:
8 N5 o2 ?- l0 t3 ` // attributes
// operations
  Z/ ~7 K) i/ ~- J5 p // 用于模仿UG的创建一个子对话框,同时隐藏父对话框; q) W! u+ x1 z7 e
BOOL CreateChildDialog(CHsPMEDialog *pChild);9 e2 D& |9 C8 e) V( u
};

+ l/ N3 o# H: l8 XCHsPMEDialog* g_pHsPMEDlg = NULL;
. j: [3 b. P+ D: i! QCHsPMEDialog* CHsPMEDialog::m_spHead = NULL;1 E, T7 o. M- E
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
, O: t5 k' p6 X* R1 V- h- k : CDialog(nIDTemplate, pParent)
. F9 @1 c% I2 W% Y{, }/ s. f7 |+ ]
//{{AFX_DATA_INIT(CHsPMEDialog)
9 I% u0 Y, T* e$ t. Y7 E" {  // NOTE: the ClassWizard will add member initialization here
! I8 |4 @6 k  q6 [ //}}AFX_DATA_INIT
* L" E% i: |5 ~" |- _9 R; j m_pParent = pParent;
+ B0 E# ]4 p! a1 J# M+ R0 J m_nTemplateID = nIDTemplate;
+ O- F/ a$ K1 J4 |1 _2 j/ u" ` m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表# T/ N. b7 B& D& ]$ h
m_pNext = m_spHead;
; F( I  O' S) L m_spHead = this;
1 Z$ A5 B. |3 b+ R m_hkCBT = NULL;# T* E; f, D. O* c% v3 ?4 G
}
CHsPMEDialog::~CHsPMEDialog()
# K# K; U. p1 Q{
6 j2 ~# b* p/ S+ @ // 从链表中删除本结点
8 d1 o# o3 H% i. s: O) B, o* p CHsPMEDialog *pTemp = m_spHead;
- N; P- _# M  k if(pTemp == this)/ [1 X5 A: a6 }- I4 W( s% m6 E# z1 K
{- k; y; L" V- e" F: c
  m_spHead = pTemp->m_pNext;9 L2 |/ r' z/ b
}
# U: p4 @) v% `' q# b, M  Z else
( G' @+ o" j8 ` {
1 F/ p) k& Q9 q; t; }  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)& l. N( Q3 k* e1 e8 T7 h# {8 i
  {
1 y5 u3 O# ^  Q* w) v- A+ P8 b  F   if(pTemp->m_pNext == this)8 h& q% x& [- q; N0 O8 q5 Z+ b8 Q. Y
   {
; y2 a7 e% F! `2 D  `    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
  H. o! a, r& a+ h; n: a( V    break;" l* z' ?3 ~" E. O. w
   }$ j3 q3 n; _( f, h0 ?
  }: T  y. ^  Z  B$ k* B' f9 J
}
. h' F- b5 J; S  |; ?}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
* b3 I% S! [( G4 W4 y$ m{
4 L7 N" a9 y( |: x5 R4 J CDialog::DoDataExchange(pDX);
7 A7 t# N/ _- {" K: |7 p //{{AFX_DATA_MAP(CHsPMEDialog)1 G' J5 H  q4 o8 [) F
DDX_Control(pDX, IDOK, m_btOK);& `. j" R% i4 l! q3 G: ?$ U0 F
DDX_Control(pDX, IDCANCEL, m_btCancel);: h0 i7 a8 z+ [4 Q4 U( c
DDX_Control(pDX, IDC_BACK, m_btBack);
7 N9 q8 c) j9 h- r. J+ C$ O //}}AFX_DATA_MAP
) }3 P% t- T4 ?" X}
! F  \. d/ g2 s5 l. A8 H" H
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)/ v$ |2 K" @0 s  }1 }, g4 U
//{{AFX_MSG_MAP(CHsPMEDialog)  e# k9 I; m8 H( R2 W, m
ON_BN_CLICKED(IDC_BACK, OnBack)
9 Y- {5 W. B* G; h ON_WM_DESTROY()
1 k$ t9 ?  u7 ^% S. K //}}AFX_MSG_MAP
' \! t8 Y1 v7 z: y3 VEND_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////0 Z$ q- S8 B& ]: Y  m! k" ~
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
  q1 C: L" x( @& l2 s{
9 j  e# W% S7 t* Q5 W2 f m_pParent = pParent;+ ~" f5 T* `& @7 M
return CDialog::Create(m_nTemplateID, pParent);; L+ z' b. O# `
}

& a- T" f: C" _1 v' O6 y' sBOOL CHsPMEDialog::OnInitDialog()
% Y/ F0 x  e4 H; K6 r{
  E6 B3 R1 P. ` CDialog::OnInitDialog();
// 设置标题栏图标
9 E  j3 \. q0 G  F4 B2 \ SetIcon(m_hIcon, TRUE);
; t) o" z. `+ ~# Y# {& v2 { SetIcon(m_hIcon, FALSE);/ Q! O2 U* K2 U

9 d( ]) F. N) @ // UG的对话框的几个标准按钮没有TAPSTOP6 |( M  J2 ?! {, [0 @& H
CWnd *pWnd = NULL;
- g4 y: k+ D) c. |+ K pWnd = GetDlgItem(IDOK);
. M# h+ N) y) }7 M, S+ i if(pWnd)
+ Q# W2 `' Y# D- |, b; x, ^ {
/ d" |# S+ j/ `5 f  pWnd->ModifyStyle(WS_TABSTOP, 0);& M5 U- W  n# V; z0 R
}+ B& _* ^) ^# Y/ [3 @( G
pWnd = GetDlgItem(IDC_BACK);' y4 n7 R# ]9 ^& j8 Z3 S" o; r
if(pWnd)6 h# O8 k& H. _2 |8 s9 X/ J
{
- v8 K. T" y4 Y2 p3 \- v  pWnd->ModifyStyle(WS_TABSTOP, 0);: d9 A% N3 e' ~
}
" W; R! r! N$ m8 L* e" R* t2 m- a pWnd = GetDlgItem(IDCANCEL);
: m" H* ~) a( C! w0 [5 V if(pWnd)* ~. w) n5 }) L" a5 m: f
{
/ L3 e% B; N, j7 [7 _( _  pWnd->ModifyStyle(WS_TABSTOP, 0);: ]  Q2 f0 n# T4 U5 d  Z3 l0 E
}
3 ~( n6 Q2 a8 x$ w* @0 W. \
. s  ?& W: C% {+ g# h: s g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
, i( e8 D7 A, m$ B# I if(m_hkKeyboard == NULL)
" s5 [, m) F: r% r {
# q: s4 H8 A( w4 z8 ^" e  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
# W0 t4 i' _, c# o! [0 k }- Z3 ?4 b& l) X& W, ~+ C) z
if(m_hkKeyboard == NULL)
& D1 @/ i& D5 G3 M4 | {9 f' R5 x( b: o
  TRACE("Set Keyboard Hook failed: %d/n", GetLastError());
5 ^4 V9 Q5 o8 d  V }
if(m_hkCBT == NULL)& X2 f" n/ C2 x) T/ q9 E
{
' E4 g7 o! M  S8 H2 N. @  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());# l9 ~" `% h3 `7 P" S' f8 W
}
8 N" k& W1 ?, u: Y if(m_hkCBT == NULL)1 {; w  m, K! ~
{
  i# d1 R- i+ A8 Q" F3 E  TRACE("Set CBT Hook Failed: %u/n", GetLastError());6 l; I5 F+ A. O
}
# f( ^# s* Y2 y& U$ P* B2 H 3 l8 q5 f0 Q1 T
return TRUE;  // return TRUE unless you set the focus to a control
& z" L: z; ?3 }7 y% D               // EXCEPTION: OCX Property Pages should return FALSE/ h- f0 ^2 H0 |5 c# B7 Z: [- D- `
}
void CHsPMEDialog::OnOK(). I' V1 c8 d, R
{) k+ H/ R9 t& \# p. O
CDialog::OnOK();
4 ~1 |. y9 P9 a" P1 F, d# G if(m_pParent)2 Y+ I2 z4 q" {1 n$ G5 v" }) L
{6 s+ [  U. D) `3 U, Z8 r6 L- r8 i
  //m_pParent->DestroyWindow();: S, e- y% N) r* i
  //((CDialog*)m_pParent)->EndDialog(IDOK);
' A# r! \8 Y9 w7 M  l  ((CHsPMEDialog*)m_pParent)->OnOK();; m% m: O7 _  j
}4 _: t& O+ x9 f; N/ n: c' r& q
}
void CHsPMEDialog::OnCancel()& }8 E- [! F7 y" C& `0 U
{
0 X% N: ]3 s% J8 W. E CDialog::OnCancel();$ ^# z/ c3 @) K9 q! A7 [1 l9 z) q2 l6 f
if(m_pParent). F* _2 L) Q, V8 i+ F
{
/ H3 V' z. R$ }1 f$ v# H  //m_pParent->DestroyWindow();
* X8 v& {9 d0 \) ^) @6 z  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
3 i! ?5 L; ^0 }$ ?  ((CHsPMEDialog*)m_pParent)->OnCancel();
3 h# b$ R8 f: C- O" O( w% W }
; S% |/ e1 T0 i; k7 n}
void CHsPMEDialog::OnBack(), X4 t' Z  M2 {7 {0 u$ Z
{
! X$ R0 _& d) l: z! t if(m_pParent)! E; |' Z5 j" G$ \, ]. |0 t3 D; k& M2 g
{3 k" a3 D( l3 [" i  e. l* k
  m_pParent->ShowWindow(SW_SHOW);
; q8 p% Z; I! [* p1 c: s6 x }
- G8 j1 Q4 P, f CDialog::OnCancel();$ D# Z  ?. G! u8 F+ X
}

3 K( Q- v. ]1 C1 s' G5 FBOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)5 S7 |1 J3 c% C7 {; p- O, n
{
8 N0 i0 @) Z3 Q# R8 A7 ` BOOL bRet = FALSE;
% K7 d' L: q8 z2 l if(pChild->GetSafeHwnd() == NULL)
1 C! |* o/ k" a' m4 ~ {5 j, E/ v+ J  U! U- m; L2 {; {
  bRet = pChild->Create(this);
8 Q$ K4 @& A& R& u, d5 p: n }$ {( A$ T, i& w# |0 c- o
bRet &= ShowWindow(SW_HIDE);
1 f) D/ ~6 t9 \4 b( V8 p bRet &= pChild->ShowWindow(SW_SHOW);$ k( ]5 @# c! U/ s1 G$ w4 O
return bRet;. g: B: Y- d0 L& z) e' n
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)' a+ r  X4 R; K; a$ b
{
, Y. p4 x5 G5 K% ]8 k& X( \) U if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
4 W$ R7 m" x- h+ k" B% [* y {! v: g' v( c, K* o8 S. v
  //TRACE("Key down/n");
2 d, N1 F! x: E9 M7 }1 H, @  CWnd *pTopWnd = CWnd::GetActiveWindow();
) i! J2 b4 O2 q# z* r0 ^  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
' O' z' A" K6 }! \& v1 i  {1 S& ?( ]7 T% o4 |
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
( X9 W+ x  \* {9 e/ j" [   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)
$ L% a' S1 _' W. [! d* l   {2 N/ D8 J2 M: e9 x0 }* O' U& v
    // 只截获tab、esc及回车键" j5 x  n6 t+ n0 s* q7 @1 n- b0 q$ X
    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);/ k" |$ r2 j9 g7 _8 T, w8 `
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);7 m& o8 V8 m: A, N4 V
   }; a6 ~3 x% [  g) [# y
   switch(wParam) {) H" x! Z/ i( G+ Y+ e
   case VK_TAB:5 g2 R1 T2 e& ?( z; P8 R) {
    {
/ A- h1 z8 r- _  D+ ^1 t     CWnd *pWnd = pTopWnd->GetFocus();2 m; P% j. s, A* E) N7 L# F
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
: ~( C/ i8 M  B2 `     if(pNext)
/ p3 l4 e3 j5 T! |1 e$ q     {$ t( |' s: H- t# K
      int nCtrlID = pNext->GetDlgCtrlID();8 N% j9 f1 n: f& G& \) k  ~" M
      //TRACE("CtrlID = %d/n", nCtrlID);* \/ \! _& p6 w. O* b% ]  d( O
      pWnd = pNext;( [" I: f1 R2 S# N" k
      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
( N% j% x: ^2 ?3 t7 P. k      {% c. a: H3 B8 r: ]( r* N
       // 根据UG对话框的属性,这三个按钮是没有焦点的
9 e' o/ k: G+ J! h+ W       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);( g. V  l) M/ G9 O9 o1 d: R
       if(!pNext || pNext == pWnd)
& c. V8 W7 G9 \+ ~' R. U       {
3 ~) ^! ~7 h: E" @' i' c        // 对话框上只有上述三个按钮  c1 z! T' Z& f
        return CallNextHookEx(NULL, code, wParam, lParam);; X) r/ [$ T' G1 z2 S
       }
5 ~0 Q/ B8 z' C, Y& \       nCtrlID = pNext->GetDlgCtrlID();
3 h2 m! I+ r+ K. f       //TRACE("CtrlID = %d/n", nCtrlID);3 v; Q# Q! c' V! I) g, t8 x4 g- C! X
      }
6 y; p( ]4 j" E      pNext->SetFocus();/ t1 k- O" {7 ]  p; M
     }
( ]4 h- Z  b+ l9 b( M: n: j     //return TRUE;1 ]/ e' Z4 @' y% Q  v; A% Q
    }
- Q2 C& z" \3 q$ a$ @    break;9 C* e& ^: `5 o" U7 s2 l
   case VK_ESCAPE:! T8 l+ ]" Z# l6 V' I
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);/ D- s4 I: I) Y$ i+ C
    //return TRUE;6 Y' Z2 \, p+ `* X: R# f5 m) y. S
    break;
; C" F7 u* @- v' d% }' F! M   case VK_RETURN:
$ s6 H: P& Q& j6 `3 V; F    // UG实际上并不处理回车键. a' i; n3 H/ U4 m( n$ ^
    break;2 N! h. Z7 `, `9 r) f; b
   default:. m9 F' g# h# N8 K  k; [; M' c
    break;
# c6 n$ i8 S) R! B% k) k   }+ A' [' N# _: c
  }
  ?% h! @# b1 [  d, Z# x& X, f }
: {, E4 ~0 C3 ^$ z& T return CallNextHookEx(NULL, code, wParam, lParam);# t1 U0 h- G  H- t. J) }0 e6 U8 r
}
void CHsPMEDialog::OnDestroy()
/ H; F' U7 W. A  D6 h1 J* S' U0 X{/ u9 A% O) r" ]" o, Z- K1 j
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
+ j6 W4 b0 a3 Q. T. E if(m_hkKeyboard)5 H; i  r0 Z$ v" r* k( Q+ T
{
0 e7 f, i% E3 ]  UnhookWindowsHookEx(m_hkKeyboard); . P. i8 P' m9 w: T9 Y" j7 z; p
  m_hkKeyboard = NULL;
% A/ b* b  M3 I+ Z6 {+ _ }
if(m_hkCBT)! Z0 b0 n8 e5 x! A% A, H
{
& N: [$ ~6 [0 z- S  {  UnhookWindowsHookEx(m_hkCBT);
9 u, F9 L! N4 M3 y2 j% A; o- W  m_hkCBT = NULL;
1 |$ b( H' H5 h- t9 i3 i9 I }
4 R' N, [& d) {}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)4 u0 Y  C2 C- h1 h; ~" G
{8 P+ T7 [$ A9 G
CHsPMEDialog *pTemp = m_spHead;
, }  ^2 e* h9 ^9 U  s BOOL bFound = FALSE;
1 \6 ^4 F2 o& _/ W for(; pTemp != NULL; pTemp = pTemp->m_pNext)4 Q, X1 J  y; A9 V
{7 i  |7 c0 m+ n8 r4 ~5 ]5 O6 w
  if(pTemp->m_hWnd == hWnd): k. j: u: e: G4 \. s) z' b
  {: R3 n, T8 K7 ^/ |; f# h
   bFound = TRUE;
) b; Y3 D* V5 v/ S2 ?6 ^   break;
; l5 l4 T: f$ U( s4 K- |$ r% G  }
3 m- Z! O' e( g5 z1 F }
7 O9 O+ D9 ?: l return bFound;+ x8 r+ s* k4 k$ }6 m
}
// Returns the HMODULE that contains the specified memory address+ T. c8 q2 K5 I
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
0 w3 V7 V4 G! {; @0 E1 s" `{
* z1 d6 \. f# _% ?6 ]2 J . h$ v' S# A7 h) {1 l
MEMORY_BASIC_INFORMATION mbi;
6 C! _  A& e6 H6 g& Z6 }9 j2 n% } return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
  @- ]& @3 ?& W1 K7 K3 n  ? (HMODULE) mbi.AllocationBase : NULL);) A7 i7 T8 y* G* E: s& [
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)5 W  p6 c0 W3 S; z5 b1 z; [0 Q, ?
{. `3 y; P7 c# q
if(nCode == HCBT_CREATEWND)
( ?2 k  K' f3 G8 K5 O6 g+ K {
7 W2 k6 Y) c; Z! {' j  //TRACE("A Window is being created/n");' K4 F  {) m$ ~" R2 q5 m
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;
3 u) r5 D( |' t  //TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
5 r+ ]. j7 R, |9 h+ b7 P  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
6 n% k. g/ ]1 ~: O3 p( g: S  {
2 [! N9 J/ H' X. ?* f2 {3 y   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
, L  f$ h( _+ g( F+ k5 J   // 取得窗口处理过程内存地址
5 J1 p( O+ ^& W0 u0 z7 S) y9 Z6 A( _, o* i   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);2 J; A# C- X" o' Z
   if(dwUserData)9 {& o. K5 Z, e, U  u! L. w
   {3 g# ?  f+ G' Q; B) D' C* y( ?3 U
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
6 A0 ^  o: \! z) J8 u7 S9 s" Z    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};, @) ^$ K0 S3 m' u8 W8 F
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
# b4 z, F) P/ {/ S    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);1 n+ F$ q! h. N- p! q6 C# F
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
" t  M0 ]4 T& M/ ~/ T" a- B    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);! t4 L6 ^, ]. D
    if(stricmp(szUGPath, szModulePath) == 0)
. u$ k! J- u; q5 k1 o5 o    {. l/ t8 ]9 A1 a. h
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
" b" Y/ Z7 E& n+ w/ J* s! H+ D     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
/ H# V4 X7 Q: M. c0 |' e2 P     {" s$ ^, ]6 ?3 ~" K
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
; l4 w" B9 H, O      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
3 ~" e. K/ a- U& `       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)7 d3 Z8 D* I( q9 _: h
      {4 W  ~. m- E& M0 S. n% F
       // 窗口非本窗口或其子窗口
$ a7 X8 o2 _8 `8 z       g_pHsPMEDlg->OnCancel();
; @! t  c7 k* V$ Z* Q5 ^      }# q  Y8 ?/ I% {9 J6 T  F
     }
9 E$ Q0 S- S& y/ B    }
, g, K) |1 `5 }, v; m& `   }
- O9 V% C$ M4 B8 z, h( k  }; g3 y6 A" T  T$ B* \( E# s
}, _" T9 W7 }, f- S# V( Z1 J, q$ I$ n
return CallNextHookEx(NULL, nCode, wParam, lParam);
% t  O; R2 s7 _. f}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 6 K! v# B$ t3 V) Q1 i# r
{
; F1 w4 |- s6 g" X // 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来+ T, R6 L5 W+ N5 g1 x8 S" H

5 A: q3 _: R. h4 [4 r* c return CDialog::WindowProc(message, wParam, lParam);
* g8 D  m6 ^( F, g+ J7 ?, J}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) ' y3 x% q) M2 M# Z# R
{
. z/ J; V5 x/ }; u 0 z. n  P( q3 A3 {% l: t8 H2 B
return CDialog::DefWindowProc(message, wParam, lParam);0 e0 R0 K, ^6 c  i  E9 f- O1 N' e
}

4 d: N& G9 @% D% D9 m
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了