分享
 
 
 

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

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有