【界面设计】对话框非客户区窗口自绘

 

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

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

 

///////////////////////////////////////////////////////////////////////////

以下为源代码: 第一部分,头文件

// 对话框非客户区自绘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();
}



posted @ 2011-11-03 13:53  陈昂  阅读(2388)  评论(0编辑  收藏  举报