duilib自绘

有时候我们在使用duilib的同时,可能想自己在窗体上绘制一些图形、线条等等,但是发现绘制不上去。emmm,不用烦恼,其实是绘制上去然后又被duilib自身的绘制机制给擦掉了应该。

更多关于自绘的知识可以看另外一篇:再谈duilib控件自绘 (其中介绍了不用自定义控件,也能对某个具体的控件自身进行自绘,并且不绘制在所有控件上层的方法。)

那么正确的绘制姿势呢?

方法1:从CControlUI派生一个子类,然后直接重写DoPaint接口,在里面绘制即可。这样有1个限制,duilib默认是后添加的控件Z序高,而实际绘制全部控件的时候,Z序高的控件在上层。因此如果这个控件的Z序比较低,是有可能被其他控件盖住的,这个要看具体的布局了。

方法2:从CControlUI派生一个子类,然后直接重写DoPostPaint接口。然后调用PaintManager的AddPostPaint接口将这个控件指针加入的m_aPostPaintControls数组即可。此时在全部控件绘制完毕后,会触发DoPostPaint接口的调用,在里面绘制即可。这种方法与1的不同之处在于,PostPaint是单独的一套机制,并不影响控件的bkcolor,bkimage,text,border等绘制。并且是在所有控件绘制之后绘制的,因此它的绘制是在最上层的,不会由于控件的Z序等导致绘制被其他控件覆盖。redrain大佬有一篇控件拖拽的文章有利用,感兴趣的可以看看。

方法3:类似方法2,不过不用派生了,可以直接将根控件(通过PaintManager的GetRoot()接口可以获得,或者自己留存)通过PaintManager的AddPostPaint加入到m_aPostPaintControls里面。然后定义一个bool OnPostPaint(void* param){};然后给需要的控件通过pControl->OnPostPaint += MakeDelegate(this,&CXXXX::OnPostPaint);这样,在全部控件绘制完毕后,会触发OnPostPaint的调用,在这里绘制即可。这样与方法2显然不同的是不需要派生新控件啦。

方法3中有一个问题要注意:

OnPostPaint中的HDC是没有的,需要自己获取才行,如果获取的是PaintManager里面的m_hDcPaint,那么是有问题的,原因是duilib是双缓冲机制,所有绘制是先绘制到m_hDcOffscreen上,再渲染到m_hDcPaint上来上屏。

OnPostPaint中如果直接绘制到m_hDcPaint上,那么在后面上屏的时候由于m_hDcOffscreen里没有被绘制,导致被覆盖而看不到自绘的内容。同样OnPaint也会存在这个问题。

解决办法有多种选择,我这边采用给PaintManager增加GetOffscreenDC接口来处理。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值