admin 发表于 2017-8-31 13:24:24

用MFC对话框模拟UG对话框

做过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都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。//-----------------------------------------------------------------------------
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
//    该类来自网络,稍作修改,版权归原作者所有
//-----------------------------------------------------------------------------
class CHsPMEButton : public CButton
{
// Construction
public:
CHsPMEButton();

// Attributes
public:

// Operations
public:
inline void SetNormalTopColor(COLORREF color)
{
m_NormalColorTop = color;
}
inline void SetNormalBottomColor(COLORREF color)
{
m_NormalColorBottom = color;
}
inline void SetActiveTextColor(COLORREF color)
{
m_ActiveTextColor = color;
}
inline void SetNormalTextColor(COLORREF color)
{
m_NormalTextColor = color;
}
inline void SetSelectTextColor(COLORREF color)
{
m_SelectTextColor = color;
}
inline void SetFrameColor(COLORREF color)
{
m_FrameColor = color;
}
inline void SetActiveColor(COLORREF color)
{
m_ActiveColor = color;
}
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHsPMEButton)
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CHsPMEButton();

// Generated message map functions
protected:
//{{AFX_MSG(CHsPMEButton)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG

void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
LONG OnMouseLeave(WPARAM, LPARAM);
BOOL m_bIsMouseMove;

COLORREF m_FrameColor;
COLORREF m_ActiveColor;

COLORREF m_ActiveTextColor;
COLORREF m_NormalTextColor;
COLORREF m_SelectTextColor;

COLORREF m_FrameHeight;
COLORREF m_FrameShadow;

COLORREF m_NormalColorTop;
COLORREF m_NormalColorBottom;

DECLARE_MESSAGE_MAP()
};/////////////////////////////////////////////////////////////////////////////
// CHsPMEButtonCHsPMEButton::CHsPMEButton()
{
m_bIsMouseMove = 0; m_NormalTextColor = RGB(0, 0, 0);
m_SelectTextColor = RGB(0, 0, 0);
m_ActiveTextColor = RGB(0, 0, 0); //m_ActiveColor= RGB(250, 180, 80);
m_ActiveColor= RGB(255, 120, 80); m_NormalColorTop = RGB(255, 255, 255);// 从UG对话框中取出的颜色
m_NormalColorBottom = RGB(213, 208, 196); m_FrameColor= RGB(0, 64, 128);
m_FrameHeight= RGB(230, 230, 230);
m_FrameShadow= RGB(128, 128, 128);
}CHsPMEButton::~CHsPMEButton()
{
}
BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
//{{AFX_MSG_MAP(CHsPMEButton)
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CHsPMEButton message handlersvoid CHsPMEButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
//*
CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
DWORD nState= lpDrawItemStruct->itemState;
DWORD nAction = lpDrawItemStruct->itemAction;
CRect rc   = lpDrawItemStruct->rcItem;
UINT uStyle   = DFCS_BUTTONPUSH; pDC->SetBkMode(TRANSPARENT);
CString strText;
GetWindowText(strText); if( nState & ODS_SELECTED )
{
m_bIsMouseMove = 0;DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
//pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));pDC->SetTextColor(m_SelectTextColor);
}
else //Normal
{
DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);pDC->SetTextColor(m_NormalTextColor);
} if( m_bIsMouseMove )
{
CRect rc2(rc);
rc2.DeflateRect(2, 2, 2, 2);DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
   m_ActiveColor, rc, rc, pDC);
DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);CBrush NullBrush;
NullBrush.CreateStockObject(NULL_BRUSH);
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);

CPen Pen;
Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
CPen* pOldPen = pDC->SelectObject(&Pen);
rc.InflateRect(1,1,1,1);
pDC->RoundRect(rc, CPoint(3, 3));
//rc.DeflateRect(1, 1, 1, 1);
//pDC->Draw3dRect(rc, HeightLight, ShadowLight);

pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);pDC->SetTextColor(m_ActiveTextColor);
}

pDC->DrawText(strText, strText.GetLength(),
&lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
//*///
}void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if( m_bIsMouseMove == 0 )
{
m_bIsMouseMove = 1;
Invalidate();

TRACKMOUSEEVENT trackmouseevent;
trackmouseevent.cbSize = sizeof(trackmouseevent);
trackmouseevent.dwFlags = TME_LEAVE;
trackmouseevent.hwndTrack = GetSafeHwnd();
trackmouseevent.dwHoverTime = HOVER_DEFAULT;
_TrackMouseEvent(&trackmouseevent);
}

CButton::OnMouseMove(nFlags, point);
}LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
{
m_bIsMouseMove = 0;
Invalidate(); return 0;
}void CHsPMEButton::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
UINT nBS = GetButtonStyle(); // Add BS_OWNERDRAW style
SetButtonStyle(nBS | BS_OWNERDRAW); CButton::PreSubclassWindow();
}void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
{
CPen Pen;
CPen* pOldPen = pDC->SelectObject(&Pen);

int R, G, B;
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();

//R = R>0 ? R : -R;
//G = G>0 ? G : -G;
//B = B>0 ? B : -B; int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
COLORREF ColMax = Top > Bottom ? Top : Bottom;
COLORREF ColMin = Top > Bottom ? Bottom: Top; for(int i=0; i<rc.Height(); i++)
{
ColR -= R;
ColG -= G;
ColB -= B;/*
if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
{
   R = G = B = 0;
}///*/
Pen.DeleteObject();
Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
   
pDC->SelectObject(&Pen);

pDC->MoveTo(rc.left, rc.top+i);
pDC->LineTo(rc.right, rc.top+i);
} pDC->SelectObject(pOldPen);
}void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
{
CBrush NullBrush;
NullBrush.CreateStockObject(NULL_BRUSH);
CBrush* pOldBrush = pDC->SelectObject(&NullBrush); CPen Pen;
Pen.CreatePen(PS_SOLID, 1, FrameColor);
CPen* pOldPen = pDC->SelectObject(&Pen);

pDC->RoundRect(rc, CPoint(3, 3));
rc.DeflateRect(1, 1, 1, 1);
pDC->Draw3dRect(rc, HeightLight, ShadowLight); pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
}
/////////////////////////////////////////////////////////////////////////////
// CHsPMEDialog dialog
//-----------------------------------------------------------------------------
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
//   指针将其显示出来,然后隐藏或销毁自身
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。
//-----------------------------------------------------------------------------
// 注意:
// 1、在构造对话框时必须给出其父窗口指针
// 2、在初始化基类时必须指定对话框资源模板ID
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
//-----------------------------------------------------------------------------class CHsPMEDialog : public CDialog
{
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
// Construction
public:
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
~CHsPMEDialog();
BOOL Create(CWnd *pParent = NULL);

// Dialog Data
//{{AFX_DATA(CHsPMEDialog)
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHsPMEDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
virtual void OnOK();
virtual void OnCancel();
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL// Implementation
protected: // Generated message map functions
//{{AFX_MSG(CHsPMEDialog)
afx_msg void OnBack();
virtual BOOL OnInitDialog();
afx_msg void OnDestroy();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()protected:
// attributes
CWnd   *m_pParent;   // 父窗口指针
HICON   m_hIcon;   // 图标
UINT   m_nTemplateID;    // 对话框资源模板ID CHsPMEButton m_btOK;
CHsPMEButton m_btCancel;
CHsPMEButton m_btBack; static HHOOK m_hkKeyboard;    // 键盘钩子句柄
HHOOK   m_hkCBT;   // CBT钩子句柄

//-------------------------------------------------------------------------
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
// 链表的头及下一个结点的指针
static CHsPMEDialog* m_spHead;
CHsPMEDialog *m_pNext; // operations
// 键盘钩子消息的处理函数
static LRESULT CALLBACK KeyboardProc(
int code,       // hook code
WPARAM wParam,// virtual-key code
LPARAM lParam   // keystroke-message information
);
// CBT钩子消息处理函数
static LRESULT CALLBACK CBTProc(
int nCode,      // hook code
WPARAM wParam,// depends on hook code
LPARAM lParam   // depends on hook code
);
// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
static BOOLIsWndKindOfThis(HWND hWnd);
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
static HMODULE ModuleFromAddress(PVOID pv);
public:
// attributes // operations
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框
BOOL CreateChildDialog(CHsPMEDialog *pChild);
};
CHsPMEDialog* g_pHsPMEDlg = NULL;
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
: CDialog(nIDTemplate, pParent)
{
//{{AFX_DATA_INIT(CHsPMEDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_pParent = pParent;
m_nTemplateID = nIDTemplate;
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标 // 建立起链表
m_pNext = m_spHead;
m_spHead = this;
m_hkCBT = NULL;
}CHsPMEDialog::~CHsPMEDialog()
{
// 从链表中删除本结点
CHsPMEDialog *pTemp = m_spHead;
if(pTemp == this)
{
m_spHead = pTemp->m_pNext;
}
else
{
for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
{
   if(pTemp->m_pNext == this)
   {
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
    break;
   }
}
}
}void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHsPMEDialog)
DDX_Control(pDX, IDOK, m_btOK);
DDX_Control(pDX, IDCANCEL, m_btCancel);
DDX_Control(pDX, IDC_BACK, m_btBack);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
//{{AFX_MSG_MAP(CHsPMEDialog)
ON_BN_CLICKED(IDC_BACK, OnBack)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CHsPMEDialog message handlersBOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
{
m_pParent = pParent;
return CDialog::Create(m_nTemplateID, pParent);
}
BOOL CHsPMEDialog::OnInitDialog()
{
CDialog::OnInitDialog(); // 设置标题栏图标
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);

// UG的对话框的几个标准按钮没有TAPSTOP
CWnd *pWnd = NULL;
pWnd = GetDlgItem(IDOK);
if(pWnd)
{
pWnd->ModifyStyle(WS_TABSTOP, 0);
}
pWnd = GetDlgItem(IDC_BACK);
if(pWnd)
{
pWnd->ModifyStyle(WS_TABSTOP, 0);
}
pWnd = GetDlgItem(IDCANCEL);
if(pWnd)
{
pWnd->ModifyStyle(WS_TABSTOP, 0);
}

g_pHsPMEDlg = this;// 方便在静态函数成员中调用 // 设置键盘钩子
if(m_hkKeyboard == NULL)
{
m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
}
if(m_hkKeyboard == NULL)
{
TRACE("Set Keyboard Hook failed: %d/n", GetLastError());
} if(m_hkCBT == NULL)
{
m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
}
if(m_hkCBT == NULL)
{
TRACE("Set CBT Hook Failed: %u/n", GetLastError());
}

return TRUE;// return TRUE unless you set the focus to a control
               // EXCEPTION: OCX Property Pages should return FALSE
}void CHsPMEDialog::OnOK()
{
CDialog::OnOK();
if(m_pParent)
{
//m_pParent->DestroyWindow();
//((CDialog*)m_pParent)->EndDialog(IDOK);
((CHsPMEDialog*)m_pParent)->OnOK();
}
}void CHsPMEDialog::OnCancel()
{
CDialog::OnCancel();
if(m_pParent)
{
//m_pParent->DestroyWindow();
//((CDialog*)m_pParent)->EndDialog(IDCANCEL);
((CHsPMEDialog*)m_pParent)->OnCancel();
}
}void CHsPMEDialog::OnBack()
{
if(m_pParent)
{
m_pParent->ShowWindow(SW_SHOW);
}
CDialog::OnCancel();
}
BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
{
BOOL bRet = FALSE;
if(pChild->GetSafeHwnd() == NULL)
{
bRet = pChild->Create(this);
}
bRet &= ShowWindow(SW_HIDE);
bRet &= pChild->ShowWindow(SW_SHOW);
return bRet;
}LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
if(code == HC_ACTION && !(lParam & 0x80000000))// 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
{
//TRACE("Key down/n");
CWnd *pTopWnd = CWnd::GetActiveWindow();
if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
{
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)
   {
    // 只截获tab、esc及回车键
    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
   }
   switch(wParam) {
   case VK_TAB:
    {
   CWnd *pWnd = pTopWnd->GetFocus();
   CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
   if(pNext)
   {
      int nCtrlID = pNext->GetDlgCtrlID();
      //TRACE("CtrlID = %d/n", nCtrlID);
      pWnd = pNext;
      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
      {
       // 根据UG对话框的属性,这三个按钮是没有焦点的
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
       if(!pNext || pNext == pWnd)
       {
      // 对话框上只有上述三个按钮
      return CallNextHookEx(NULL, code, wParam, lParam);
       }
       nCtrlID = pNext->GetDlgCtrlID();
       //TRACE("CtrlID = %d/n", nCtrlID);
      }
      pNext->SetFocus();
   }
   //return TRUE;
    }
    break;
   case VK_ESCAPE:
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
    //return TRUE;
    break;
   case VK_RETURN:
    // UG实际上并不处理回车键
    break;
   default:
    break;
   }
}
}
return CallNextHookEx(NULL, code, wParam, lParam);
}void CHsPMEDialog::OnDestroy()
{
CDialog::OnDestroy(); g_pHsPMEDlg = NULL; // 销毁键盘钩子
if(m_hkKeyboard)
{
UnhookWindowsHookEx(m_hkKeyboard);
m_hkKeyboard = NULL;
} if(m_hkCBT)
{
UnhookWindowsHookEx(m_hkCBT);
m_hkCBT = NULL;
}
}BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
{
CHsPMEDialog *pTemp = m_spHead;
BOOL bFound = FALSE;
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
{
if(pTemp->m_hWnd == hWnd)
{
   bFound = TRUE;
   break;
}
}
return bFound;
}// Returns the HMODULE that contains the specified memory address
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
{

MEMORY_BASIC_INFORMATION mbi;
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
? (HMODULE) mbi.AllocationBase : NULL);
}LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode == HCBT_CREATEWND)
{
//TRACE("A Window is being created/n");
LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;
//TRACE("Window Name = %s, Class Name = %s/n", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
{
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
   // 取得窗口处理过程内存地址
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
   if(dwUserData)
   {
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
    char szUGPath = {0}, szModulePath = {0};
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
    TRACE("CreateWindow Frome Module: %s/n", szModulePath);
    TRACE("Window Name: %s/n", lpCBT->lpcs->lpszName);
    if(stricmp(szUGPath, szModulePath) == 0)
    {
   // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
   if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
   {
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
      {
       // 窗口非本窗口或其子窗口
       g_pHsPMEDlg->OnCancel();
      }
   }
    }
   }
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来

return CDialog::WindowProc(message, wParam, lParam);
}LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{

return CDialog::DefWindowProc(message, wParam, lParam);
}
页: [1]
查看完整版本: 用MFC对话框模拟UG对话框