标签:blog http ar 使用 sp for 数据 on div
http://www.cnblogs.com/acuier 整整十几篇,省得我自己研究,学一下就可以了。
测试颜色:
// 找到了WM_PAINT消息处理,既然找到了,那么对WM_PAINT消息也算有个交代了,于是上面所有的WndProc全部正常结束。
// 除非TWinControl.WMPaint里面再继续执行复杂的调用,否则Button1.Update就算执行结束了。
procedure TWinControl.WMPaint(var Message: TWMPaint);
var
DC, MemDC: HDC;
MemBitmap, OldBitmap: HBITMAP;
PS: TPaintStruct;
begin
// 注意,这里是重画句柄控件,重画图形控件不在这里
// fixme 不知道什么时候是双缓冲
if not FDoubleBuffered or (Message.DC <> 0) then
begin
// 自己不把自己算做子控件,所以这个函数是用来重画子控件的。
// 想画自己,就得另外覆盖Paint;函数,但是发消息给子控件重画这件事情,这里已经帮助程序员写好了(子控件自己还是要覆盖Paint;才能保证正确画自己)
// 注意csCustomPaint这个风格
if not (csCustomPaint in ControlState) and (ControlCount = 0) then
inherited // 假牙,父类根本就没有相关函数,什么都不做。fixme,好像是通过父类来重画自己
else
PaintHandler(Message); // 一般走这里,给所有子控件做剪裁并重画(挨个发送WM_PAINT消息)
end
else
begin
// 准备内存画板,此时还没有Canvas,所以用API旧方法
DC := GetDC(0); // 参数0代表取得整个屏幕的DC
MemBitmap := CreateCompatibleBitmap(DC, ClientRect.Right, ClientRect.Bottom); // 创建当前DC的画板(大概是为了保留除了当前窗口以外的显示内容,跟画板的底板一样)
ReleaseDC(0, DC); // 留下MemBitmap,然后释放整个屏幕的DC
MemDC := CreateCompatibleDC(0); // 创建当前DC的兼容DC
OldBitmap := SelectObject(MemDC, MemBitmap); // 把MemBitmap画板放到MemDC里去,就可以准备在MemDC里画了
try
DC := BeginPaint(Handle, PS); // 返回值是指定Window的DC
// 双缓冲工作真正开始
Perform(WM_ERASEBKGND, MemDC, MemDC); // 当前控件使用MemDC擦除背景
Message.DC := MemDC; // 构建一个消息,把MemDC传入,当前控件和子控件都在MemDC上画
WMPaint(Message); // 递归调用函数(构建了一个消息,但不是发生消息),而且此时的DC不等于0,因此条件成立,进入块执行PaintHandler
Message.DC := 0; // 消息使用完毕,消息参数复位,但是通过消息得到的MemDC所有数据都在
// 画完了内存画板,准备切换
BitBlt(DC, 0, 0, ClientRect.Right, ClientRect.Bottom, MemDC, 0, 0, SRCCOPY); // 把画好所有控件的MemDC一次性拷贝到指定Window的DC
EndPaint(Handle, PS); // 结束画图过程
finally
SelectObject(MemDC, OldBitmap);
DeleteDC(MemDC);
DeleteObject(MemBitmap);
end;
end;
end;
标签:blog http ar 使用 sp for 数据 on div
原文地址:http://www.cnblogs.com/findumars/p/4109106.html