去边角(CreateRoundRgn)对窗体坐标的影响

ToCpp 2009-04-03 10:40:09
一直都搞不明白这个问题,我自绘窗体的过程中,有些边角地方,就像QQ之类的,需要去掉,我用CreateRoundRgn(0,0,width,height,4,4),当然也可以根据图像的特殊色来产生rgn,设置了 Rgn后,当绘制窗体的左下角,右下角时都会出现问题,总是少绘制了一个像素,我看到好多代码里面都会响应WM_NCCALCNCSIZE来重新设置客户区(非客户区)区域:
问题就是当我对一个窗体设置了一个rgn后,是不是对窗体的非客户区或者客户区坐标产生了影响,应该怎么解决呢?
...全文
235 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
cnzdgs 2009-04-04
  • 打赏
  • 举报
回复
你上面的代码是因为擦除客户区(WM_ERASEBKGND消息)时是按矩形填充的,把红色都覆盖掉了,不是“少画了一个像素”。通常情况不需要效应WM_NCCALCSIZE消息来做处理,创建RGN时也不需要+1。
cnzdgs 2009-04-04
  • 打赏
  • 举报
回复
上面是标题栏,属于非客户区,所以没有被客户区覆盖,如果你的圆角设置的足够大,一样会被覆盖。
ToCpp 2009-04-04
  • 打赏
  • 举报
回复
那左上角的红色怎么没有覆盖呢,
ToCpp 2009-04-03
  • 打赏
  • 举报
回复
上面圆角下面直角,基本上应该就是通过图片来产生RNG了吧,感觉这样更方便些,而且可以做到图片是怎样的窗体就是怎样的。
这些函数也都有现成的,BitmapToRgn之类的,主要设置了RGN后产生的问题,是不是需要响应WM_NCCALCASIZE或者在产生RNG时就+1之类做一些其他的处理,先回去了,明天继续讨论
ToCpp 2009-04-03
  • 打赏
  • 举报
回复
基本上就是异型窗体吧,思路知道大都就用Rgn,问题当设置了Rgn后,是不是对窗体的坐标产生影响,因为我像上述代码那样设置Rgn后,窗体的下边和右边绘制时总会少绘制一个像素,上图其实也看得出来,左上角的圆角明显是画出来了,但是其他三个角就没有画出
cnzdgs 2009-04-03
  • 打赏
  • 举报
回复
你是想要上面圆角、下面直角吗?
cnzdgs 2009-04-03
  • 打赏
  • 举报
回复
没看出少画了什么,你把想要的效果贴出来看看。
ToCpp 2009-04-03
  • 打赏
  • 举报
回复
就是想做成QQ那样的边角去掉,而且最好是能从图片产生RGN,毕竟有时不一定是圆角,是不是和WM_NCCALCASIZE消息有关
ToCpp 2009-04-03
  • 打赏
  • 举报
回复
你看上面那个图,下边和右边的区域都少画了一部分,按照mynamelj 说的加1好像就没有问题,但是对于从图片产生的RGN不能这样加1啊,设置了RGN后是不是对坐标有影响呢。
cnzdgs 2009-04-03
  • 打赏
  • 举报
回复
“少绘制了一个像素”是什么问题?想解决成什么样子?
SetWindowRgn是设置整个窗口区域,包括非客户区。
ToCpp 2009-04-03
  • 打赏
  • 举报
回复
如果我不用CreateRoundRectRgn,而是根据图片中的特殊色来产生RGN又该怎么办呢?
ToCpp 2009-04-03
  • 打赏
  • 举报
回复
为什么要加1呢,这个是怎么产生的,是不是加了1就不用处理WM_NCCALNCSIZE了
mynamelj 2009-04-03
  • 打赏
  • 举报
回复
void CMyDlg::OnSize(UINT nType, int cx, int cy)
{
if( cx > 0 && cy > 0 )
{
CRect rcWindow;
GetWindowRect(&rcWindow);
rcWindow.OffsetRect(-rcWindow.TopLeft());
HRGN hRgn = CreateRoundRectRgn(0, 0, rcWindow.Width() + 1, rcWindow.Height() + 1, m_ptCorner.x, m_ptCorner.y);
SetWindowRgn(hRgn, TRUE);
DeleteObject(hRgn);
}
}
mynamelj 2009-04-03
  • 打赏
  • 举报
回复
CreateRoundRgn(0,0,width+1,height+1,4,4)

右和下是要加1的
ToCpp 2009-04-03
  • 打赏
  • 举报
回复
补充下,不带系统边框的窗体好像也有这样的问题。
ToCpp 2009-04-03
  • 打赏
  • 举报
回复

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

if ( cx > 0 && cy > 0 )
{
// Here we calculate the resulting window size from the passed client size
CRect rect( 0, 0, cx, cy );
CalcWindowRect( &rect );

// Here we create the rounded region - you can adjust the 'rounding' using a different 'r'
CRgn rgn;
int r = 50;
rgn.CreateRoundRectRgn( 0, 0, rect.Width(), rect.Height(), r, r );
SetWindowRgn( (HRGN)rgn.Detach(), TRUE );
}
}


void CMyDlg::OnNcPaint()
{
// TODO: Add your message handler code here
// Do not call CDialog::OnNcPaint() for painting messages
const MSG* pMsg = GetCurrentMessage();

CRect rect;
GetWindowRect( &rect );

CRgn rgn;
rgn.CreateRectRgn( rect.left, rect.top, rect.right, rect.bottom );

if ( pMsg->wParam != 1 )
{
// just a part of the window's NC area needs to be drawn, so
// we create a copy of the update region
HRGN hRgn = (HRGN)pMsg->wParam;
rgn.CopyRgn( CRgn::FromHandle( hRgn ) );

// in this case the regions coordinates are screen coordinates,
// so we need to move the region before we fill it
rgn.OffsetRgn( -rect.left, -rect.top );
}
else
{
// the whole window needs to be drawn. In this case we don't need
// to move the region since the window's region is relative to the window
GetWindowRgn( (HRGN)rgn.GetSafeHandle() );
}

CWindowDC dc( this );
CBrush brush;
brush.CreateSolidBrush( RGB( 255, 0, 0 ) );
dc.FillRgn( &rgn, &brush );
}

这段代码是网上搜到的,和我描述的问题是一样的,http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_24078243.html



我的代码基本上就是和这个一样的。

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧