我有一个模式较少的对话框,我已使用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不起作用,并且可能在这里提供一些示例代码 这会使它发挥作用。
答案 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);
方法中。
偏移的原因是你的窗口有一个你通常不会画的边框(有方法,但我们现在会忽略它们)。因此,设备上下文描述了一个偏离窗口的区域。
在您的情况下,最简单的解决方案可能是修改对话框模板以指定无边框。这当然会限制窗口的大小调整,但是因为你已经设置了一个区域,我假设调整大小也不是一个选项。