MFC中给对话框重绘边框
需求:有时候为了做出好看的UI,不需要使用Windows自带的最大化最小化和关闭按钮,那么此时对话框一定的属性中Border一定就不是Dialog Frame了,应该选择None,此时没有边框,那么就需要给对话框重绘一个边框。
思想:重绘边框,主要是对top,left,right和bottom四个边进行重新绘制。
处理:具体的实现细节和代码如下:
第一步:重载DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam),并添加以下代码:
1 LRESULT CPswDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 2 { 3 LRESULT lResult = CDialog::DefWindowProc(message, wParam, lParam); 4 5 CWnd* pWnd = this->GetParent(); 6 m_hWnd = pWnd->m_hWnd; 7 if (!::IsWindow(m_hWnd)) 8 { 9 return lResult; 10 } 11 12 if (message==WM_MOVE||message==WM_PAINT||message==WM_NCPAINT||message==WM_NCACTIVATE ||message == WM_NOTIFY) 13 { 14 CDC* pWinDC = GetWindowDC(); 15 if (pWinDC) 16 { 17 DrawBorder(pWinDC); 18 } 19 ReleaseDC(pWinDC); 20 } 21 return lResult; 22 //return CDialog::DefWindowProc(message, wParam, lParam); 23 }
此处有一个重绘函数需要实现:
1 void CPswDlg::DrawBorder(CDC *pDC) 2 { 3 if (m_hWnd ) 4 { 5 CBrush Brush(RGB(185, 184, 182)); 6 CBrush* pOldBrush = pDC->SelectObject(&Brush); 7 8 CRect rtWnd; 9 GetWindowRect(&rtWnd); 10 11 CPoint point; 12 //填充顶部框架 13 point.x = rtWnd.Width(); 14 point.y = GetSystemMetrics(SM_CYFRAME)+1; 15 pDC->PatBlt(0, 0, point.x, point.y, PATCOPY); 16 //填充左侧框架 17 point.x = GetSystemMetrics(SM_CXFRAME); 18 point.y = rtWnd.Height(); 19 pDC->PatBlt(0, 0, point.x, point.y, PATCOPY); 20 //填充底部框架 21 point.x = rtWnd.Width(); 22 point.y = GetSystemMetrics(SM_CYFRAME) + 1; 23 pDC->PatBlt(0, rtWnd.Height()-point.y, point.x, point.y, PATCOPY); 24 //填充右侧框架 25 point.x = GetSystemMetrics(SM_CXFRAME); 26 point.y = rtWnd.Height(); 27 pDC->PatBlt(rtWnd.Width()-point.x, 0, point.x, point.y, PATCOPY); 28 } 29 }
由于在设置对话框的Border的属性时选择的是None,那么此时鼠标点击对话框拖动就失去了作用,使用如下的代码是可以实现拖动的:
1 LRESULT CPswDlg::OnNcHitTest(CPoint point) 2 { 3 UINT nh = CDialog::OnNcHitTest(point); 4 return ((nh==HTCLIENT) ? HTCAPTION : nh); 5 6 //return CDialog::OnNcHitTest(point); 7 }
这里是重载了WM_NCHITTEST消息。另外,按照以上重绘的边框,边框的四个角都是直角,使用如下代码,可以将直角变为圆角。
1 void CPswDlg::OnSize(UINT nType, int cx, int cy) 2 { 3 CDialog::OnSize(nType, cx, cy); 4 5 CRgn rgn; 6 CRect rc; 7 GetWindowRect(&rc); //获得窗口矩形 8 rc -= rc.TopLeft(); 9 rgn.CreateRoundRectRgn(rc.left, rc.top, rc.right, rc.bottom, 15, 15); //根据窗口矩形创建一个圆角矩形最后两个是形成圆角的大小 10 SetWindowRgn(rgn, TRUE); 11 }
经过以上的几个函数的重载处理,基本上你想要的功能都实现了。下面是实现的效果图: