数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
给pb的listview或者treeview控件加上背景图

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

此文章献给想美化程序界面的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下载,欢迎大家作进一步探讨:)




相关文章

相关软件