如何在MFC中的非矩形窗口中绘制边框

时间:2013-04-30 14:22:48

标签: c++ mfc

我有一个模式较少的对话框,我已使用SetWindowRgn()将形状更改为圆形。我想使用FrameRgn在它周围画一个彩色边框。这是我正在使用的代码

BOOL CMyDlg::OnInitDialog() 
 {
 CDialog::OnInitDialog(); m_Brush.CreateSolidBrush(RGB(255,255,255));
 CRect rcDialog;
 GetClientRect(rcDialog);

 // This Creates area assigned to Dialog: This goes directly below the above in OnInitDialog
 m_rgnShape.CreateRoundRectRgn(rcDialog.TopLeft().x, rcDialog.TopLeft().y,rcDialog.BottomRight().x,rcDialog.BottomRight().y, rcDialog.Width()/8, rcDialog.Height()/8);
::SetWindowRgn(GetSafeHwnd(), (HRGN)m_rgnShape, TRUE);

return TRUE; // return TRUE unless you set the focus to a control
  // EXCEPTION: OCX Property Pages should return FALSE

}

void CMyDlg::OnPaint() 
{
 CPaintDC dc(this); // device context for painting

 CBrush brush;
 brush.CreateSolidBrush(RGB(255,0,0));

  dc.FrameRgn(&m_rgnShape, &brush, 2, 2);
}

任何人都可以解释为什么FrameRgn不起作用,并且可能在这里提供一些示例代码 这会使它发挥作用。

1 个答案:

答案 0 :(得分:1)

CWnd::SetWindowRgn文档中所示:

  

成功调用SetWindowRgn后,操作系统拥有   区域指定的区域处理hRgn。操作系统   不要复制该区域,所以不要做任何进一步的功能   使用此区域句柄调用,并且不要关闭此区域句柄。

这基本上意味着你不能再将该地区用于其他目的,而且你也不能“失去”该地区。由于它是一个成员变量,因此最后一个问题不是您需要担心的问题。但是关于“不要使用它”部分,您会注意到FrameRgn(...)调用很可能返回零,表示尝试绘制时失败。

您可以做的是从CRgn对象中分离区域句柄并使用它来设置窗口区域,然后您可以像以前一样重新创建一个新区域:

m_rgnShape.CreateRoundRectRgn(...);
HGDIOBJ hRgn = m_rgnShape.Detach();
::SetWindowRgn(GetSafeHwnd(), (HRGN)hRgn, TRUE);
m_rgnShape.CreateRoundRectRgn(...);

有关更好的说明,请查看本文涵盖Setting a Window Region,使其看起来像猫。


编辑:您的评论提到现在,框架区域实际上被金额所抵消。金额可能是窗口边框的大小。

当您调用GetClientRect时,它会返回窗口客户区的大小 - 您可以轻松绘制的部分,以及当您执行{{1时“设备上下文”描述“的部分在CPaintDC dc(this);方法中。

偏移的原因是你的窗口有一个你通常不会画的边框(有方法,但我们现在会忽略它们)。因此,设备上下文描述了一个偏离窗口的区域。

在您的情况下,最简单的解决方案可能是修改对话框模板以指定无边框。这当然会限制窗口的大小调整,但是因为你已经设置了一个区域,我假设调整大小也不是一个选项。