正文

CListBox自绘与刷新2010-06-03 21:28:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/yuqiexing/51291.html

分享到:


CListBox自绘的具体步骤就不再详述了,不过还是要留意以下几点:

 

LBS_OWNERDRAWVARIABLE:允许每一项有不同的长度。要想改变某一项的高度,通过MeasureItem无法做到(宽度可以)。需要用到函数SetItemHeight

 

LBS_NOTIFY:只有加入该风格,CListBox才能响应双击等消息。

 

DrawItem:核心自绘函数。不过并不建议直接使用CListBoxDC来绘制,而是采用双缓冲的方式,可以有效的在Invalidate(FALSE)时减小刷新。

 

本文主要介绍实际应用中的一种情况。有些时候,当双击CListBox某一项的时候,我们希望它能展开,显示更多的信息;再次双击一下,能够收缩,回到正常状态。功能的具体实现很简单,只需要调用SetItemHeight实时调整大小,在DrawItem判断该项是否为展开项来进行显示。

 

 

 

但是,在刷新显示的时候碰到一个问题。当双击收缩最后一项时,如果调用Invalidate(TRUE),自然会产生轻微的闪烁;本文采用了Invalidate(FALSE)来避免闪烁,却发现最后一项收缩后显示正常,但是刚才扩展的区域,因为未刷新,仍然显示刚才的内容,这种效果显然是不正确的。造成的主要原因是因为DrawItem只会负责绘制该项的区域,如果不实时改变每项的高度,这已经足够了;但是由于每项高度在双击后会改变,因此其有义务维护上一次该项的绘制区域。

 

因此一个技巧就是在绘制最后一项时,判断其是否因为收缩而需要刷新,如果是,则利用双缓冲绘制时,需要绘制从该项往下整个客户区(或者展开区域);如果不是,则绘制其实时区域。

 

 

    核心代码如下:

 

      // 如果不是最后一项 绘制其实时区域(展开或者收缩)

       if(lpDrawItemStruct->itemID != GetCount() - 1)

              pDC->BitBlt(wholeRect.left,wholeRect.top,wholeRect.Width(),wholeRect.Height(),&memDC,0,0,SRCCOPY);

       else

       {

              //收缩后刷新,不能只绘制自己项的部分,而是客户区朝下

              if(m_bInvalidated)

              {

       pDC->BitBlt(wholeRect.left,wholeRect.top,wholeRect.Width(),clientrect.Height(),&memDC,0,0,SRCCOPY);

                     m_bInvalidated = FALSE;

              }

              else

       pDC->BitBlt(wholeRect.left,wholeRect.top,wholeRect.Width(),wholeRect.Height(),&memDC,0,0,SRCCOPY);

       }


 

阅读(6740) | 评论(2)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册