CSplitterWnd 控件的特性

最近,调UI,发现 CSplitterWnd 这个控件的特性,很有意思。先贴点它自绘的源码。

void MyCSplitter::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg)
{

if (pDC == NULL)
{
RedrawWindow(rectArg, NULL, RDW_INVALIDATE|RDW_NOCHILDREN|RDW_NOERASE );
return;
}
otherwise, actually draw
COLORREF clrBtnShadow = 0x00a0a0a0;
COLORREF clrBtnHilite = 0x00ffffff;
COLORREF clrWindowFrame = 0x00646464;
COLORREF clrBtnFace = 0x00f0f0f0;
CRect rect = rectArg;
switch (nType)
{
case splitBorder:
pDC->Draw3dRect(rect, clrBtnShadow, clrBtnHilite);
rect.InflateRect(-AFX_CX_BORDER, -AFX_CY_BORDER);
pDC->Draw3dRect(rect, clrWindowFrame, clrBtnFace);
return;


case splitIntersection:
break;


case splitBox:
pDC->Draw3dRect(rect, clrBtnFace, clrWindowFrame);
rect.InflateRect(-AFX_CX_BORDER, -AFX_CY_BORDER);
pDC->Draw3dRect(rect, clrBtnHilite, clrBtnShadow);
rect.InflateRect(-AFX_CX_BORDER, -AFX_CY_BORDER);
break;


case splitBar:
break;


default:
ASSERT(FALSE);  // unknown splitter type
}


// fill the middle
COLORREF clr = 0x00f0f0f0;
pDC->FillSolidRect(rect, clr);

}

这是它的重绘的部分源码,也是主要的代码。重绘的时序分为两个部分,第一部分,是 void CSplitterWnd::RecalcLayout() 调用 OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg)。这次的调用,传入的pDC 是 NULL,目的就是让 RedrawWindow(rectArg, NULL, RDW_INVALIDATE|RDW_NOCHILDREN|RDW_NOERASE ) 执行,用来强制更新 CSplitterWnd 内部范围的显示,而不是更新 CSplitterWnd 自身边框的显示。第二部分,就是 void CSplitterWnd::OnDraw(CDC* pDC),这次传入的 pDC不是NULL,所以,它就开始绘制自己的边框这类的显示。

那么,在MFC框架下,这样的设计是没问题的。但是对于DIY UI的情况,就有点问题了。就像之前的博文,我在view中 使用了SDL,然后SDL的渲染是采用的OPENGL,这时候,渲染的图像信息是存储在SDL内部的,在现实的时候,只是swapbuff了一下。这个swapbuff之后显示的内容,mfc本地没有管理,也没法管。当CSplitterWnd强制更新内部范围的显示时,就有问题了。

那么这种情况,就要自定义CSplitterWnd的重绘行为了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值