重绘标题界面类

.h文件
 DrawAppearance  .h: interface for the CDrawAppearance   class.
//
//
/*
			|**************************************************|
			| 雄鹰的翅膀只有在凌空翱翔的时候才最美丽 -- Tercel |
			|--------------------------------------------------|   
			|      email:ChinaTianXiang@foxmail.com		   |                                                         
			|**************************************************|
*/
#if !defined(AFX_DRAWAPPEARANCE_H__D181D9FE_00B4_42F3_9432_37A4027770DD__INCLUDED_)
#define AFX_DRAWAPPEARANCE_H__D181D9FE_00B4_42F3_9432_37A4027770DD__INCLUDED_

#include "AFXWIN.H"	// Added by ClassView
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CDrawAppearance 
{
public:
	CDrawAppearance  ();
	virtual ~CDrawAppearance  (); 
private :
	WORD  m_wdFontH;			//标题字体高度	:0
	WORD  m_wdFontW;			//标题字体宽度	:0	
	WORD  m_wdSpace;			//控制系统按钮的距离:1
	
	UINT  m_unIDMInNor;			//系统按钮正常状态时的位图ID  在DrawStytemBtn函数中保存 :0
	UINT  m_unIDMaxNor;
	UINT  m_unIDResNor;
	UINT  m_unIDClsNor;	
	UINT  m_unIDMInDown;		//系统按钮按下状态时的位图ID  在NcLButtonDown函数中保存 :0
	UINT  m_unIDMaxDown;
	UINT  m_unIDResDown;
	UINT  m_unIDClsDown;
	
	
	BOOL  m_bRedrawWnd;			//标示整个窗口是否发生重绘,在DrawBtnBmp函数中判断 :FALSE
	BOOL  m_bDownMin;			//标示按钮是否处于按下状态 
	BOOL  m_bDownMax;
	BOOL  m_bDownCls;
	
	CRect m_rtMinBtn;			//保存系统按钮的位置 :NULL
	CRect m_rtMaxBtn;
	CRect m_rtCloseBtn;	
		
	COLORREF m_clrTitle;		//标题颜色 :RGB(255,255,255)
protected:
	void LButtonUP(HWND hWnd, CPoint point);
	
	void NcMouseMove(HWND hWnd, CPoint point, UINT nIDClose, UINT nIDMax, UINT nIDRestore, UINT nIDMin);  
	
	void NcLButtonDblClk(HWND hWnd, CPoint point);
	
	BOOL NcLButtonDown(HWND hWnd, CPoint point, UINT nIDClose, UINT nIDMax, UINT nIDRestore, UINT nIDMin);
	
	BOOL NcLButtonUp(HWND hWnd, CPoint point);
	
	BOOL TransparentBlt(HDC hdcDest,int nXOriginDest,int nYOriginDest,int nWidthDest,int nHeightDest,HDC hdcSrc,
			int nXOriginSrc,int nYOriginSrc,int nWidthSrc,int nHeightSrc,UINT crTransparent);	
	
	CRect GetTitleBarRect(CDC *pWinDC);											//获得标题栏矩形
	
	CRect DrawBtnBmp(CDC *pWinDC, UINT nIDBmp, CRect rect=NULL);					
public:
	void SetTitleFontSize(WORD nFontW,WORD nFontH);								//设置标题字体
	
	void SetTitleColor(COLORREF clrTitle);										//设置标题颜色

	BOOL DrawIcon(CDC *pWinDC,UINT idIcon,int nLeftSpace);					
	
	BOOL DrawTitle(CDC *pWinDC,CString strTitle,int nLeftSpace);				//绘制窗口标题
	
	BOOL DrawTitleBar(CDC *pWinDC,COLORREF clrTop,COLORREF clrBottom);			//绘制标题栏
	
	BOOL DrawBorder(CDC *pWinDC,COLORREF color,int nLefOffset=0,int nTopOffset=0,int nRitOffset=0,int nBtmOffset=0);
	
	BOOL InterceptMessage(UINT msg,HWND hWnd,CPoint point,UINT nIDClose=0,UINT nIDMax=0,UINT nIDRestore=0,UINT nIDMin=0);
	
	BOOL DrawSystemBtn(CDC *pWinDC,UINT nIDClose=0,UINT nIDMax=0,UINT nIDRestore=0,UINT nIDMin=0);
	
	BOOL DrawBackground(CDC *pWinDC,CRect *pDesRect,COLORREF clrBrush,UINT nIDBitmap,BOOL bCenter=FALSE,
			BOOL bTransparent=FALSE,COLORREF clrTransparent=0);					
};

#endif // !defined(AFX_DRAWAPPEARANCE_H__D181D9FE_00B4_42F3_9432_37A4027770DD__INCLUDED_)
.cpp文件
 
// DrawAppearance  .cpp: interface for the CDrawAppearance   class.
//
//
#include "stdafx.h"
#include "DrawAppearance.h"

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

CDrawAppearance ::CDrawAppearance ()
{
	m_clrTitle=RGB(255,255,255);
	m_wdFontW = 0;
	m_wdFontH = 0;
	m_wdSpace = 1;
	
	m_rtMaxBtn=NULL;
	m_rtMinBtn=NULL;
	m_rtCloseBtn=NULL;

	m_unIDMInNor=0;
	m_unIDClsNor=0;
	m_unIDMaxNor=0;
	m_unIDResNor=0;

	m_unIDMInDown=0;
	m_unIDClsDown=0;
	m_unIDMaxDown=0;
	m_unIDResDown=0;
	
	m_bDownMin=FALSE;
	m_bDownMax=FALSE;
	m_bDownCls=FALSE;
	
	m_bRedrawWnd=FALSE;
}

CDrawAppearance ::~CDrawAppearance ()
{

}
/************************************************************************/
/* 功能:绘制窗口边框
/*-------------------------------------------------------------------
/* 参数:CDC	  *pWinDC		---- 窗口 DC    
/*		 COLORREF color			---- 边框颜色	
/*		 int	  nLefOffset	---- 左 :0 (调整边框的粗细 +n 或 -n)
/*		 int	  nTopOffset	---- 上 :0
/*		 int	  nRitOffset	---- 右	:0
/*		 int	  nBtmOffset	---- 下	:0
/*-------------------------------------------------------------------
/* 返回:成功返回 TRUE   DC无效返回FALSE	
/*-------------------------------------------------------------------
/* 注  :本DC是利用GetWindowDC()获得 不是GetDC()
/*		 
/* GetWindowDC(): 获得整个窗口的DC     GetDC(): 获得客户区域DC
/*
/************************************************************************/
BOOL CDrawAppearance ::DrawBorder(CDC *pWinDC,COLORREF color,int nLefOffset,int nTopOffset,int nRitOffset,int nBtmOffset)
{
	if(!pWinDC)
	{	//AfxMessageBox("窗口不存在!",MB_ICONASTERISK);
		return FALSE; 
	}

	CBrush Brush(color);								// 创建一个画刷对象
    CBrush* pOldBrush = pWinDC->SelectObject(&Brush);	// 载入指定颜色的画刷
	
    CRect rtWnd;
    pWinDC->GetWindow()->GetWindowRect(&rtWnd);			//获得窗口矩形

    CPoint point;
    //填充顶部框架
    point.x = rtWnd.Width();							
    point.y = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) + nTopOffset;	
    pWinDC->PatBlt(0, 0, point.x, point.y, PATCOPY);
    //填充左侧框架
    point.x = GetSystemMetrics(SM_CXFRAME) + nLefOffset;			
    point.y = rtWnd.Height();
    pWinDC->PatBlt(0, 0, point.x, point.y, PATCOPY);
    //填充底部框架
    point.x = rtWnd.Width(); 
    point.y = GetSystemMetrics(SM_CYFRAME) + nBtmOffset;
    pWinDC->PatBlt(0, rtWnd.Height()-point.y, point.x, point.y, PATCOPY);
    //填充右侧框架
    point.x = GetSystemMetrics(SM_CXFRAME) + nRitOffset;
    point.y = rtWnd.Height();
    pWinDC->PatBlt(rtWnd.Width()-point.x, 0, point.x, point.y, PATCOPY);

	return TRUE;
}

/************************************************************************/
/* 功能:绘制标题栏
/*------------------------------------------------
/* 参数:CDC	  *pWinDC		---- 窗口DC
		 COLORREF clrTop		---- 标题栏顶部颜色	
		 COLORREF clrBottom		---- 标题栏底部颜色
/*------------------------------------------------		
/* 返回:成功返回 TRUE   DC无效返回FALSE
/*------------------------------------------------
/* 注  :本DC是利用GetWindowDC()获得 不是GetDC()
/************************************************************************/
BOOL CDrawAppearance ::DrawTitleBar(CDC *pWinDC, COLORREF clrTop, COLORREF clrBottom)
{
	if (!pWinDC)
		return FALSE;

	CPen Pen; 
	CRect  rtWnd,rtTitle; 

	::GetWindowRect(pWinDC->GetWindow()->m_hWnd,&rtWnd);		//整个Window的相对于屏幕的矩形 
	rtTitle=GetTitleBarRect(pWinDC);

	rtTitle.left -=10;											//修改尺寸
	rtTitle.top	 -=10;
	rtTitle.right+=10;

	CPen* pOldPen=pWinDC-> SelectObject(&Pen);					//选入画笔

	int R,G,B; 
	R=(GetRValue(clrTop)-GetRValue(clrBottom))/rtTitle.Height();//颜色差值
	G=(GetGValue(clrTop)-GetGValue(clrBottom))/rtTitle.Height(); 
	B=(GetBValue(clrTop)-GetBValue(clrBottom))/rtTitle.Height(); 
	
	int ColR = GetRValue(clrTop),ColG= GetGValue(clrTop),ColB=GetBValue(clrTop); 
	
	for (int i=0;i<rtTitle.Height();i++)					//控制表面的光亮,从矩形的上面开始画横线,一直画 
	{ 
		ColR -= R;											//到矩形的底部,而且颜色逐渐变深 
		ColG -= G; 
		ColB -= B; 

		Pen.DeleteObject(); 
		Pen.CreatePen(PS_SOLID,2,RGB(ColR,ColG,ColB));		//创建画笔
		pWinDC-> SelectObject(&Pen); 

		pWinDC-> MoveTo(rtTitle.left,rtTitle.top+i);		//画线
		pWinDC-> LineTo(rtTitle.right,rtTitle.top+i); 
	} 
	
	pWinDC-> SelectObject(pOldPen);

	return TRUE;
}

/************************************************************************/
/* 功能:绘制窗口图标
/*---------------------------------------------------------
/* 参数:CDC  *pWinDC		---- 窗口DC
		 UINT idIcon		---- 图标ID
		 int  nLeftSpace	---- 图标目标位置与标题栏左边距离
/*----------------------------------------------------------		
/* 返回:成功返回 TRUE   DC无效返回NULL
/*----------------------------------------------------------
/* 注  :本DC是利用GetWindowDC()获得 不是GetDC()
/************************************************************************/
BOOL CDrawAppearance ::DrawIcon(CDC *pWinDC, UINT idIcon, int nLeftSpace)
{
	if (!pWinDC)
		return NULL;

	CRect rtIcon;										
	CRect rtTitle=GetTitleBarRect(pWinDC);						
	
	rtIcon.left =rtTitle.left + nLeftSpace;					//调整图标矩形
	rtIcon.top	=rtTitle.top; 
	rtIcon.right=rtIcon.left+rtTitle.bottom-5;
	rtIcon.bottom=rtIcon.top+rtTitle.bottom-5;
								
	::DrawIconEx(pWinDC->m_hDC,rtIcon.left,rtIcon.top, AfxGetApp()->LoadIcon(idIcon), //绘制图标
		rtIcon.Width(), rtIcon.Height(), 0, NULL,DI_NORMAL);
	return TRUE;
}

/************************************************************************/
/* 功能:获得标题栏矩形区域
/************************************************************************/
CRect CDrawAppearance ::GetTitleBarRect(CDC *pWinDC)
{
	if (!pWinDC)
	{	AfxMessageBox("窗口不存在!",MB_ICONASTERISK);
		return NULL; 
	}
	
	CRect rtTitle;
	CRect rtWnd;

	GetWindowRect(pWinDC->GetWindow()->m_hWnd,&rtWnd);		//整个Window的相对于屏幕的矩形 

	rtTitle.left = GetSystemMetrics(SM_CXFRAME); 			//取得整个Title bar的矩形 
	rtTitle.top  = GetSystemMetrics(SM_CYFRAME); 
	rtTitle.right= rtWnd.Width() - GetSystemMetrics(SM_CXFRAME);
	rtTitle.bottom=rtTitle.top + GetSystemMetrics(SM_CYSIZE);
	return rtTitle;
}

/************************************************************************/
/* 功能:绘制窗口标题
/*--------------------------------------------------------
/* 参数:CDC	 *pWinDC	---- 窗口DC
/*		 CString strTitle	---- 标题文本
/*		 int	 nLeftSpace	---- 标题左边与标题栏左边的距离
/*--------------------------------------------------------
/* 返回:成功返回 TRUE   DC无效返回NULL
/*--------------------------------------------------------
/* 注  :本DC是利用GetWindowDC()获得 不是GetDC()
/************************************************************************/
BOOL CDrawAppearance ::DrawTitle(CDC *pWinDC, CString strTitle, int nLeftSpace)
{	
	if (!pWinDC)
		return FALSE;

	CFont font;										
	CFont *pOldFont;
	
	int nOldMode = pWinDC->SetBkMode(TRANSPARENT);			//文字透明显示
	COLORREF clOldText=pWinDC->SetTextColor(m_clrTitle);	//设置文本颜色
	
	font.CreateFont(m_wdFontH,m_wdFontW,0,0,0,FALSE,FALSE,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
		DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,_T("楷体_GB2312"));//创建字体
	pOldFont=pWinDC->SelectObject(&font);					//选入字体
	
	//pWinDC->SelectStockObject(OEM_FIXED_FONT);			//选入字体

	CRect rtTitle=GetTitleBarRect(pWinDC);					//获得标题栏矩形

	rtTitle.left += nLeftSpace;								//标题输出位置

	if (m_wdFontH<=0)	
		rtTitle.top +=rtTitle.top/2;
	else
		rtTitle.top +=(rtTitle.Height()-m_wdFontH)/2-1;		//-1是因为有些偏差

	pWinDC->DrawText(strTitle, &rtTitle, DT_LEFT);			//绘制标题
	pWinDC->SetBkMode(nOldMode);							//恢复
	pWinDC->SetTextColor(clOldText);					
	pWinDC->SelectObject(pOldFont);
	
	return TRUE;			
}

/************************************************************************/
/* 功能:绘制窗口背景
/*-----------------------------------------------------------------------
/* 参数:CDC		*pWinDC,	    ---- 窗口DC		
/*		 CRect		*pDesRect,		---- 目标矩形区域
/*		 COLORREF	clrBrush,		---- 背景画刷,为NULL不设置
/*		 UINT		unIDBitmap,		---- 背景位图,为NULL不设置  
/*		 BOOL		bCenter,		---- 是否居中显示,默认TRUE : FALSE
/*		 BOOL		bTransparent,	---- 位图是否透明显示 :FALSE
/*		 COLORREF	clrTransparent	---- 将要透明的颜色	  :0
/*-----------------------------------------------------------------------
/* 返回:bSet	----返回函数是否执行成功	
/*-----------------------------------------------------------------------
/* 注  :****此DC使用 GetDC()获得*****
/*-----------------------------------------------------------------------				
/* 本函数主要是用于添加文档类背景,如果是对话框修改背景可以在OnCtrlColor中
/*
/* 重新创建画刷 (可以是位图画刷),但本函数可以实现位图居中显示与透明显示,
/* 
/* 可以更灵活的绘制位图与画刷,但如果透明显示时改变了位图大小,位图会失真。
/* 
/************************************************************************/
BOOL CDrawAppearance ::DrawBackground(CDC *pWinDC, CRect *pDesRect, COLORREF clrBrush, UINT unIDBitmap,
									  BOOL bCenter,BOOL bTransparent,COLORREF clrTransparent)	
{
	BOOL bSet=FALSE;									//返回值		
	if (pWinDC==NULL && !IsWindow(pWinDC->GetWindow()->m_hWnd))
	{	AfxMessageBox("无效的DC,或窗口不存在!",MB_ICONASTERISK);
		return NULL;
	}

	if (clrBrush!=NULL)									//设置背景画刷
	{	
		CBrush brush(clrBrush);							
		CBrush *pOldBrush=pWinDC->SelectObject(&brush);	
		bSet=pWinDC->PatBlt(pDesRect->left,pDesRect->top,pDesRect->Width(),pDesRect->Height(),PATCOPY);
		pWinDC->SelectObject(pOldBrush);					
		pOldBrush->DeleteObject();
	}	
	if (unIDBitmap!=NULL)								//设置背景位图
	{
		BOOL	bZoom=FALSE;
		CDC		dcMem;												
		BITMAP	bmOriginal;
		BITMAP	bmNew;
		CBitmap bitmap;
		int x,y,nWidth,nHeight;
		
		dcMem.CreateCompatibleDC(pWinDC);
		
		if (!bitmap.LoadBitmap(unIDBitmap))				//载入位图
		{
			AfxMessageBox("Load bitmap failure!\r\rThe bitmap exist?",MB_ICONERROR|MB_OK);
			return bSet;
		}
		
		bitmap.GetBitmap(&bmOriginal);					//获得位图尺寸
		CBitmap *pOldBitmap=dcMem.SelectObject(&bitmap);
		
		double dBitmapWidth  = bmOriginal.bmWidth;
		double dBitmapHeight = bmOriginal.bmHeight;
		double dBitmapRatio=dBitmapWidth/dBitmapHeight;	//图像宽高比
		
		if (pDesRect->Width()<bmOriginal.bmWidth)		//如果目标矩形宽小于位图宽
		{	
			bmNew.bmWidth  = (int)(pDesRect->Width()/dBitmapWidth*dBitmapHeight);	
			bmNew.bmHeight = (int)(bmNew.bmWidth/dBitmapRatio);
			bZoom = TRUE;
		}
		else if(pDesRect->Height()<bmOriginal.bmHeight) //如果目标矩形高小于位图高
		{	
			bmNew.bmHeight = (int)(pDesRect->Height()/dBitmapWidth*dBitmapHeight);
			bmNew.bmWidth  = (int)(bmNew.bmHeight*dBitmapRatio);
			bZoom = TRUE;
		}
		else
			bmNew=bmOriginal;							//否则位图大小不变
		
		if (bCenter)
		{	
			x=(pDesRect->Width()-bmNew.bmWidth)/2;		//图像居中显示
			y=(pDesRect->Height()-bmNew.bmHeight)/2;	
			nWidth =bmNew.bmWidth;
			nHeight=bmNew.bmHeight;
		}
		else
		{
			x=pDesRect->left;							//图像填充来整个目标矩形
			y=pDesRect->top;
			nWidth =pDesRect->Width();					
			nHeight=pDesRect->Height();
		}
		
		pWinDC->SetStretchBltMode(HALFTONE);			//设置图像平滑显示 
		if(bTransparent&& !bZoom && bCenter)
			bSet=TransparentBlt(pWinDC->m_hDC,x,y,nWidth,nHeight,dcMem.m_hDC,0,0,bmOriginal.bmWidth,bmOriginal.bmHeight,
							clrTransparent);			//拷贝位图
		else
			bSet=pWinDC->StretchBlt(x,y,nWidth,nHeight,&dcMem,0,0,bmOriginal.bmWidth,bmOriginal.bmHeight,SRCCOPY);//拷贝位图
		
		dcMem.SelectObject(pOldBitmap);					//恢复默位图
		dcMem.DeleteDC();								//释放DC
	}					
	return bSet;
}

/************************************************************************/
/*功能:位图透明显示
/*--------------------------------------------------
/*参数:HDC		hdcDest,		---- 目标DC
/*		int		nXOriginDest,   ---- 目标X偏移
/*		int		nYOriginDest,   ---- 目标Y偏移
/*		int		nWidthDest,     ---- 目标宽度
/*		int		nHeightDest,    ---- 目标高度
/*		HDC		hdcSrc,         ---- 源DC
/*		int		nXOriginSrc,    ---- 源X起点
/*		int		nYOriginSrc,    ---- 源Y起点
/*		int		nWidthSrc,      ---- 源宽度
/*		int		nHeightSrc,     ---- 源高度
/*		UINT	crTransparent   ---- 透明色,COLORREF类型
/*---------------------------------------------------
/*返回:成功返回真 		
/************************************************************************/
BOOL CDrawAppearance ::TransparentBlt( HDC hdcDest,int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
					   HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, UINT crTransparent)
{
	HBITMAP hOldImageBMP, hImageBMP;
	hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest);	// 创建兼容位图
	
	HBITMAP hOldMaskBMP, hMaskBMP;
	hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);			// 创建单色掩码位图

	HDC		hImageDC = CreateCompatibleDC(hdcDest);
	HDC		hMaskDC = CreateCompatibleDC(hdcDest);

	hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);
	hOldMaskBMP =  (HBITMAP)SelectObject(hMaskDC, hMaskBMP);

	// 将源DC中的位图拷贝到临时DC中
	if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
		BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
	else
		StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, 
					hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);

	// 设置透明色
	SetBkColor(hImageDC, crTransparent);

	// 生成透明区域为白色,其它区域为黑色的掩码位图
	BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);

	// 生成透明区域为黑色,其它区域保持不变的位图
	SetBkColor(hImageDC, RGB(0,0,0));
	SetTextColor(hImageDC, RGB(255,255,255));
	BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

	// 透明部分保持屏幕不变,其它部分变成黑色
	SetBkColor(hdcDest,RGB(255,255,255));
	SetTextColor(hdcDest,RGB(0,0,0));
	BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

	// "或"运算,生成最终效果
	BOOL bResult=BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);

	// 清理、恢复	
	SelectObject(hImageDC, hOldImageBMP);
	DeleteDC(hImageDC);
	SelectObject(hMaskDC, hOldMaskBMP);
	DeleteDC(hMaskDC);
	DeleteObject(hImageBMP);
	DeleteObject(hMaskBMP);
	return bResult;
}

/************************************************************************/
/*功能:设置标题的颜色
/*--------------------
/*注  :在绘制之前设置
/************************************************************************/
void CDrawAppearance ::SetTitleColor(COLORREF clrTitle)
{
	m_clrTitle=clrTitle;
}

/************************************************************************/
/*功能:设置标题字体大小
/*-----------------------
/*参数:宽度、高度
/*-----------------------
/*注  :在绘制之前设置
/************************************************************************/
void CDrawAppearance ::SetTitleFontSize(WORD wdFontW, WORD wdFontH)
{
	m_wdFontW=wdFontW;
	m_wdFontH=wdFontH;
}

/************************************************************************/
/* 功能:获得按钮位图ID,调用绘图函数进行绘制,保存按钮位置
/*---------------------------------------------------------
/* 参数:CDC  *pWinDC		---- 窗口DC
/*		 UINT unIDClose 	---- 各个按钮的位图ID 默认值:0
/*		 UINT unIDMax			 
/*		 UINT unIDRestore		 
/*       UINT unIDMin		
/*---------------------------------------------------------
/* 返回:成功返回-TRUE   DC无效返回-NULL
/*---------------------------------------------------------
/* 注  :本DC是利用GetWindowDC()获得 不是GetDC()
/************************************************************************/
BOOL CDrawAppearance ::DrawSystemBtn(CDC *pWinDC, UINT unIDClose, UINT unIDMax, UINT unIDRestore, UINT unIDMin)
{
	if (!pWinDC)
		return FALSE;
	
	m_bRedrawWnd=TRUE;		

	m_rtCloseBtn = DrawBtnBmp(pWinDC,unIDClose);		//绘制位图并保存位置

	if (pWinDC->GetWindow()->IsZoomed())			
		m_rtMaxBtn = DrawBtnBmp(pWinDC,unIDRestore);
	else
		m_rtMaxBtn = DrawBtnBmp(pWinDC,unIDMax);

	m_rtMinBtn = DrawBtnBmp(pWinDC,unIDMin);

	m_wdSpace = 0;									//全部绘制完毕后要清0

	m_unIDMaxNor = unIDMax;							//保存位图ID
	m_unIDMInNor = unIDMin;
	m_unIDClsNor = unIDClose;
	m_unIDResNor = unIDRestore;

	return TRUE;
}	

/************************************************************************/
/* 功能:绘制按钮位图
/*-----------------------------------------------------------
/* 参数:CDC   *pWinDC		---- 窗口DC
/*		 UINT  unIDBmp 		---- 位图ID
/*		 CRect rect			---- 在MouseMove时,传递保存的位置			
/*-----------------------------------------------------------
/* 返回:成功返回按钮位置   位图ID无效返回-NULL
/*-----------------------------------------------------------
/* 注  :本DC是利用GetWindowDC()获得 不是GetDC()
/************************************************************************/
CRect CDrawAppearance ::DrawBtnBmp(CDC *pWinDC, UINT unIDBmp, CRect rect)
{
	if (unIDBmp==0)
		return NULL;
	
	CDC		MemDC;
	BITMAP  bmSrc;
	CBitmap	Bitmap,*pOldBitmap;;
	CRect rtButton;
	CRect rtWnd;
	CRect rtTitle=GetTitleBarRect(pWinDC);						//获得标题栏矩形

	MemDC.CreateCompatibleDC(pWinDC);							//创建兼容DC

	Bitmap.LoadBitmap(unIDBmp);									//载入位图
	Bitmap.GetBitmap(&bmSrc);									//获得位图尺寸
	pOldBitmap=MemDC.SelectObject(&Bitmap);						//选入DC

	GetWindowRect(pWinDC->GetWindow()->m_hWnd,&rtWnd);			//整个Window的相对于屏幕的矩形 
	
	if (m_bRedrawWnd)											//如果发生重绘,需要重新计算按钮位置
	{
		if (bmSrc.bmHeight<rtTitle.Height())
		{	
			rtButton.left = rtTitle.right-bmSrc.bmWidth-m_wdSpace;	
			rtButton.right= rtTitle.right-m_wdSpace;
			rtButton.top  = rtTitle.top+(rtTitle.Height()-bmSrc.bmHeight)/2-2;
			rtButton.bottom = rtButton.top+bmSrc.bmHeight;		//设置按钮位置
		}
		else
		{	
			rtButton.bottom = rtTitle.bottom-3;					//调整目标位图大小、位置	
			rtButton.top  = rtTitle.top+1;						//此时就可以得到目标位图高
			
			int nW=bmSrc.bmWidth-(bmSrc.bmHeight-rtButton.Height()); //原位图宽-(原位图高-目标位图高) = 目标位图宽 
		 	
			rtButton.right = rtTitle.right-m_wdSpace;				
			rtButton.left  = rtTitle.right-nW-m_wdSpace;			 	
		}
	}
	else														//未发生重绘,使用保存按钮的位置
	{
		rect.OffsetRect(-rtWnd.left,-rtWnd.top);
		rtButton=rect;
	}
	
	if (bmSrc.bmHeight<rtTitle.Height())
		pWinDC->BitBlt(rtButton.left,rtButton.top,bmSrc.bmWidth,bmSrc.bmHeight,&MemDC,0,0,SRCCOPY);
	else
	{	
		pWinDC->SetStretchBltMode(HALFTONE);					//设置图像平滑显示
		pWinDC->StretchBlt(rtButton.left, rtButton.top, rtButton.Width(), rtButton.Height(), &MemDC, 
			0, 0,bmSrc.bmWidth,bmSrc.bmHeight,SRCCOPY);	
	}
	
	m_wdSpace=rtTitle.right-rtButton.left+1;					//每次加上之前位图的宽度并+1分隔按钮

	MemDC.SelectObject(pOldBitmap);								//选入原始位图
	MemDC.DeleteDC();											//释放DC、资源
	DeleteObject(&Bitmap);

	rtButton.OffsetRect(rtWnd.TopLeft());						//由于rtButton存储的矩形对于窗口区域的
																//而我们要保存的是相对于屏幕的
	return rtButton;											
}

/************************************************************************/
/* 功能:截获消息、并判断消息类型,调用相应函数进行处理
/*---------------------------------------------------------------------
/* 参数:UINT   msg			---- 指定当前截获的消息类型
/*		 HWND   hWnd 		---- 窗口句柄,this->m_hWnd
/*		 CPoint point		---- 消息发生时Mouse所在位置
/*		 UINT   unIDClose	---- 不同消息要传递不同的位图
/*		 UINT   unIDMax			 鼠标移动时传递热点的位图
/*		 UINT   unIDRestore	     鼠标按下时传递按下的位图
/*		 UINT   unIDMin			 4个参数默认值 : 0
/*----------------------------------------------------------------------
/* 返回:如果传递的消息正确返回 TRUE    否则 FALSE
/*----------------------------------------------------------------------
/* 注  :msg 可传递MFC提供的标准消息,无需自定义			
/*		 
/*		 在以下列出的对话框的消息响应中添加此函数
/************************************************************************/
BOOL CDrawAppearance ::InterceptMessage(UINT msg, HWND hWnd, CPoint point, UINT unIDClose, 
										UINT unIDMax, UINT unIDRestore, UINT unIDMin)
{	
	BOOL bResult;
	m_bRedrawWnd=FALSE;
	switch (msg)
	{
	case WM_LBUTTONDOWN:
		LButtonUP(hWnd,point);
		break;
	case WM_NCMOUSEMOVE:
		NcMouseMove(hWnd, point, unIDClose, unIDMax, unIDRestore, unIDMin);
		break;
	case WM_NCLBUTTONDOWN:
		bResult = NcLButtonDown(hWnd, point, unIDClose, unIDMax, unIDRestore, unIDMin);
		break;
	case WM_NCLBUTTONUP:
		bResult = NcLButtonUp(hWnd, point);
		break;
	case WM_NCLBUTTONDBLCLK:
		NcLButtonDblClk(hWnd, point);
		break;
	default:
		bResult = FALSE;
		break;
	}	

	m_wdSpace=0; //清0 否则影响下一次绘图

	return bResult;
}

/************************************************************************/
/*功能:绘制LButtonDown时的按钮位图
/*------------------------------------------------
/*参数:同上
/*------------------------------------------------		
/*返回:如果鼠标在按钮区域返回 TRUE  否则返回 FALSE (可调用默认函数处理)
/************************************************************************/
BOOL CDrawAppearance ::NcLButtonDown(HWND hWnd, CPoint point, UINT unIDClose, UINT unIDMax, UINT unIDRestore, UINT unIDMin)
{
	m_unIDMInDown = unIDMin;		//保存按下时的位图
	m_unIDClsDown = unIDClose;
	m_unIDMaxDown = unIDMax;
	m_unIDResDown = unIDRestore;

	CDC *pWinDC=CDC::FromHandle(GetWindowDC(hWnd));

	if (m_rtMaxBtn.PtInRect(point))	
	{	
		m_bDownMax = TRUE;
		if (IsZoomed(hWnd))
			DrawBtnBmp (pWinDC, unIDRestore, m_rtMaxBtn);
		else
			DrawBtnBmp (pWinDC, unIDMax, m_rtMaxBtn);					
	}
	else if (m_rtCloseBtn.PtInRect(point))	
	{
		m_bDownCls = TRUE;
		DrawBtnBmp (pWinDC, unIDClose, m_rtCloseBtn);
	}
	else if (m_rtMinBtn.PtInRect(point))
	{
		m_bDownMin = TRUE;
		DrawBtnBmp (pWinDC, unIDMin, m_rtMinBtn);
	}
	else	
		return FALSE;

	return TRUE;
}

/************************************************************************/
/*功能:双击标题栏大化与恢复窗口
/*------------------------------------------------
/*参数:同上
/************************************************************************/
void CDrawAppearance ::NcLButtonDblClk(HWND hWnd, CPoint point)
{
	if  (IsZoomed(hWnd))
		SendMessage(hWnd,WM_SYSCOMMAND,SC_RESTORE,MAKELPARAM(point.x,point.y));
	else 
	{	
		SendMessage(hWnd,WM_SYSCOMMAND,SC_MAXIMIZE,MAKELPARAM(point.x,point.y));									
	
		CRect rect;
		
		HWND hwTaskbar=FindWindow("Shell_TrayWnd","");		// 获得任务栏窗口句柄			
	
		GetWindowRect(hwTaskbar,&rect);			// 任务栏矩形
		
		int nHeight=rect.Height();  			// 任务栏的高度	
		
		GetWindowRect(hWnd,&rect);

		MoveWindow(hWnd,rect.left,rect.top,rect.Width(),rect.Height()-nHeight,TRUE);//改变窗口高度,否则盖住任务栏	
	};
}

/************************************************************************/
/*功能:鼠标移动到按钮位置绘制热点位图,否则绘制正常状态时位图
/*-----------------------------------------------------------
/*参数:同上
/************************************************************************/
void CDrawAppearance ::NcMouseMove(HWND hWnd, CPoint point,UINT unIDClose, UINT unIDMax, UINT unIDRestore, UINT unIDMin)
{

	CDC *pWinDC= CDC::FromHandle(GetWindowDC(hWnd));			
	BOOL bDown = m_bDownMax || m_bDownMin || m_bDownCls;		// 得出是否有按钮处于按下状态
	 
	if ( m_rtMaxBtn.PtInRect(point) )
	{	
		if( bDown && !m_bDownMax )								// 如果处于按下状态但并不是此按钮返回,如果bDown为FALSE说
				return;											// 明没有按钮被按下,此时m_bDownMax也一定不会是TRUE,那么
		 														// 可以绘制热点状态时的位图,以下同理
		if ( IsZoomed(hWnd) )	
		{	
			if (m_bDownMax)								
				DrawBtnBmp(pWinDC, m_unIDResDown, m_rtMaxBtn);    
			else
				DrawBtnBmp(pWinDC, unIDRestore, m_rtMaxBtn);
		}
		else
		{
			if (m_bDownMax)
				DrawBtnBmp(pWinDC, m_unIDMaxDown, m_rtMaxBtn); 
			else
				DrawBtnBmp(pWinDC, unIDMax, m_rtMaxBtn); 
		}
	}
	else
	{
		if (IsZoomed(hWnd))
			DrawBtnBmp(pWinDC, m_unIDResNor, m_rtMaxBtn);
		else
			DrawBtnBmp(pWinDC, m_unIDMaxNor, m_rtMaxBtn); 
	}
	

	if (m_rtCloseBtn.PtInRect(point))	
	{
		if( bDown && !m_bDownCls )
				return;
		if (m_bDownCls)
			DrawBtnBmp(pWinDC, m_unIDClsDown, m_rtCloseBtn);
		else
			DrawBtnBmp(pWinDC, unIDClose, m_rtCloseBtn);
	}
	else
		DrawBtnBmp(pWinDC, m_unIDClsNor, m_rtCloseBtn);


	if (m_rtMinBtn.PtInRect(point))
	{
		if( bDown && !m_bDownMin )
				return;
		if (m_bDownMin)
			DrawBtnBmp(pWinDC, m_unIDMInDown, m_rtMinBtn);
		else
			DrawBtnBmp(pWinDC, unIDMin, m_rtMinBtn);
	}
	else
		DrawBtnBmp(pWinDC, m_unIDMInNor, m_rtMinBtn);	
}

/************************************************************************/
/*功能:各窗口发送相应消息
/*------------------------------------------------
/*参数:同上
/*------------------------------------------------		
/*返回:如果鼠标在按钮区域返回 TRUE  否则返回 FALSE (可调用默认函数处理)
/************************************************************************/
BOOL CDrawAppearance ::NcLButtonUp(HWND hWnd, CPoint point)
{
	BOOL bDown = m_bDownMax || m_bDownMin || m_bDownCls, bResult=TRUE;	//得出是否有按钮处于按下状态
	
	if ( !bDown )	//没有返回
	{	return FALSE; }
 
	CDC *pWinDC=CDC::FromHandle(GetWindowDC(hWnd));						
	
	if ( m_rtMaxBtn.PtInRect(point) && m_bDownMax)						//如果在按钮范围而且之前有被按下
	{	
		if (IsZoomed(hWnd))
			SendMessage(hWnd,WM_SYSCOMMAND,SC_RESTORE,MAKELPARAM(point.x,point.y));
		else
		{	SendMessage(hWnd,WM_SYSCOMMAND,SC_MAXIMIZE,MAKELPARAM(point.x,point.y));	
			CRect rtWnd;	
			CRect rtTask;		
			
			HWND hwTaskbar=FindWindow("Shell_TrayWnd","");				//获得任务栏窗口句柄
			
			GetWindowRect(hwTaskbar,&rtTask);							//任务栏矩形				
			GetWindowRect(hWnd,&rtWnd);									//窗口矩形				
			
			//改变窗口高度,否则盖住任务栏
			SetWindowPos(hWnd,NULL,0,0,rtWnd.Width(),rtWnd.Height()-rtTask.Height(),SWP_NOMOVE);
		}
	}
	else if (m_rtCloseBtn.PtInRect(point) && m_bDownCls)
	{	
		SendMessage(hWnd,WM_CLOSE,0,0);
	}
	else if (m_rtMinBtn.PtInRect(point) && m_bDownMin)
	{	
		SendMessage(hWnd,WM_SYSCOMMAND,SC_MINIMIZE,MAKELPARAM(point.x,point.y));
	}
	else
		bResult=FALSE;

	m_bDownCls = FALSE;		//全部置为抬起状态
	m_bDownMax = FALSE;
	m_bDownMin = FALSE;	
	return bResult;		
}

/************************************************************************/
/*功能:鼠标抬起时标示系统按钮为抬起状态
/*------------------------------------------------
/*参数:同上。可以传递NULL (也可自定义用途)
/************************************************************************/
void CDrawAppearance::LButtonUP(HWND hWnd, CPoint point)
{
	m_bDownCls = FALSE;		//全部置为抬起状态
	m_bDownMax = FALSE;
	m_bDownMin = FALSE;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值