MFC重绘对话框的边框和绘制圆角

13 篇文章 0 订阅

说明:以下方法也是在网上查的,自己已实现。

第一步:重载DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)

LRESULT CMyTestDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	// TODO: 在此添加专用代码和/或调用基类
	LRESULT lResult = CDialog::DefWindowProc(message, wParam, lParam);

	CWnd* pWnd=this->GetParent();
	m_hWnd = pWnd->m_hWnd;
	if (!::IsWindow(m_hWnd))
    {
        return lResult;
    }
		
	if (message==WM_MOVE||message==WM_PAINT||message==WM_NCPAINT||message==WM_NCACTIVATE ||message == WM_NOTIFY)
	{
		CDC* pWinDC = GetWindowDC();
		if (pWinDC)
        {
            DrawBorder(pWinDC);
        }
        else
        {
            ReleaseDC(pWinDC);
        }
	}
	return lResult;
	//return CDialog::DefWindowProc(message, wParam, lParam);
}

第二步:处理画边函数

void CMyDlg::DrawBorder(CDC *pDC)
{
	if (m_hWnd )
	{
		CBrush Brush(RGB(185, 184, 182));
		CBrush* pOldBrush = pDC->SelectObject(&Brush);

		CRect rtWnd;
		GetWindowRect(&rtWnd);

		CPoint point;
		//填充顶部框架
		point.x = rtWnd.Width();
		point.y = GetSystemMetrics(SM_CYFRAME)+1;
		pDC->PatBlt(0, 0, point.x, point.y, PATCOPY);
		//填充左侧框架
		point.x = GetSystemMetrics(SM_CXFRAME);
		point.y = rtWnd.Height();
		pDC->PatBlt(0, 0, point.x, point.y, PATCOPY);
		//填充底部框架
		point.x = rtWnd.Width();
		point.y = GetSystemMetrics(SM_CYFRAME) + 1;
		pDC->PatBlt(0, rtWnd.Height()-point.y, point.x, point.y, PATCOPY);
		//填充右侧框架
		point.x = GetSystemMetrics(SM_CXFRAME);
		point.y = rtWnd.Height();
		pDC->PatBlt(rtWnd.Width()-point.x, 0, point.x, point.y, PATCOPY);
	}
}

绘制圆角:

void CMyDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
	CRgn rgn;
	CRect rc;
	GetWindowRect(&rc); //获得窗口矩形
	rc -= rc.TopLeft();
	rgn.CreateRoundRectRgn(rc.left, rc.top, rc.right, rc.bottom, 15, 15); //根据窗口矩形创建一个圆角矩形最后两个是形成圆角的大小
	SetWindowRgn(rgn, TRUE);
}

在这里补充一点,说明两个问题,一个是如果处理右上角放大/缩小/关闭系统 三个按钮,一个是如何实现界面拖动。

1、实现右上角的放大/缩小/关闭系统

该步骤,可以添加三个按钮,直接手动实现它们的功能,后续的步骤就很简单了,这里就不说明。

2、实现界面的拖动

直接说解决方案,在类的消息处理中选中WM_NCHITTEST,添加OnNcHitTest()函数,修改其中的处理。具体如下:

 

LRESULT CMyTestDlg::OnNcHitTest(CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	UINT nh = CDialog::OnNcHitTest(point);
	return ((nh==HTCLIENT) ? HTCAPTION : nh);

	//return CDialog::OnNcHitTest(point);
}

这样就可以了,具体的原理目前已经忘记了,大家可以自行上网查询。

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要在 MFC 中实现圆角对话框,可以按照以下步骤进行操作: 1.创建一个对话框类 使用 MFC 应用程序向导创建一个对话框类。在“资源视图”中打开对话框,然后右键单击对话框并选择“属性”。 2.设置样式 在对话框属性中,单击“样式”选项卡。在“对话框外观”部分中,选中“边框”复选框,并从下拉框中选择“无边框”。 3.添加圆角对话框属性中,单击“扩展样式”选项卡。在“扩展对话框风格”部分中,选中“圆角”复选框,并设置圆角半径。 4.载 OnPaint 函数 在对话框类中载 OnPaint 函数,实现圆角绘制。 ```cpp void CMyDialog::OnPaint() { CPaintDC dc(this); CRect rect; GetClientRect(&rect); int nWidth = rect.Width(); int nHeight = rect.Height(); CDC dcMem; dcMem.CreateCompatibleDC(&dc); CBitmap bmp; bmp.CreateCompatibleBitmap(&dc, nWidth, nHeight); CBitmap *pOldBmp = dcMem.SelectObject(&bmp); CBrush brush; brush.CreateSolidBrush(RGB(255, 255, 255)); dcMem.FillRect(&rect, &brush); CRgn rgn; rgn.CreateRoundRectRgn(0, 0, nWidth + 1, nHeight + 1, m_nRound, m_nRound); dcMem.SelectClipRgn(&rgn); // 绘制对话框内容 // ... dc.BitBlt(0, 0, nWidth, nHeight, &dcMem, 0, 0, SRCCOPY); dcMem.SelectObject(pOldBmp); } ``` 在 OnPaint 函数中,首先创建一个和对话框相同大小的位图,然后将其选入内存 DC 中。接着创建一个圆角区域,并将其设置为内存 DC 的剪切区域。最后,绘制对话框内容,并将内存 DC 中的位图拷贝到设备上下文中。 5.载 OnNcPaint 函数 在对话框类中载 OnNcPaint 函数,实现圆角绘制。 ```cpp void CMyDialog::OnNcPaint() { CWindowDC dc(this); CRect rect; GetWindowRect(&rect); rect.OffsetRect(-rect.left, -rect.top); rect.right++; rect.bottom++; CDC dcMem; dcMem.CreateCompatibleDC(&dc); CBitmap bmp; bmp.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); CBitmap *pOldBmp = dcMem.SelectObject(&bmp); CRgn rgn; rgn.CreateRoundRectRgn(0, 0, rect.Width(), rect.Height(), m_nRound, m_nRound); dcMem.SelectClipRgn(&rgn); // 绘制非客户区 // ... dc.BitBlt(0, 0, rect.Width(), rect.Height(), &dcMem, 0, 0, SRCCOPY); dcMem.SelectObject(pOldBmp); } ``` 在 OnNcPaint 函数中,首先创建一个和对话框相同大小的位图,然后将其选入内存 DC 中。接着创建一个圆角区域,并将其设置为内存 DC 的剪切区域。最后,绘制非客户区内容,并将内存 DC 中的位图拷贝到窗口 DC 中。 以上就是在 MFC 中实现圆角对话框的步骤,希望能对您有所帮助!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值