欢迎光临
我们一直在努力

给pb的listview或者treeview控件加上背景图-数据库专栏,其他相关

建站超值云服务器,限时71元/月

此文章献给想美化程序界面的pb程序员。

一.载入位图资源并创建patternbrush作为填充背景图的刷子
long ll_bmp
long h_deskdc
long ll_memdc

if ih_bkbrush>0 then
 deleteobject(ih_bkbrush)
 ih_bkbrush=0
end if

h_deskdc =getdc(0)
//载入图片
ll_bmp = loadimage(0,bmpbkname,0,0,0,16)
//失败
if ll_bmp = 0 then
 releasedc(0,h_deskdc)
 return
end if
ll_memdc = createcompatibledc(h_deskdc)
//选入到场景
selectobject(ll_memdc,ll_bmp)
//创建绘制背景图的刷子
ih_bkbrush =createpatternbrush(ll_bmp)
//释放不需要的资源
releasedc(0,h_deskdc)
deleteobject(ll_bmp)
deletedc(ll_memdc)

二.给listview加背景图
1.得到listview客户区域矩形
getclientrect(handle(this),lvclientrect)

2.在listview中以pbm_erasebkgnd为事件id,自定义事件ue_erasebkgnd ,script如下 
if ih_bkbrush>0 then
 fillrect(hdc,lvclientrect,ih_bkbrush)
 return 1
end if

3.当listview的显示风格为listviewreport!,listviewlist!时候,拖动滚动条时候会出现挤压需要以pbm_vscroll和pbm_hscroll作为eventid自定义事件ue_vscroll,ue_hscroll。
if ih_bkbrush>0 and (view=listviewreport! or view=listviewlist!) then
 if (scrollcode<>sb_endscroll) and (scrollcode<>sb_thumbposition) then
  invalidaterect(handle(this),lvclientrect,1)
 end if
end if
尽管如此,在上述两种风格中拖动滚动条依然有闪烁的情况,我还没有能够解决,欢迎大家提出意见。

4.如果想要listview中item的文本和图片背景透明,只需调用以下代码
constant long clr_none = 4294967295
constant long lvm_first   =4096
constant long lvm_settextbkcolor = (lvm_first + 38)
constant long lvm_getimagelist = (lvm_first + 2)
constant long lvm_setbkcolor = (lvm_first + 1)
constant long  lvsil_normal= 0
constant long  lvsil_small=1
constant long  lvsil_state=2
//让文本的背景色透明
send(handle(this),lvm_settextbkcolor,0,clr_none)
//让图片的背景色透明
send(handle(this),lvm_setbkcolor,0,clr_none)

此外,如果使用pb自带的图片,需要将picturemaskcolor设置为silver。

三.给treeview加背景图
    如果按照上述listview的方法给treeview控件添加背景图,也可以基本实现,但是在树的子项展开,收缩时候以及拖动滚动条时会挤压图形,如果用setredraw控制会出现严重的闪烁情况。此外树的子项的文本和图片背景也不能透明。

1.我参考了其他程序语言实现的例程,基本都会在wm_paint事件中处理,因此我以pbm_paint作为eventid自定义事件ue_paint。但由于此事件的参数hdc在任何情况下均为0,所以我猜测在pb中,此事件只是在调用windowproc处理wm_paint消息前执行,并没有使用beginpaint开始进行绘图操作。
   要让树的子项的文本和图片背景透明,只需要做一些光栅运算就可以了
   相关代码如下:
if ih_bkbrush>0 then

 if message.wordparm >0 then
  //由send函数带wordparm参数触发,不执行下面的操作
  return 0
 end if
 
 tagpaintstruct ps
 //开始paint操作
 hdc=beginpaint(handle(this),ps)
 long memdc,maskdc,resultdc;
 long hbitmap;
 long li_rcwidth,li_rcheight
 
 li_rcwidth=tvclientrect.right -tvclientrect.left
 li_rcheight=tvclientrect.bottom -tvclientrect.top
 resultdc=createcompatibledc(hdc);
 hbitmap=createcompatiblebitmap(hdc,li_rcwidth,li_rcheight);
 selectobject(resultdc, hbitmap );
 deleteobject(hbitmap)
 
 //将背景图绘制到设备场景resultdc上
 fillrect(resultdc,tvclientrect,ih_bkbrush)
 
 // create a compatible memory dc
 memdc=createcompatibledc(hdc);
 hbitmap=createcompatiblebitmap(hdc,li_rcwidth,li_rcheight);
 selectobject(memdc, hbitmap );
 deleteobject(hbitmap)
 //将tv的内容绘制到设备场景memdc上
 send(handle(this),wm_paint,memdc, 0)
 
 // create mask dc
 maskdc=createcompatibledc(hdc);
 hbitmap=createbitmap(li_rcwidth,li_rcheight,1, 1,0);
 selectobject(maskdc, hbitmap );
 deleteobject(hbitmap)
 //只有单色
 bitblt(maskdc,0,0,li_rcwidth,li_rcheight,memdc,0,0,srccopy);
 
 setbkcolor(memdc,rgb(0,0,0));
 settextcolor(memdc,rgb(255,255,255))
 //白色替换为黑色
 bitblt(memdc,0,0,li_rcwidth,li_rcheight,maskdc,0,0,srcand);
 
 //通过and操作,将item和文本置为黑色添加到背景图上
 bitblt(resultdc,0,0,li_rcwidth,li_rcheight,maskdc,0,0,srcand);
 //通过or操作,将treeitem替换为原有颜色
 bitblt(resultdc,0,0,li_rcwidth,li_rcheight,memdc,0,0,srcpaint);
 
 //将合并后的图copy到hdc上
 bitblt(hdc,0,0,li_rcwidth,li_rcheight,resultdc,0,0,srccopy);

 deletedc(memdc)
 deletedc(maskdc)
 deletedc(resultdc)
 //结束paint操作
 endpaint(handle(this),ps)
end if

由于做了多次的位图处理操作,在配置较低的机器上可能会有延迟的现象,所以treeview控件的长度和宽度不要太大,子项的数目应该控制在合理的范围内。

2、由于我们在ue_paint事件中已经对背景进行了绘制,因此需要屏蔽默认的刷新背景操作。
ue_erasebkgnd:
if ih_bkbrush>0 then
 //不执行默认的消息处理程序
 return 1
end if

3.对于treeview由于子项展开,收缩时候会挤压图形,需要itemcollapsin、itemexpanding和selectchanging事件控制从而使整个控件重画。
if ih_bkbrush>0 then invalidaterect(handle(this),tvclientrect,0)
 
4、对于由于滚动条拖动产生的图形积压,也需要做类似处理。
pbm_vscroll和pbm_hscroll:
if ih_bkbrush>0 and (scrollcode<>sb_endscroll) and (scrollcode<>sb_thumbposition) then
 invalidaterect(handle(this),tvclientrect,0)
end if

在这里我只对程序的关键实现部分作了说明,省略了相关的变量、外部函数、结构声明和其他部分。完整的pb8例程可在 
http://www.tiantiansoft.com/dispbbs.asp?boardid=23&id=934下载,欢迎大家作进一步探讨:)

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 给pb的listview或者treeview控件加上背景图-数据库专栏,其他相关
分享到: 更多 (0)

相关推荐

  • 暂无文章