定制控件背景颜色与背景位图

本文讲述如何定制控件的背景颜色和背景位图的技巧。

首先要说一下控件的绘制过程:当控件的某个区域需要重绘时,都会触发WM_ERASEBKGND和WM_PAINT消息。比如控件的某个区域被另一个程序的窗口挡住了,而后那个窗口又被移走了,这时控件被挡住的内容就需要重新绘制了。

第一步:系统向控件发送WM_ERASEBKGND消息以实现背景的擦除工作(有时不发送,比如用户可能调用InvalidateRect(),其参数却指定不擦除背景,这样就没有这个消息);

第二步:系统向控件的窗口过程发送WM_PAINT消息,控件执行处理这个WM_PAINT消息时会有选择地触发后面三个步骤的动作;

第三步:对于有些标准控件,如Button、Edit、ListBox、ScrollBar、Static控件,它还会向父窗口发送WM_CTLCOLORxxx(WM_CTLCOLORBUTTON、WM_CTLCOLOREDIT、WM_CTLCOLORSTATIC、WM_CTLCOLORLISTBOX、WM_CTLCOLORSCROLLBAR等)的消息,这些消息返回一个刷子句柄,系统拿这个刷子句柄进一步涂刷自己的背景。另外还发现Trackbar也会向父窗口发送WM_CTLCOLORSTATIC消息,TreeView在某些情况下也有,不过我没有看到微软在什么地方对这一点作说明;我常常发现很多人处理这个消息时,喜欢给系统返回一个NULL_BRUSH的空刷子,以为这样系统就不会把前面步骤画好的背景覆盖掉,其实不一定的,有些控件不覆盖,有些就有问题,像Trackbar就是如此,要小心。

第四步:对于菜单和许多标准控件,如Button、Edit、ListBox、Static、ComboBox它可能会向父窗口发送WM_MEASUREITEM和WM_DRAWITEM消息,另外通用控件Tab、StatusBar、ListView、Header也可能会有WM_DRAWITEM消息;但对于多数通用控件,如TreeView、ListView、Rebar、Trackbar、Toolbar等,它会向父窗口发送许多其ID为NM_CUSTOMDRAW的WM_NOTIFY消息。对于这两种消息,实际要求用户在已经涂刷好的背景之上再执行自己的绘制工作;

第五步:当控件的WM_DRAWITEM或者WM_NOTIFY消息没有被用户处理时,系统会亲自执行自己的默认绘制工作,把控件画出来,这一步没有办法重载。

知道了这些步骤,大概我们心中已经了然,知道如何定制控件的背景颜色和背景位图了。一般情况下我们定制第一步、第三步实现自己的特殊背景,定制第四部实现控件本身的特殊绘制。甚至我们可以整个重载控件第一步的WM_ERASEBKGND消息和第二步的WM_PAINT消息,控件背景和控件绘制全部自己搞定,没人说这样做不行。不过要注意,当自己实现WM_PAINT消息的重载处理时,后面3个步骤就都不发生了。

定制颜色倒是很简单,根据控件的类型处理WM_ERASEBKGND、WM_CTLCOLORxxx、WM_DRAWITEM、WM_NOTIFY消息了,一般情况下,定制WM_ERASEBKGND和WM_CTLCOLORxxx就可以了;对于背景位图很多控件却特别麻烦,像ListBox,你把背景位图涂刷好,结果因为用户操作滚动条或鼠标滚轮或按方向键,背景位图也发生滚动,这就不得不重绘位图,对于背景颜色就没有这个问题,不管怎么滚动,颜色还是那个颜色,位图就不行,需要自己重载发生滚动操作的各种消息以实现位图重绘。微软似乎并不假设你会修改控件的背景位图,它没有对这个情况作准备,总是毫不犹豫的对控件画布执行Scroll操作。真正实现背景位图的方法常常迫使我们要拦截那些导致窗口内容发生滚动的各种操作,因此位图背景的功能实现也总让人觉得不怎么规范、不那么可信。

最后要说明的是:如果父控件还包含背景透明的子控件,你应当重载父控件的WM_ERASEBKGND消息,否则那些透明背景的子控件可能就没有正确的背景内容。

上面这些步骤是我个人的理解,不一定对哦!仅供参考。

定制控件背景颜色与背景位图,布布扣,bubuko.com

时间: 2024-08-08 09:38:04

定制控件背景颜色与背景位图的相关文章

锐浪 报表, 当多行交叉报表时,对多行交叉报表中自由格中的多个字段控件,进行颜色控制. 取值 判断等实现

需要注意的点是: 1 . 要对自由格中对应的 字段框的背景填充方式改为:填充,否则没有效果. 2 . 代码中红色部门代码: Column 为明细网络对象属性中的 列集合 中的 交叉列的 名称,  Report.RunningDetailGrid.Columns.Item("Column_2") 3.  蓝色部门 为自由格中 控件的索引位置 ,也可以根据字段框的名称来进行控制如:  contentCell.Controls.Item("FieldBox8") 代码如下

BarcodeX条形码控件可以被导出为位图

BarcodeX条形码控件是一个功能齐全的ActiveX控件,可以生成任何类型的条码.它可以被绑定到一个数据源上,用于数据库报表中. 条形码可以被导出为位图,图元文件,剪贴板 具体功能: 用在Windows95/98/NT/2000/XP系统中的32位ActiveX控件 (OCX) 可在VisualStudio.Net, ASP, ASP.NET, VBScript等中使用 包含VB.Net示例程序 ASP页的频外发讯流条码图片 对于条码下方的可选文本行,所有WINDOWS字体均可用 前景和背景

Android定制控件-带图像的TextView

最近在学习Android,边看书边敲代码,看到是李宁的Android开发完全讲义,因为是对着书本敲的, 所以代码跟原书的代码基本上是一致的 看到第四章,定制控件,觉得需要记录下些东西,所有把代码写到博客作为自己以后查阅的资料. 先上效果图 在src新建net.blogjava.mobile.widget/IconTextView.java 代码如下: package net.blogjava.mobile.widget; import android.content.Context; impor

2、继承和组合,绘制方式定制控件

定制控件的方式 1.继承其他控件类. 例如,EditText,是继承TextView. 例子:带图标的文本框 public IconTextView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.IconTextView); resourceId = typedArray.

Xcode中给控件添加颜色时自动显示出颜色

在iOS开发中,给一些控件设置颜色的时候,设置完不能立马看到颜色.必须要运行程序之后才能看到设置的颜色,如果颜色有偏差再回代码改参数,然后再运行看颜色很是麻烦.令人高兴得是Xcode有很多功能强大插件,使用起来非常方便.ColorSense-for-Xcode-master 就是一个非常好用的设置完颜色就能立即显示颜色的插件.效果图如下 插件安装方法: 1.到github上下载插件https://github.com/omz/ColorSense-for-Xcode 2.下载完插件之后用Xcod

WorldWind源码剖析系列:窗口定制控件类WorldWindow

在WorldWindow定制控件是从Control类派生出来的,需要自己操纵GDI+绘制所需要的界面效果,比较耗费精力(区别于用户控件UserControl,也叫组合控件,大多是对.NET工具箱提供的默认基础控件进行的组合和轻量级的改变,实现起来比较简单).为了明确定制控件Control和用户控件UserControl之间的体系关系,此处给出了Control类继承层次结构(源自MSDN): 在WorldWindow中星球球体的渲染和经纬网格的渲染时分别绘制的,星球由类World表示,经纬网格.

用继承和组合方式定制控件

1. 定制控件的方式 2. 带标签的文本编辑框(不带命名空间) 3. 带图标的文本框(带命名空间) 4. 控件属性验证 1. 定制控件的方式 <1>继承其他控件类 Ctrl + 左键 --->EditText <2>组合方式. 当前控件类从容器类继承, 并将若干个控件添加到当前容器中 <3>绘制控件. 也就是控件类从View继承, 并在onDraw方法中从零开始绘制控件, 例如TextView 2. 带标签的文本编辑框(不带命名空间)

3、用继承和组合方式定制控件

定制控件的方式 ? 继承其它控件类(EditText.Button) ? 组合方式.当前控件类从容器类继承,并将若干个控件添加到当前的容器中. ? 绘制控件,也就是控件类从View继承,并在onDraw方法中从零绘制 控件.例如,TextView.  带标签的文本编辑框(不带命名空间) 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http:

设置LISTControl控件某一行的背景和文字颜色

定义宏 用listcontrol的SetItemData设置某一行的属性,通过自定义属性标识实现. 自定义某行内容颜色属性: #define COLOR_DEFAULT 0 //默认颜色 #define COLOR_RED 1 //红色 #define COLOR_BLUE 2 //蓝色 定义消息 调用BOOL SetItemData(In int nItem, In DWORD_PTR dwData); 其中nItem为某行位置,下标以0开始,dwData可为自定义颜色属性. 然后在LISTC