给pb的listview或者treeview控件加上背景图

原创 2004年02月05日 00:43:00

此文章献给想美化程序界面的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/bbs/fileshow.asp?boardid=79&id=234下载,欢迎大家作进一步探讨:)

PB treeview 控件设置背景图片

  • 2012年12月25日 10:17
  • 374KB
  • 下载

PB中TreeView控件使用技巧

PB中TreeView控件使用技巧 2007-01-28 00:09:20 分类: 数据库开发技术 PowerBuilder中的TreeView 控件为树状游览,类似于WIND...
  • tlammon
  • tlammon
  • 2016年03月01日 20:40
  • 1884

PB控件属性之TreeView

TreeView 【其他】 ■TreeView控件可以以树型方式来组织项目,不仅显示直观、界面友好,而且项目的管理和操作更为方便,是当前比较流行的一个控件。 该控件的特点是在较小的空...
  • u012369435
  • u012369435
  • 2014年07月03日 11:38
  • 1204

PB下使用TreeView控件实现多级分类检索

PowerBuilder中的TreeView控件为树状列表,其特点是信息项呈树状层次结构,且形式灵活,可展开也可回缩,使用鼠标进行控制,操作简便。因此在应用中,可将其与DataWindow配合,一个提...
  • tlammon
  • tlammon
  • 2016年03月23日 01:24
  • 812

PB TreeView 控件实现查找功能

long ll_handle,ll_level,ll_handletree[] int li_find string ls_find treeviewitem ltvi_1 SetPointer(h...
  • smilysoft
  • smilysoft
  • 2016年06月01日 17:58
  • 989

PB实现TreeView多级分类检索(案例)

contructor事件:long ll_row,i TreeViewItem tv_new //建立一个图标队列,供其中的TreeViewItem项引用,在这里建立主要是为了能够控制图标大小 //首...
  • tlammon
  • tlammon
  • 2016年03月25日 01:12
  • 923

c#中TreeView和ListView的一些用法

TreeView   TreeNode的Tag可以用来存储一个对象的引用(类似vc里面的SetData方法),可以用来存储相对于这个node的自己所需要的数据 添加首個節點使用TreeView....
  • rekrad
  • rekrad
  • 2013年01月18日 17:06
  • 3760

PB TreeView 属性,事件详解(转)

PB TreeView 属性,事件详解(转)   本文转自:http://chbin95233.blog.163.com/blog/static/3207511120101057344...
  • tlammon
  • tlammon
  • 2016年02月25日 10:09
  • 686

VS之treeview和listview拆分窗口

VS中,经常会使用到窗口的拆分技术,本文以treeview和listview来实现拆分窗口。...
  • bingdianlanxin
  • bingdianlanxin
  • 2014年12月22日 21:16
  • 1524

PB控件TreeView的四个函数

TreeViewItem 笔记     四个函数:        1.InsertItem()函数:         Treeviewname.InsertItem(handleparent,h...
  • tlammon
  • tlammon
  • 2016年03月24日 19:51
  • 270
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:给pb的listview或者treeview控件加上背景图
举报原因:
原因补充:

(最多只允许输入30个字)