2013-04-30 106 views
1

我有一个模式较少的对话框,我已经使用SetWindowRgn()将形状更改为一个圆角。我想用FrameRgn在它周围画一个彩色边框。下面是我使用如何在MFC的非矩形窗口中绘制边框

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

作为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,它返回窗口的客户区的大小 - 你可以轻而易举地吸引了一部分,那就是当你在OnPaint()方法做“描述”的设备上下文的一部分。

偏移量的原因是你的窗口有一个边界,你通常不会绘制(有方法,但我们现在将忽略这些边界)。所以设备上下文描述了一个偏离窗口的区域。

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

+0

嗨,我改变了代码,当我绘制一个多边形shaped.Now边界显示,但只为多边形的两侧。你可以告诉我如何控制它。现在,边界不是来多边形的所有边。 – user2336139 2013-05-01 06:21:08

+0

这可能是由于你在对话框上有一个边框 - 我会在我的答案中添加一些内容来解释。 – icabod 2013-05-01 15:58:24