- 热门文章:
- · PowerBuilder 9.0 抢先预览
- · [UDF系列]如何创建InterBase UDF
- · (interbase之九)intebase的存储过程、触发器以及事件、异常
- · (interbase之七) 使用域扩展interbase的数据类型
- · (interbase之六) interbase的dialect
- · (INTERBASE之五) IB技术指标
- · (INTERBASE之四) interbase技术探秘
- · (INTERBASE之三) 什么是interbase
- · (INTERBASE之二) INTERBASE的发展史
- · (INTERBASE之一) INTERBASE有趣的故事
- · (interbase之八) interbase的事务处理
- · [UDF系列]如何编写InterBase UDF 之三
上一篇:多語言版vfp程序設計簡單實現 >>
给pb的listview或者treeview控件加上背景图
此文章献给想美化程序界面的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下载,欢迎大家作进一步探讨:)
下一篇:PowerBuilder 9.0 抢先预览 >>
相关文章:
- · [UDF系列]如何编写InterBase UDF 之二
- · [UDF系列]如何编写InterBase UDF 之一
- · 如何在pb中创建COM组件,并在asp中调用并返回结果集?
- · 如何在pb9中调用WebService
- · Powerbuilder6.0实现 Browser/Server结构的Internet解决方案和工作方式
- · How did Interbase appear?(Interbase是如何出现的?)
- · PowerBuilder中回车键的应用
- · PowerBuilder数据库配置方法
- · PB中对INI文件读写的补充函数:删除指定的节或者指定节中某个项
- · 用PowerBuilder建立browser-server结构应用程序
- · PB7.0通用选字段查询窗口的设计
- · 怎样在PB中调用外部程序并判断其运行结束?
- · 如何在PB中实现串口编程
- · PowerBuilder修改数据库表结构的技巧
- · PowerBuilder窗口之间传递多参数的方法
- · 使PB窗口居中
- · 用PB实现Windows2000下的自动关机
- · InterBase 6.5的新特性
- · 2001-12-04 Borland 交付InterBase&reg; 6.5
- · 通用权限管理工具,支所有ADO(包括ODBC)支持的数据库,不管用什么编程都行,VC/BCB/VB/PB/Delphi
- · 在PowerBuilder7.0中应用DDE技术一例
- · 不用重新安装PowerBuilder8.0也可以使用
- · powerbuilder中API應用10則
- · powerbuilder初學者概念20則
- · PB中表的修改对数据窗口和报表的影响的解决办法
- · 自适应屏幕分辨率的基类窗口(pb)
- · pb用纯函数实现在数据窗口中模拟资源管理器鼠标单击动作动态排序,并显示排序箭头
- · PowerBuilder 7.0实用技巧八则
- · 建立和部署PowerBuilder组件
- · powerbuilder中把图标放在时间显示处
- · 数字转换为大写(vfp)
- · 如何在POWER BUILDER中使用WINSOCK控件
- · 如何在PB下实现圆形的窗口
- · pb中取汉字串首字符的一个函数
- · 如何在PB中切换中英文输入法数
- · pb中窗口等对象如何改名
- · PowerBuilder 6.0 简介
- · 用PB编写多线程应用程序
