自绘对话框-界面设计

原文地址:http://www.cnblogs.com/chenang/archive/2011/11/03/2234460.html

 更多参考:(微软的资料)

 http://msdn.microsoft.com/en-us/library/bb688195(v=vs.85).aspx

 

这篇文章主要是介绍非客户区的自绘,目前只用了对话框功能。

该程序可以实现最大化,最小化,最大化恢复,绘制的效果。

头文件:

// 对话框非客户区自绘Dlg.h : header file
//

#if !defined(AFX_DLG_H__29895C86_9D01_4C17_B374_289E36621F88__INCLUDED_)
#define AFX_DLG_H__29895C86_9D01_4C17_B374_289E36621F88__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/
// CMyDlg dialog

class CMyDlg : public CDialog
{
// Construction
public:
    void GetAreasOfRect();
    CRect NCClientToScreen(CRect* lpRtSrc);
    void DrawNCButtons(CDC *pDC);
    BOOL InitInfo();
    BOOL DrawBitmapInRect(CRect rt, CBitmap *cbmp, CDC *pDC);
    void DrawNC(CDC* pDC);
    LONG GetBitmapWidth(CString strBmpName);
    LONG GetBitmapHeight(CString strBmpName);
    BOOL LoadBitmapFromFile(CString strBmpName, CBitmap* cbmp);
    CMyDlg(CWnd* pParent = NULL);    // standard constructor

// Dialog Data
    //{{AFX_DATA(CMyDlg)
    enum { IDD = IDD_MY_DIALOG };
        // NOTE: the ClassWizard will add data members here
    //}}AFX_DATA

    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMyDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    virtual void PreSubclassWindow();
    virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
    virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
    //}}AFX_VIRTUAL

// Implementation
protected:
    int            m_nCaptionHeight;    //标题栏高度.
    CString        m_strCaptionText;    //标题栏

    BOOL        m_bNCActive;        //窗口活动状态
    BOOL        m_bButtonMinOver;    //最小化按钮,鼠标在上面
    BOOL        m_bButtonMaxOver;    //最大化按钮,鼠标在上面
    BOOL        m_bButtonExitOver;    //关闭按钮,鼠标在上面

    CRect        m_rtWnd;            //整个窗体Rect.
    CRect        m_rtTitleBar;        //Title bar
    CRect        m_rtClient;            //客户区
    CRect        m_rtIcon;            //图标.
    CRect        m_rtCaption;        //标题栏
    CRect        m_rtButtons;        //最大,最小,关闭按钮.
    CRect        m_rtButtonMin;        //最小.
    CRect        m_rtButtonMax;        //最大.
    CRect        m_rtButtonExit;        //关闭.
    CRect        m_rtBorderLeft;        //边框左边.
    CRect        m_rtBorderRight;    //边框右边.
    CRect        m_rtBorderBottom;    //边框底边.
    CRect        m_rtBorderBottom2;    //边框底边.

    CBitmap        m_bmpCaption;        //标题栏
    CBitmap        m_bmpButtonMin;        //最小.
    CBitmap        m_bmpButtonMax;        //最大.
    CBitmap        m_bmpButtonExit;    //关闭.
    CBitmap        m_bmpButtons;        //系统按钮.
    CBitmap        m_bmpBorderLeft;    //边框左边.
    CBitmap        m_bmpBorderRight;    //边框右边.
    CBitmap        m_bmpBorderBottom;    //边框底边.
    CBitmap        m_bmpBorderBottom2;    //边框底边.
    CBitmap        m_bmpCaptionOver;    //标题栏,鼠标在上边
    CBitmap        m_bmpButtonMinOver;    //最小.鼠标在上边
    CBitmap        m_bmpButtonMaxOver;    //最大.鼠标在上边
    CBitmap        m_bmpButtonMaxZoomed;//最大.最大化了
    CBitmap        m_bmpButtonExitOver;//关闭.鼠标在上边

    COLORREF    m_rgbBackGround;    //背景颜色
    COLORREF    m_rgbFrontGroun;    //前景颜色
    CBrush        m_brBackGround;        //背景画刷
    HICON        m_hIcon;            //系统图标

    // Generated message map functions
    //{{AFX_MSG(CMyDlg)
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg void OnNcPaint();
    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point);
    afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
    afx_msg void OnNcLButtonUp(UINT nHitTest, CPoint point);
    afx_msg BOOL OnNcActivate(BOOL bActive);
    afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp);
    afx_msg void OnMove(int x, int y);
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
    afx_msg void OnDestroy();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DLG_H__29895C86_9D01_4C17_B374_289E36621F88__INCLUDED_)

 

实现文件:

// 对话框非客户区自绘Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "对话框非客户区自绘.h"
#include "对话框非客户区自绘Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define BORDER_WIDTH    4        //边框的厚度
/
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
    CAboutDlg();

// Dialog Data
    //{{AFX_DATA(CAboutDlg)
    enum { IDD = IDD_ABOUTBOX };
    //}}AFX_DATA

    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CAboutDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    //}}AFX_VIRTUAL

// Implementation
protected:
    //{{AFX_MSG(CAboutDlg)
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
    //{{AFX_DATA_INIT(CAboutDlg)
    
    //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CAboutDlg)
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    //{{AFX_MSG_MAP(CAboutDlg)
        // No message handlers
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CMyDlg dialog

CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CMyDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CMyDlg)
        // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CMyDlg)
        // NOTE: the ClassWizard will add DDX and DDV calls here
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
    //{{AFX_MSG_MAP(CMyDlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_NCPAINT()
    ON_WM_CTLCOLOR()
    ON_WM_NCMOUSEMOVE()
    ON_WM_NCLBUTTONDOWN()
    ON_WM_NCLBUTTONUP()
    ON_WM_NCACTIVATE()
    ON_WM_NCCALCSIZE()
    ON_WM_MOVE()
    ON_WM_CREATE()
    ON_WM_INITMENUPOPUP()
    ON_WM_DESTROY()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CMyDlg message handlers

BOOL CMyDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    //取消掉 关于 对话框选项
    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    
    // TODO: Add extra initialization here
    InitInfo();
    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialog::OnSysCommand(nID, lParam);
    }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMyDlg::OnPaint() 
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMyDlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}

void CMyDlg::OnNcPaint() 
{
    // TODO: Add your message handler code here
    //更新坐标信息 RECT
    GetAreasOfRect();

    //进行非客户区的画图操作
    CDC* pWinDC=GetWindowDC();
    if (pWinDC) DrawNC(pWinDC);
    ReleaseDC(pWinDC);
    // Do not call CDialog::OnNcPaint() for painting messages
}

void CMyDlg::PreSubclassWindow() 
{
    // TODO: Add your specialized code here and/or call the base class
    m_nCaptionHeight = 50;//GetBitmapHeight(_T("caption_normal"));
    CDialog::PreSubclassWindow();
}

//获取文件中的BMP位图的位图类
BOOL CMyDlg::LoadBitmapFromFile(CString strBmpName, CBitmap* cbmp)
{
    HBITMAP bitmap;
    CString strFilePath;
    strFilePath = _T("skin//") + _T(strBmpName) + _T(".bmp");
    bitmap=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),strFilePath,IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
    
    if (bitmap)
    {
        cbmp->Attach(bitmap);
        return TRUE;
    }

    return FALSE;
}

//获取文件中的BMP图片的高度
LONG CMyDlg::GetBitmapHeight(CString strBmpName)
{
    CBitmap    cbmp;
    BITMAP bmp;
    memset(&bmp, 0, sizeof(BITMAP));

    if (LoadBitmapFromFile(strBmpName, &cbmp))
    {
        cbmp.GetBitmap(&bmp);
    }
    cbmp.DeleteObject();

    return bmp.bmHeight;
}

//获取文件中的BMP图片的宽度
LONG CMyDlg::GetBitmapWidth(CString strBmpName)
{
    CBitmap    cbmp;
    BITMAP bmp;
    memset(&bmp, 0, sizeof(BITMAP));
    
    if (LoadBitmapFromFile(strBmpName, &cbmp))
    {
        cbmp.GetBitmap(&bmp);
    }
    cbmp.DeleteObject();
    
    return bmp.bmWidth;
}

//在RECT区域画一张BMP图
BOOL CMyDlg::DrawBitmapInRect(CRect rt, CBitmap *cbmp, CDC *pDC)
{
    BITMAP    bmp;
    cbmp->GetBitmap(&bmp);
    
    CDC MemDC;
    MemDC.CreateCompatibleDC (pDC);
    CBitmap *pOldBitmap=MemDC.SelectObject(cbmp);
    
//    pDC->BitBlt(rt.left, rt.top, rt.Width(), rt.Height(), &MemDC,0,0,SRCCOPY);
    pDC->StretchBlt(rt.left, rt.top, rt.Width(), rt.Height(), &MemDC,0, 0, bmp.bmWidth, bmp.bmHeight,SRCCOPY);
    MemDC.SelectObject (pOldBitmap);
    ReleaseDC(&MemDC);
    
    //    cbmp.DeleteObject();
    pOldBitmap->DeleteObject();
    return true; 
}

//非客户区画图
void CMyDlg::DrawNC(CDC *pDC)
{
    //各区域贴图
    if (m_bNCActive)
    {
        DrawBitmapInRect(m_rtTitleBar,        &m_bmpCaption,        pDC);
    }
    else
    {
        DrawBitmapInRect(m_rtTitleBar,        &m_bmpCaptionOver,    pDC);
    }
    
    DrawBitmapInRect(m_rtBorderLeft,    &m_bmpBorderLeft,    pDC);
    DrawBitmapInRect(m_rtBorderRight,    &m_bmpBorderRight,    pDC);
    DrawBitmapInRect(m_rtBorderBottom,    &m_bmpBorderBottom,    pDC);
    DrawBitmapInRect(m_rtBorderBottom2,    &m_bmpBorderBottom2,pDC);
    DrawBitmapInRect(m_rtButtons,        &m_bmpButtons,        pDC);
    //画各系统按钮的不同状态下的贴图 
    DrawNCButtons(pDC);

    //画图标
    ::DrawIconEx(pDC->m_hDC, m_rtIcon.left, m_rtIcon.top,m_hIcon,m_rtIcon.Height(), m_rtIcon.Width(),0, NULL,DI_NORMAL);

    //画CAPTION 文本信息
    pDC->SetBkMode(TRANSPARENT);            //背景透明
    pDC->SetTextColor(RGB(100, 100, 200));    //文本颜色

    CRect rect = m_rtCaption;
    rect.OffsetRect(BORDER_WIDTH,BORDER_WIDTH);
    pDC->DrawText(m_strCaptionText, rect, DT_CENTER);
    pDC->DrawText(m_strCaptionText, CRect(rect.left+1,rect.top,rect.right+1,rect.bottom), DT_CENTER);
}

//非客户区按钮区画图
void CMyDlg::DrawNCButtons(CDC *pDC)
{
    //画各系统按钮的不同状态下的贴图 
    if (m_bButtonExitOver)
    {
        DrawBitmapInRect(m_rtButtonExit,    &m_bmpButtonExitOver,    pDC);
    }
    else
    {
        DrawBitmapInRect(m_rtButtonExit,    &m_bmpButtonExit,    pDC);
    }
    if (IsZoomed())
    {
        DrawBitmapInRect(m_rtButtonMax,        &m_bmpButtonMaxZoomed,    pDC);
    }
    else
    {
        if (m_bButtonMaxOver)
        {
            DrawBitmapInRect(m_rtButtonMax,        &m_bmpButtonMaxOver,    pDC);
        }
        else
        {
            DrawBitmapInRect(m_rtButtonMax,        &m_bmpButtonMax,    pDC);
        }
    }
    if (m_bButtonMinOver)
    {
        DrawBitmapInRect(m_rtButtonMin,        &m_bmpButtonMinOver,    pDC);
    }
    else
    {
        DrawBitmapInRect(m_rtButtonMin,        &m_bmpButtonMin,    pDC);
    }
}

//非客户区的坐标转换为屏幕坐标
CRect CMyDlg::NCClientToScreen(CRect *lpRtSrc)
{
    //坐标系转换
    CRect    rect;
    
    rect = CRect(lpRtSrc->left, lpRtSrc->top-m_nCaptionHeight, lpRtSrc->right, lpRtSrc->bottom-m_nCaptionHeight);
    ClientToScreen(&rect);
    
    return rect;
}

//初始化图片 等资源信息
BOOL CMyDlg::InitInfo()
{
    //状态信息
    m_bNCActive            = TRUE;
    m_bButtonExitOver    = FALSE;
    m_bButtonMinOver    = FALSE;
    m_bButtonMaxOver    = FALSE;

    //初始化载入的信息
    LoadBitmapFromFile(_T("caption_normal"),        &m_bmpCaption);
    LoadBitmapFromFile(_T("btn_min_normal"),        &m_bmpButtonMin);
    LoadBitmapFromFile(_T("btn_max_normal"),        &m_bmpButtonMax);
    LoadBitmapFromFile(_T("btn_exit_normal"),        &m_bmpButtonExit);
    LoadBitmapFromFile(_T("btns_normal"),            &m_bmpButtons);
    LoadBitmapFromFile(_T("border_left_normal"),    &m_bmpBorderLeft);
    LoadBitmapFromFile(_T("border_right_normal"),    &m_bmpBorderRight);
    LoadBitmapFromFile(_T("border_bottom_normal"),    &m_bmpBorderBottom);
    LoadBitmapFromFile(_T("border_bottom2_normal"),    &m_bmpBorderBottom2);
    LoadBitmapFromFile(_T("caption_over"),            &m_bmpCaptionOver);
    LoadBitmapFromFile(_T("btn_min_over"),            &m_bmpButtonMinOver);
    LoadBitmapFromFile(_T("btn_max_over"),            &m_bmpButtonMaxOver);
    LoadBitmapFromFile(_T("btn_max_zoomed"),        &m_bmpButtonMaxZoomed);
    LoadBitmapFromFile(_T("btn_exit_over"),            &m_bmpButtonExitOver);


    //CAPTION 文本
    m_strCaptionText        = _T("漂亮窗口的自绘");

    //设置背景颜色和前景颜色
    m_rgbBackGround            = RGB(210,230,240);
    m_rgbFrontGroun            = RGB(255,0,0);
    
    //画刷
    m_brBackGround.CreateSolidBrush(m_rgbBackGround);

//    ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE);

    //更新坐标信息 RECT
    GetAreasOfRect();

    return TRUE;
}

//获取各区域的RECT坐标
void CMyDlg::GetAreasOfRect()
{
    //设置各区域的RECT坐标:主要以m_rtWnd为基准进行计算
    GetWindowRect(&m_rtWnd);
    
    //TitleBar 的RECT坐标
    m_rtTitleBar.left        = 0;
    m_rtTitleBar.top        = 0;
    m_rtTitleBar.right        = m_rtWnd.Width() + BORDER_WIDTH;
    m_rtTitleBar.bottom        = m_nCaptionHeight + BORDER_WIDTH;
    
    //ICON 的RECT坐标
    m_rtIcon.left            = m_rtTitleBar.left + 10;
    m_rtIcon.top            = m_rtTitleBar.top + 2;
    m_rtIcon.right            = m_rtIcon.left + m_rtTitleBar.Height() - BORDER_WIDTH;
    m_rtIcon.bottom            = m_rtIcon.top + m_rtTitleBar.Height() - BORDER_WIDTH;
    
    int height=0,width=0;
    height    = GetBitmapHeight(_T("btn_exit_normal"));
    width    = GetBitmapWidth (_T("btn_exit_normal"));
    //关闭按钮 的RECT坐标
    m_rtButtonExit.top        = m_rtTitleBar.top + 2;
    m_rtButtonExit.right    = m_rtTitleBar.right - 6*BORDER_WIDTH;
    m_rtButtonExit.bottom    = m_rtButtonExit.top + height;
    m_rtButtonExit.left        = m_rtButtonExit.right - width;
    
    height    = GetBitmapHeight(_T("btn_max_normal"));
    width    = GetBitmapWidth (_T("btn_max_normal"));
    //最大化按钮 的RECT坐标
    m_rtButtonMax.top        = m_rtButtonExit.top;
    m_rtButtonMax.right        = m_rtButtonExit.left - 2;
    m_rtButtonMax.bottom    = m_rtButtonMax.top + height;
    m_rtButtonMax.left        = m_rtButtonMax.right - width;
    
    height    = GetBitmapHeight(_T("btn_min_normal"));
    width    = GetBitmapWidth (_T("btn_min_normal"));
    //最小化按钮 的RECT坐标
    m_rtButtonMin.top        = m_rtButtonMax.top;
    m_rtButtonMin.right        = m_rtButtonMax.left - 2;
    m_rtButtonMin.bottom    = m_rtButtonMin.top + height;
    m_rtButtonMin.left        = m_rtButtonMin.right - width;
    
    //系统按钮区 的RECT坐标
    m_rtButtons.left        = m_rtButtonMin.left-6*BORDER_WIDTH;
    m_rtButtons.top            = m_rtTitleBar.top;
    m_rtButtons.right        = m_rtTitleBar.right;
    m_rtButtons.bottom        = m_rtTitleBar.bottom;
    
    //CAPTION 的RECT坐标
    m_rtCaption.left        = m_rtIcon.right;
    m_rtCaption.top            = m_rtTitleBar.top;
    m_rtCaption.right        = m_rtButtonMin.left;
    m_rtCaption.bottom        = m_rtTitleBar.bottom;
    
    //边框左边的 RECT坐标
    m_rtBorderLeft.left        = m_rtTitleBar.left;
    m_rtBorderLeft.top        = m_rtTitleBar.bottom - BORDER_WIDTH;
    m_rtBorderLeft.right    = m_rtBorderLeft.left + BORDER_WIDTH;
    m_rtBorderLeft.bottom    = m_rtTitleBar.top + m_rtWnd.Height();
    
    //边框右边的 RECT坐标
    m_rtBorderRight.right    = m_rtTitleBar.right - BORDER_WIDTH;
    m_rtBorderRight.left    = m_rtTitleBar.right - 2*BORDER_WIDTH;
    m_rtBorderRight.top        = m_rtTitleBar.bottom - 2*BORDER_WIDTH;
    m_rtBorderRight.bottom    = m_rtTitleBar.top + m_rtWnd.Height();
    
    //边框底边的 RECT坐标
    m_rtBorderBottom.left    = m_rtBorderLeft.left;
    m_rtBorderBottom.top    = m_rtWnd.Height()  - 1*BORDER_WIDTH;
    m_rtBorderBottom.right    = m_rtBorderRight.right;
    m_rtBorderBottom.bottom = m_rtBorderBottom.top + 3*BORDER_WIDTH;
    
    m_rtBorderBottom2        = m_rtBorderBottom;
    m_rtBorderBottom2.left    = m_rtBorderBottom.left + (m_rtWnd.Width() - m_rtButtons.Width()) + m_rtIcon.Width();
    m_rtBorderBottom2.right    = m_rtBorderRight.right;
}

//对话框及常见控件进行文本颜色 字体类型 画刷填充
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    
    // TODO: Change any attributes of the DC here
    if (nCtlColor == CTLCOLOR_DLG)
    {
        pDC->SetBkMode(TRANSPARENT);
        pDC->SetTextColor(m_rgbFrontGroun);
        return static_cast<HBRUSH>(m_brBackGround);
    }

    if (nCtlColor == CTLCOLOR_STATIC)
    {
        pDC->SetBkMode(TRANSPARENT);
        pDC->SetTextColor(m_rgbFrontGroun);
        return static_cast<HBRUSH>(m_brBackGround);
    }
    // TODO: Return a different brush if the default is not desired
    return hbr;
}

void CMyDlg::OnNcMouseMove(UINT nHitTest, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    //坐标系转换
    CRect    rect;

    //判断当前鼠标位置是否在各系统按钮上: 非客户区的整个TitleBar的高度
    rect = NCClientToScreen(&m_rtButtonExit);
    if (rect.PtInRect(point))
    {
        m_bButtonExitOver = TRUE;
    }
    else
    {
        m_bButtonExitOver = FALSE;
    }

    //最大化按钮上的时候,更新按钮上状态
    rect = NCClientToScreen(&m_rtButtonMax);
    if (rect.PtInRect(point))
    {
        m_bButtonMaxOver = TRUE;
    }
    else
    {
        m_bButtonMaxOver = FALSE;
    }

    //最小化按钮上的时候,更新按钮上状态
    rect = NCClientToScreen(&m_rtButtonMin);
    if (rect.PtInRect(point))
    {
        m_bButtonMinOver = TRUE;
    }
    else
    {
        m_bButtonMinOver = FALSE;
    }

    //只更新系统按钮
    CDC* pWinDC=GetWindowDC();
    if (pWinDC) DrawNCButtons(pWinDC);
    ReleaseDC(pWinDC);

    CDialog::OnNcMouseMove(nHitTest, point);
}

LRESULT CMyDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    // TODO: Add your specialized code here and/or call the base class

    return CDialog::DefWindowProc(message, wParam, lParam);
}

LRESULT CMyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    // TODO: Add your specialized code here and/or call the base class
     switch (message)
     {
//     case WM_NCMOUSEMOVE:
//         if (wParam==HTMINBUTTON || wParam==HTMAXBUTTON || wParam==HTCLOSE)
//         {
//             wParam=HTCAPTION;
//         }
//          break;
    case WM_NCHITTEST:
        if (wParam==HTMINBUTTON || wParam==HTMAXBUTTON || wParam==HTCLOSE)
        {
            wParam=HTCAPTION;
        }
        break;
    case WM_NCACTIVATE:
//        m_strCaptionText.Format(_T("%d %d %d"), wParam, HIWORD(lParam), LOWORD(lParam));
        break;
    case WM_SETCURSOR:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCLBUTTONDOWN:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCLBUTTONUP:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCLBUTTONDBLCLK:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCRBUTTONDOWN:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCRBUTTONDBLCLK:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case 0x125:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
     }
    return CDialog::WindowProc(message, wParam, lParam);
}

//鼠标事件的处理:鼠标按下
void CMyDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    if (m_bButtonMinOver)
    {
        CDC* pWinDC=GetWindowDC();
        if (pWinDC) DrawBitmapInRect(m_rtButtonMin, &m_bmpButtonMin, pWinDC);
        ReleaseDC(pWinDC);
        return;
    }
    if (m_bButtonMaxOver)
    {
        CDC* pWinDC=GetWindowDC();
        if (pWinDC) DrawBitmapInRect(m_rtButtonMax, &m_bmpButtonMax, pWinDC);
        ReleaseDC(pWinDC);
        return;
    }
    if (m_bButtonExitOver)
    {
        CDC* pWinDC=GetWindowDC();
        if (pWinDC) DrawBitmapInRect(m_rtButtonExit, &m_bmpButtonExit, pWinDC);
        ReleaseDC(pWinDC);
        return;
    }

    if(!IsZoomed())//防止在最大化后能拖动.
    {
        CDialog::OnNcLButtonDown(nHitTest, point);
    }
}

//鼠标事件的处理:鼠标弹起
void CMyDlg::OnNcLButtonUp(UINT nHitTest, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    
    if (m_bButtonMinOver)
    {
        SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, MAKELPARAM(point.x, point.y));
    }
    if (m_bButtonMaxOver)
    {
        if (IsZoomed())
        {
            SendMessage(WM_SYSCOMMAND, SC_RESTORE, MAKELPARAM(point.x, point.y));
        }
        else
        {
            SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, MAKELPARAM(point.x, point.y));
        }
    }
    if (m_bButtonExitOver)
    {
        PostMessage(WM_CLOSE);
    }
    CDialog::OnNcLButtonUp(nHitTest, point);
}

BOOL CMyDlg::OnNcActivate(BOOL bActive) 
{
    // TODO: Add your message handler code here and/or call default
    m_bNCActive = bActive;
    if (m_bNCActive)
    {
        ModifyStyle(0, WS_SYSMENU);
        OnNcPaint();
    }
    else
    {
        ModifyStyle(WS_SYSMENU, 0);
        OnNcPaint();
    }
    return true;    //返回真,防止任务栏中点击鼠标左键和右键,显示原有框架
    /*CDialog::OnNcActivate(bActive)*/
}

void CMyDlg::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
{
    // TODO: Add your message handler code here and/or call default
    lpncsp->rgrc[0].top+=m_nCaptionHeight-GetSystemMetrics(SM_CYCAPTION);
    CDialog::OnNcCalcSize(bCalcValidRects, lpncsp);
}

void CMyDlg::OnMove(int x, int y) 
{
    CDialog::OnMove(x, y);
    
    // TODO: Add your message handler code here
    GetWindowRect(&m_rtWnd);
}

int CMyDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    this->ModifyStyle(WS_SYSMENU, 0);//防止在任务栏右单击时出现最大最小关闭.
    if (CDialog::OnCreate(lpCreateStruct) == -1)
        return -1;
    return 0;
}

void CMyDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) 
{
    CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
    
    // TODO: Add your message handler code here
    if(bSysMenu)
    {
        OnNcPaint();
    }
}


void CMyDlg::OnDestroy() 
{
    CDialog::OnDestroy();
    
    // TODO: Add your message handler code here
    m_bmpButtonMin.DeleteObject();
    m_bmpButtonMax.DeleteObject();
    m_bmpButtonExit.DeleteObject();
    m_bmpButtons.DeleteObject();
    m_bmpBorderLeft.DeleteObject();
    m_bmpBorderRight.DeleteObject();
    m_bmpBorderBottom.DeleteObject();
    m_bmpBorderBottom2.DeleteObject();
    m_bmpCaptionOver.DeleteObject();
    m_bmpButtonMinOver.DeleteObject();
    m_bmpButtonMaxOver.DeleteObject();
    m_bmpButtonMaxZoomed.DeleteObject();
    m_bmpButtonExitOver.DeleteObject();
}


 


// 对话框非客户区自绘Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "对话框非客户区自绘.h"
#include "对话框非客户区自绘Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define BORDER_WIDTH    4        //边框的厚度
/
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
    CAboutDlg();

// Dialog Data
    //{{AFX_DATA(CAboutDlg)
    enum { IDD = IDD_ABOUTBOX };
    //}}AFX_DATA

    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CAboutDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    //}}AFX_VIRTUAL

// Implementation
protected:
    //{{AFX_MSG(CAboutDlg)
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
    //{{AFX_DATA_INIT(CAboutDlg)
    
    //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CAboutDlg)
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    //{{AFX_MSG_MAP(CAboutDlg)
        // No message handlers
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CMyDlg dialog

CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CMyDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CMyDlg)
        // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CMyDlg)
        // NOTE: the ClassWizard will add DDX and DDV calls here
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
    //{{AFX_MSG_MAP(CMyDlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_NCPAINT()
    ON_WM_CTLCOLOR()
    ON_WM_NCMOUSEMOVE()
    ON_WM_NCLBUTTONDOWN()
    ON_WM_NCLBUTTONUP()
    ON_WM_NCACTIVATE()
    ON_WM_NCCALCSIZE()
    ON_WM_MOVE()
    ON_WM_CREATE()
    ON_WM_INITMENUPOPUP()
    ON_WM_DESTROY()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CMyDlg message handlers

BOOL CMyDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    //取消掉 关于 对话框选项
    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    
    // TODO: Add extra initialization here
    InitInfo();
    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialog::OnSysCommand(nID, lParam);
    }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMyDlg::OnPaint() 
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMyDlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}

void CMyDlg::OnNcPaint() 
{
    // TODO: Add your message handler code here
    //更新坐标信息 RECT
    GetAreasOfRect();

    //进行非客户区的画图操作
    CDC* pWinDC=GetWindowDC();
    if (pWinDC) DrawNC(pWinDC);
    ReleaseDC(pWinDC);
    // Do not call CDialog::OnNcPaint() for painting messages
}

void CMyDlg::PreSubclassWindow() 
{
    // TODO: Add your specialized code here and/or call the base class
    m_nCaptionHeight = 50;//GetBitmapHeight(_T("caption_normal"));
    CDialog::PreSubclassWindow();
}

//获取文件中的BMP位图的位图类
BOOL CMyDlg::LoadBitmapFromFile(CString strBmpName, CBitmap* cbmp)
{
    HBITMAP bitmap;
    CString strFilePath;
    strFilePath = _T("skin//") + _T(strBmpName) + _T(".bmp");
    bitmap=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),strFilePath,IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
    
    if (bitmap)
    {
        cbmp->Attach(bitmap);
        return TRUE;
    }

    return FALSE;
}

//获取文件中的BMP图片的高度
LONG CMyDlg::GetBitmapHeight(CString strBmpName)
{
    CBitmap    cbmp;
    BITMAP bmp;
    memset(&bmp, 0, sizeof(BITMAP));

    if (LoadBitmapFromFile(strBmpName, &cbmp))
    {
        cbmp.GetBitmap(&bmp);
    }
    cbmp.DeleteObject();

    return bmp.bmHeight;
}

//获取文件中的BMP图片的宽度
LONG CMyDlg::GetBitmapWidth(CString strBmpName)
{
    CBitmap    cbmp;
    BITMAP bmp;
    memset(&bmp, 0, sizeof(BITMAP));
    
    if (LoadBitmapFromFile(strBmpName, &cbmp))
    {
        cbmp.GetBitmap(&bmp);
    }
    cbmp.DeleteObject();
    
    return bmp.bmWidth;
}

//在RECT区域画一张BMP图
BOOL CMyDlg::DrawBitmapInRect(CRect rt, CBitmap *cbmp, CDC *pDC)
{
    BITMAP    bmp;
    cbmp->GetBitmap(&bmp);
    
    CDC MemDC;
    MemDC.CreateCompatibleDC (pDC);
    CBitmap *pOldBitmap=MemDC.SelectObject(cbmp);
    
//    pDC->BitBlt(rt.left, rt.top, rt.Width(), rt.Height(), &MemDC,0,0,SRCCOPY);
    pDC->StretchBlt(rt.left, rt.top, rt.Width(), rt.Height(), &MemDC,0, 0, bmp.bmWidth, bmp.bmHeight,SRCCOPY);
    MemDC.SelectObject (pOldBitmap);
    ReleaseDC(&MemDC);
    
    //    cbmp.DeleteObject();
    pOldBitmap->DeleteObject();
    return true; 
}

//非客户区画图
void CMyDlg::DrawNC(CDC *pDC)
{
    //各区域贴图
    if (m_bNCActive)
    {
        DrawBitmapInRect(m_rtTitleBar,        &m_bmpCaption,        pDC);
    }
    else
    {
        DrawBitmapInRect(m_rtTitleBar,        &m_bmpCaptionOver,    pDC);
    }
    
    DrawBitmapInRect(m_rtBorderLeft,    &m_bmpBorderLeft,    pDC);
    DrawBitmapInRect(m_rtBorderRight,    &m_bmpBorderRight,    pDC);
    DrawBitmapInRect(m_rtBorderBottom,    &m_bmpBorderBottom,    pDC);
    DrawBitmapInRect(m_rtBorderBottom2,    &m_bmpBorderBottom2,pDC);
    DrawBitmapInRect(m_rtButtons,        &m_bmpButtons,        pDC);
    //画各系统按钮的不同状态下的贴图 
    DrawNCButtons(pDC);

    //画图标
    ::DrawIconEx(pDC->m_hDC, m_rtIcon.left, m_rtIcon.top,m_hIcon,m_rtIcon.Height(), m_rtIcon.Width(),0, NULL,DI_NORMAL);

    //画CAPTION 文本信息
    pDC->SetBkMode(TRANSPARENT);            //背景透明
    pDC->SetTextColor(RGB(100, 100, 200));    //文本颜色

    CRect rect = m_rtCaption;
    rect.OffsetRect(BORDER_WIDTH,BORDER_WIDTH);
    pDC->DrawText(m_strCaptionText, rect, DT_CENTER);
    pDC->DrawText(m_strCaptionText, CRect(rect.left+1,rect.top,rect.right+1,rect.bottom), DT_CENTER);
}

//非客户区按钮区画图
void CMyDlg::DrawNCButtons(CDC *pDC)
{
    //画各系统按钮的不同状态下的贴图 
    if (m_bButtonExitOver)
    {
        DrawBitmapInRect(m_rtButtonExit,    &m_bmpButtonExitOver,    pDC);
    }
    else
    {
        DrawBitmapInRect(m_rtButtonExit,    &m_bmpButtonExit,    pDC);
    }
    if (IsZoomed())
    {
        DrawBitmapInRect(m_rtButtonMax,        &m_bmpButtonMaxZoomed,    pDC);
    }
    else
    {
        if (m_bButtonMaxOver)
        {
            DrawBitmapInRect(m_rtButtonMax,        &m_bmpButtonMaxOver,    pDC);
        }
        else
        {
            DrawBitmapInRect(m_rtButtonMax,        &m_bmpButtonMax,    pDC);
        }
    }
    if (m_bButtonMinOver)
    {
        DrawBitmapInRect(m_rtButtonMin,        &m_bmpButtonMinOver,    pDC);
    }
    else
    {
        DrawBitmapInRect(m_rtButtonMin,        &m_bmpButtonMin,    pDC);
    }
}

//非客户区的坐标转换为屏幕坐标
CRect CMyDlg::NCClientToScreen(CRect *lpRtSrc)
{
    //坐标系转换
    CRect    rect;
    
    rect = CRect(lpRtSrc->left, lpRtSrc->top-m_nCaptionHeight, lpRtSrc->right, lpRtSrc->bottom-m_nCaptionHeight);
    ClientToScreen(&rect);
    
    return rect;
}

//初始化图片 等资源信息
BOOL CMyDlg::InitInfo()
{
    //状态信息
    m_bNCActive            = TRUE;
    m_bButtonExitOver    = FALSE;
    m_bButtonMinOver    = FALSE;
    m_bButtonMaxOver    = FALSE;

    //初始化载入的信息
    LoadBitmapFromFile(_T("caption_normal"),        &m_bmpCaption);
    LoadBitmapFromFile(_T("btn_min_normal"),        &m_bmpButtonMin);
    LoadBitmapFromFile(_T("btn_max_normal"),        &m_bmpButtonMax);
    LoadBitmapFromFile(_T("btn_exit_normal"),        &m_bmpButtonExit);
    LoadBitmapFromFile(_T("btns_normal"),            &m_bmpButtons);
    LoadBitmapFromFile(_T("border_left_normal"),    &m_bmpBorderLeft);
    LoadBitmapFromFile(_T("border_right_normal"),    &m_bmpBorderRight);
    LoadBitmapFromFile(_T("border_bottom_normal"),    &m_bmpBorderBottom);
    LoadBitmapFromFile(_T("border_bottom2_normal"),    &m_bmpBorderBottom2);
    LoadBitmapFromFile(_T("caption_over"),            &m_bmpCaptionOver);
    LoadBitmapFromFile(_T("btn_min_over"),            &m_bmpButtonMinOver);
    LoadBitmapFromFile(_T("btn_max_over"),            &m_bmpButtonMaxOver);
    LoadBitmapFromFile(_T("btn_max_zoomed"),        &m_bmpButtonMaxZoomed);
    LoadBitmapFromFile(_T("btn_exit_over"),            &m_bmpButtonExitOver);


    //CAPTION 文本
    m_strCaptionText        = _T("漂亮窗口的自绘");

    //设置背景颜色和前景颜色
    m_rgbBackGround            = RGB(210,230,240);
    m_rgbFrontGroun            = RGB(255,0,0);
    
    //画刷
    m_brBackGround.CreateSolidBrush(m_rgbBackGround);

//    ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE);

    //更新坐标信息 RECT
    GetAreasOfRect();

    return TRUE;
}

//获取各区域的RECT坐标
void CMyDlg::GetAreasOfRect()
{
    //设置各区域的RECT坐标:主要以m_rtWnd为基准进行计算
    GetWindowRect(&m_rtWnd);
    
    //TitleBar 的RECT坐标
    m_rtTitleBar.left        = 0;
    m_rtTitleBar.top        = 0;
    m_rtTitleBar.right        = m_rtWnd.Width() + BORDER_WIDTH;
    m_rtTitleBar.bottom        = m_nCaptionHeight + BORDER_WIDTH;
    
    //ICON 的RECT坐标
    m_rtIcon.left            = m_rtTitleBar.left + 10;
    m_rtIcon.top            = m_rtTitleBar.top + 2;
    m_rtIcon.right            = m_rtIcon.left + m_rtTitleBar.Height() - BORDER_WIDTH;
    m_rtIcon.bottom            = m_rtIcon.top + m_rtTitleBar.Height() - BORDER_WIDTH;
    
    int height=0,width=0;
    height    = GetBitmapHeight(_T("btn_exit_normal"));
    width    = GetBitmapWidth (_T("btn_exit_normal"));
    //关闭按钮 的RECT坐标
    m_rtButtonExit.top        = m_rtTitleBar.top + 2;
    m_rtButtonExit.right    = m_rtTitleBar.right - 6*BORDER_WIDTH;
    m_rtButtonExit.bottom    = m_rtButtonExit.top + height;
    m_rtButtonExit.left        = m_rtButtonExit.right - width;
    
    height    = GetBitmapHeight(_T("btn_max_normal"));
    width    = GetBitmapWidth (_T("btn_max_normal"));
    //最大化按钮 的RECT坐标
    m_rtButtonMax.top        = m_rtButtonExit.top;
    m_rtButtonMax.right        = m_rtButtonExit.left - 2;
    m_rtButtonMax.bottom    = m_rtButtonMax.top + height;
    m_rtButtonMax.left        = m_rtButtonMax.right - width;
    
    height    = GetBitmapHeight(_T("btn_min_normal"));
    width    = GetBitmapWidth (_T("btn_min_normal"));
    //最小化按钮 的RECT坐标
    m_rtButtonMin.top        = m_rtButtonMax.top;
    m_rtButtonMin.right        = m_rtButtonMax.left - 2;
    m_rtButtonMin.bottom    = m_rtButtonMin.top + height;
    m_rtButtonMin.left        = m_rtButtonMin.right - width;
    
    //系统按钮区 的RECT坐标
    m_rtButtons.left        = m_rtButtonMin.left-6*BORDER_WIDTH;
    m_rtButtons.top            = m_rtTitleBar.top;
    m_rtButtons.right        = m_rtTitleBar.right;
    m_rtButtons.bottom        = m_rtTitleBar.bottom;
    
    //CAPTION 的RECT坐标
    m_rtCaption.left        = m_rtIcon.right;
    m_rtCaption.top            = m_rtTitleBar.top;
    m_rtCaption.right        = m_rtButtonMin.left;
    m_rtCaption.bottom        = m_rtTitleBar.bottom;
    
    //边框左边的 RECT坐标
    m_rtBorderLeft.left        = m_rtTitleBar.left;
    m_rtBorderLeft.top        = m_rtTitleBar.bottom - BORDER_WIDTH;
    m_rtBorderLeft.right    = m_rtBorderLeft.left + BORDER_WIDTH;
    m_rtBorderLeft.bottom    = m_rtTitleBar.top + m_rtWnd.Height();
    
    //边框右边的 RECT坐标
    m_rtBorderRight.right    = m_rtTitleBar.right - BORDER_WIDTH;
    m_rtBorderRight.left    = m_rtTitleBar.right - 2*BORDER_WIDTH;
    m_rtBorderRight.top        = m_rtTitleBar.bottom - 2*BORDER_WIDTH;
    m_rtBorderRight.bottom    = m_rtTitleBar.top + m_rtWnd.Height();
    
    //边框底边的 RECT坐标
    m_rtBorderBottom.left    = m_rtBorderLeft.left;
    m_rtBorderBottom.top    = m_rtWnd.Height()  - 1*BORDER_WIDTH;
    m_rtBorderBottom.right    = m_rtBorderRight.right;
    m_rtBorderBottom.bottom = m_rtBorderBottom.top + 3*BORDER_WIDTH;
    
    m_rtBorderBottom2        = m_rtBorderBottom;
    m_rtBorderBottom2.left    = m_rtBorderBottom.left + (m_rtWnd.Width() - m_rtButtons.Width()) + m_rtIcon.Width();
    m_rtBorderBottom2.right    = m_rtBorderRight.right;
}

//对话框及常见控件进行文本颜色 字体类型 画刷填充
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    
    // TODO: Change any attributes of the DC here
    if (nCtlColor == CTLCOLOR_DLG)
    {
        pDC->SetBkMode(TRANSPARENT);
        pDC->SetTextColor(m_rgbFrontGroun);
        return static_cast<HBRUSH>(m_brBackGround);
    }

    if (nCtlColor == CTLCOLOR_STATIC)
    {
        pDC->SetBkMode(TRANSPARENT);
        pDC->SetTextColor(m_rgbFrontGroun);
        return static_cast<HBRUSH>(m_brBackGround);
    }
    // TODO: Return a different brush if the default is not desired
    return hbr;
}

void CMyDlg::OnNcMouseMove(UINT nHitTest, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    //坐标系转换
    CRect    rect;

    //判断当前鼠标位置是否在各系统按钮上: 非客户区的整个TitleBar的高度
    rect = NCClientToScreen(&m_rtButtonExit);
    if (rect.PtInRect(point))
    {
        m_bButtonExitOver = TRUE;
    }
    else
    {
        m_bButtonExitOver = FALSE;
    }

    //最大化按钮上的时候,更新按钮上状态
    rect = NCClientToScreen(&m_rtButtonMax);
    if (rect.PtInRect(point))
    {
        m_bButtonMaxOver = TRUE;
    }
    else
    {
        m_bButtonMaxOver = FALSE;
    }

    //最小化按钮上的时候,更新按钮上状态
    rect = NCClientToScreen(&m_rtButtonMin);
    if (rect.PtInRect(point))
    {
        m_bButtonMinOver = TRUE;
    }
    else
    {
        m_bButtonMinOver = FALSE;
    }

    //只更新系统按钮
    CDC* pWinDC=GetWindowDC();
    if (pWinDC) DrawNCButtons(pWinDC);
    ReleaseDC(pWinDC);

    CDialog::OnNcMouseMove(nHitTest, point);
}

LRESULT CMyDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    // TODO: Add your specialized code here and/or call the base class

    return CDialog::DefWindowProc(message, wParam, lParam);
}

LRESULT CMyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    // TODO: Add your specialized code here and/or call the base class
     switch (message)
     {
//     case WM_NCMOUSEMOVE:
//         if (wParam==HTMINBUTTON || wParam==HTMAXBUTTON || wParam==HTCLOSE)
//         {
//             wParam=HTCAPTION;
//         }
//          break;
    case WM_NCHITTEST:
        if (wParam==HTMINBUTTON || wParam==HTMAXBUTTON || wParam==HTCLOSE)
        {
            wParam=HTCAPTION;
        }
        break;
    case WM_NCACTIVATE:
//        m_strCaptionText.Format(_T("%d %d %d"), wParam, HIWORD(lParam), LOWORD(lParam));
        break;
    case WM_SETCURSOR:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCLBUTTONDOWN:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCLBUTTONUP:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCLBUTTONDBLCLK:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCRBUTTONDOWN:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case WM_NCRBUTTONDBLCLK:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
    case 0x125:
        ModifyStyle(WS_SYSMENU, 0);//移除系统菜单.
        break;
     }
    return CDialog::WindowProc(message, wParam, lParam);
}

//鼠标事件的处理:鼠标按下
void CMyDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    if (m_bButtonMinOver)
    {
        CDC* pWinDC=GetWindowDC();
        if (pWinDC) DrawBitmapInRect(m_rtButtonMin, &m_bmpButtonMin, pWinDC);
        ReleaseDC(pWinDC);
        return;
    }
    if (m_bButtonMaxOver)
    {
        CDC* pWinDC=GetWindowDC();
        if (pWinDC) DrawBitmapInRect(m_rtButtonMax, &m_bmpButtonMax, pWinDC);
        ReleaseDC(pWinDC);
        return;
    }
    if (m_bButtonExitOver)
    {
        CDC* pWinDC=GetWindowDC();
        if (pWinDC) DrawBitmapInRect(m_rtButtonExit, &m_bmpButtonExit, pWinDC);
        ReleaseDC(pWinDC);
        return;
    }

    if(!IsZoomed())//防止在最大化后能拖动.
    {
        CDialog::OnNcLButtonDown(nHitTest, point);
    }
}

//鼠标事件的处理:鼠标弹起
void CMyDlg::OnNcLButtonUp(UINT nHitTest, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    
    if (m_bButtonMinOver)
    {
        SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, MAKELPARAM(point.x, point.y));
    }
    if (m_bButtonMaxOver)
    {
        if (IsZoomed())
        {
            SendMessage(WM_SYSCOMMAND, SC_RESTORE, MAKELPARAM(point.x, point.y));
        }
        else
        {
            SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, MAKELPARAM(point.x, point.y));
        }
    }
    if (m_bButtonExitOver)
    {
        PostMessage(WM_CLOSE);
    }
    CDialog::OnNcLButtonUp(nHitTest, point);
}

BOOL CMyDlg::OnNcActivate(BOOL bActive) 
{
    // TODO: Add your message handler code here and/or call default
    m_bNCActive = bActive;
    if (m_bNCActive)
    {
        ModifyStyle(0, WS_SYSMENU);
        OnNcPaint();
    }
    else
    {
        ModifyStyle(WS_SYSMENU, 0);
        OnNcPaint();
    }
    return true;    //返回真,防止任务栏中点击鼠标左键和右键,显示原有框架
    /*CDialog::OnNcActivate(bActive)*/
}

void CMyDlg::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
{
    // TODO: Add your message handler code here and/or call default
    lpncsp->rgrc[0].top+=m_nCaptionHeight-GetSystemMetrics(SM_CYCAPTION);
    CDialog::OnNcCalcSize(bCalcValidRects, lpncsp);
}

void CMyDlg::OnMove(int x, int y) 
{
    CDialog::OnMove(x, y);
    
    // TODO: Add your message handler code here
    GetWindowRect(&m_rtWnd);
}

int CMyDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    this->ModifyStyle(WS_SYSMENU, 0);//防止在任务栏右单击时出现最大最小关闭.
    if (CDialog::OnCreate(lpCreateStruct) == -1)
        return -1;
    return 0;
}

void CMyDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) 
{
    CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
    
    // TODO: Add your message handler code here
    if(bSysMenu)
    {
        OnNcPaint();
    }
}


void CMyDlg::OnDestroy() 
{
    CDialog::OnDestroy();
    
    // TODO: Add your message handler code here
    m_bmpButtonMin.DeleteObject();
    m_bmpButtonMax.DeleteObject();
    m_bmpButtonExit.DeleteObject();
    m_bmpButtons.DeleteObject();
    m_bmpBorderLeft.DeleteObject();
    m_bmpBorderRight.DeleteObject();
    m_bmpBorderBottom.DeleteObject();
    m_bmpBorderBottom2.DeleteObject();
    m_bmpCaptionOver.DeleteObject();
    m_bmpButtonMinOver.DeleteObject();
    m_bmpButtonMaxOver.DeleteObject();
    m_bmpButtonMaxZoomed.DeleteObject();
    m_bmpButtonExitOver.DeleteObject();
}


 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值