8.VC(ui)-自绘对话框基类

所有的对话框都是基于CDialog的,也就都具有CDialog的特征,本文以CDialog为基类派生一个新的类CSkinDialogBase,只需将基于CDialog的对话框中CDialog替换成CSkinDialogBase,则可具有自绘DLG的特征.

下面例子是自己重绘了非客户区及客户区底色完成的一个圆角Dialog的基类,直接上图:

实现步骤:

1.派生自CDialog的类CSkinDialogBase,这时系统会自动生成一个DLG资源,把enum { IDD = ...};删除掉,重载CSkinDialogBase的构造函数:

CSkinDialogBase::CSkinDialogBase(UINT nIDD,CWnd *pParent) : CDialog(nIDD,pParent) { }

记得把原来默认的构造函数删除掉

2.在OnNcCalcSize中定义非客户区边框的size,这里用到的绘制边框的图片都是6*5的,所以设置如下:

void CSkinDialogBase::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp) { lpncsp->rgrc[0].left+=6; lpncsp->rgrc[0].top+=5; lpncsp->rgrc[0].right-=6; lpncsp->rgrc[0].bottom-=5; }

3.在OnNcHitTest中设置CAPTION的size,将客户区一部分映射为非客户区,以便拖动。

LRESULT CSkinDialogBase::OnNcHitTest(CPoint point) { CPoint p(point) ; ScreenToClient(&p) ; if (p.y>=0&&p.y<=20) return HTCAPTION ; return CDialog::OnNcHitTest(point); }

4.将客户区颜色刷为和非客户区绘制一样的颜色,这里为RGB(240,240,240),有两种实现方式,在OnEraseBkgnd中和在OnCtlColor均可实现

BOOL CSkinDialogBase::OnEraseBkgnd(CDC* pDC) { CRect rcClient; CBrush brushBkgrnd(RGB(240,240,240)); GetWindowRect(&rcClient); ScreenToClient(&rcClient); pDC->FillRect(&rcClient, &brushBkgrnd); return TRUE; }

HBRUSH CSkinDialogBase::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); static CBrush brushDialog(RGB(240,240,240)); if (nCtlColor == CTLCOLOR_DLG) { return brushDialog; } return hbr; }

 

 5.绘制非客户区,这里必须用CWindowDC来绘制

CWindowDC mdc(this); CDC dcMemory; dcMemory.CreateCompatibleDC(&mdc); CRect rcWnd; GetWindowRect(&rcWnd); rcWnd.OffsetRect(-rcWnd.TopLeft()); CRect rcTopLeft(rcWnd); rcTopLeft.right=m_bmpTopLeft.GetWidth()+rcTopLeft.left; rcTopLeft.bottom=m_bmpTopLeft.GetHeight()+rcTopLeft.top; CBitmap *pOldBitmap=dcMemory.SelectObject(&m_bmpTopLeft); mdc.BitBlt(rcTopLeft.left,rcTopLeft.top,rcTopLeft.Width(),rcTopLeft.Height(), &dcMemory,0,0,SRCCOPY); CRect rcTopRepeat(rcWnd); rcTopRepeat.left=rcTopLeft.right; rcTopRepeat.bottom=rcTopLeft.bottom; rcTopRepeat.right=rcWnd.right-m_bmpTopRight.GetWidth(); dcMemory.SelectObject(&m_bmpTopRepeat); mdc.StretchBlt(rcTopRepeat.left,rcTopRepeat.top,rcTopRepeat.Width(),rcTopRepeat.Height(), &dcMemory,0,0,m_bmpTopRepeat.GetWidth(),m_bmpTopRepeat.GetHeight(),SRCCOPY); CRect rcTopRight(rcWnd); rcTopRight.left=rcTopRepeat.right; rcTopRight.bottom=rcTopRepeat.bottom; dcMemory.SelectObject(&m_bmpTopRight); mdc.BitBlt(rcTopRight.left,rcTopRight.top,rcTopRight.Width(),rcTopRight.Height(), &dcMemory,0,0,SRCCOPY); CRect rcLeftRepeat; rcLeftRepeat.SetRect(rcWnd.left,rcTopLeft.bottom,m_bmpLeftRepeat.GetWidth(),rcWnd.bottom-m_bmpBottomLeft.GetHeight()); dcMemory.SelectObject(&m_bmpLeftRepeat); mdc.StretchBlt(rcLeftRepeat.left,rcLeftRepeat.top,rcLeftRepeat.Width(),rcLeftRepeat.Height(), &dcMemory,0,0,m_bmpLeftRepeat.GetWidth(),m_bmpLeftRepeat.GetHeight(),SRCCOPY); CRect rcRightRepeat(rcLeftRepeat); rcRightRepeat.left=rcTopRepeat.right; rcRightRepeat.right=rcWnd.right; dcMemory.SelectObject(&m_bmpRightRepeat); mdc.StretchBlt(rcRightRepeat.left,rcRightRepeat.top,rcRightRepeat.Width(),rcRightRepeat.Height(), &dcMemory,0,0,m_bmpRightRepeat.GetWidth(),m_bmpRightRepeat.GetHeight(),SRCCOPY); CRect rcBottomLeft(rcWnd); rcBottomLeft.top=rcLeftRepeat.bottom; rcBottomLeft.right=rcLeftRepeat.right; dcMemory.SelectObject(&m_bmpBottomLeft); mdc.BitBlt(rcBottomLeft.left,rcBottomLeft.top,rcBottomLeft.Width(),rcBottomLeft.Height(), &dcMemory,0,0,SRCCOPY); CRect rcBottomRepeat(rcWnd); rcBottomRepeat.left=rcBottomLeft.right; rcBottomRepeat.top=rcBottomLeft.top; rcBottomRepeat.right=rcWnd.right-m_bmpBottomRight.GetWidth(); dcMemory.SelectObject(&m_bmpBottomRepeat); mdc.StretchBlt(rcBottomRepeat.left,rcBottomRepeat.top,rcBottomRepeat.Width(),rcBottomRepeat.Height(), &dcMemory,0,0,m_bmpBottomRepeat.GetWidth(),m_bmpBottomRepeat.GetHeight(),SRCCOPY); CRect rcBottomRight(rcWnd); rcBottomRight.left=rcBottomRepeat.right; rcBottomRight.top=rcBottomRepeat.top; dcMemory.SelectObject(&m_bmpBottomRight); mdc.BitBlt(rcBottomRight.left,rcBottomRight.top,rcBottomRight.Width(),rcBottomRight.Height(), &dcMemory,0,0,SRCCOPY); dcMemory.SelectObject(pOldBitmap) ;

至此,完成,调用方法很简单:对任意以CDialog为基类的对话框,将CDialog用CSkinDialogBase替换,即可变成上图所示的对话框形状(请将边框设为none)。

本人小菜,随手写的,很多不周,请多指点,3Q。

===》示例源代码下载

 

你可能感兴趣的:(8.VC(ui)-自绘对话框基类)