MFC中给对话框重绘边框

时间:2022-06-20 14:35:42

  需求:有时候为了做出好看的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 }

 

经过以上的几个函数的重载处理,基本上你想要的功能都实现了。下面是实现的效果图:

MFC中给对话框重绘边框