delphi 不规则窗体与桌面宠物
二、支持区域操作的编程接口
在Windows的API函数中有一组用于区域操作的函数,可以用来生成区域、合并区域、获取区域数据、根据数据生成区域、把区域和窗体联系等,其中常用的几个函数有:生成矩形区域的CreateRectRgn函数,生成椭圆区域的CreateEllipticRgn函数,合并两个区域的CombinetRgn函数,从内存区域数据生成区域的ExCreateRegion函数,获得区域数据的GetRegionData函数,把区域和窗体联系的SetWindowRgn函数。
在Delphi中,这些常用的区域函数都被封装到了Windows单元中,在实际应用中,只须在单元文件中引用Windows单元(默认),即可直接使用这些函数。
三、多态窗体的生成原理
1、不规则窗体的生成
在实际操作过程中,可以直接利用CreateEllipticRgn函数直接生成圆形窗体,也可以利用CreatePolygonRgn函数生成任意非矩形窗体。如果目标区域过于复杂,可以把目标划分成规则的多个小区域分别建立,再把各区域合并,即可得到目标区域。
对于要生成基于位图图案的窗体,可以首先将位图背景色设为单一色,再按位图图案上的色彩进行行扫描,每扫描到非背景色,则产生一个像素宽的矩形区域,并入已形成的区域。这样当整个图案扫描完毕,以位图轮廓构成的区域形成,然后把位图图案绘入窗体,可以得到一个图形窗体。
2、动画的生成
在窗体创建时,建立起相对于每个位图图案的区域数据,在程序运行时,通过线程轮换调用数据产生区域,并在窗体上显示相应的位图图案,以达到动画效果。
四、位图图案窗体的创建
1、位图图案区域数据的生成函数GetRgnData
procedure GetRgnData (Bmp: TBitmap; var nCount: Cardinal; var lpRgnData: PRgnData);
var
h, w, i, j: Integer;
tc: TColor;
hrgn1, hrgn2: HRGN;
begin
h := Bmp.Height;
w := Bmp.Width;
//获取位图第一象素点的颜色值,背景颜色
tc := Bmp.Canvas.Pixels[0, 0];
//生成矩形区域
hrgn1 := CreateRectRgn (0, 0, w, h);
try
for i := 0 to h-1 do
begin
for j := 0 to w-1 do
begin
//判断当前象素点的颜色值是否与背景色相同
if Bmp.Canvas.Pixels[j, i] = tc then
begin
hrgn2 := CreateRectRgn (j, i, j+1, i+1);
if hrgn2 <> 0 then
//抠去hrgn2数据区域
CombineRgn (hrgn1, hrgn1, hrgn2, RGN_DIFF);
DeleteObject (hrgn2);
end;
end;
end;
//获取hrgn1数据区域大小
nCount := GetRegionData (hrgn1, 0, nil);
//分配内存空间给临时区域指针lpRgnData
GetMem (lpRgnData, nCount * sizeof(TRgnData));
//获取数据
GetRegionData (hrgn1, nCount, lpRgnData);
except
ShowMessage ('区域数据生成出错');
end;
DeleteObject (hrgn1);
end;
2、动画线程的实现
⑴ 线程的定义
TAnimThread = class (TThread)
private
FIndex: Integer;
OwnerForm: TForm;
procedure DrawAnimPic;
protected
procedure Execute; override;
public
constructor Create (Form: TForm); {override;}
end;
说明:①FIndex所要显示的位图索引值,OwnerForm指定当前窗体;
②DrawAnimPic线程中动画绘制窗体过程。
⑵ 线程的实现
constructor TAnimThread.Create (Form: TForm);
begin
OwnerForm := Form;
FIndex := 0;
inherited Create (False);
end;
procedure TAnimThread.DrawAnimPic;
var
Bmp: TBitmap;
w, h: Integer;
rgn: HRGN;
begin
Bmp := AnimBmp[FIndex];
w := Bmp.Width;
h := Bmp.Height;
//重新设置窗体的尺寸
OwnerForm.Width := w;
OwnerForm.Height := h;
//从内存区域数据生成区域
rgn := ExtCreateRegion (nil, nCount[FIndex], TRData[FIndex]^);
//把区域和窗体联系起来
SetWindowRgn (OwnerForm.Handle, rgn, True);
DeleteObject (rgn);
//在窗体画布上绘制位图图案
BitBlt (OwnerForm.Canvas.Handle, 0, 0, w, h, Bmp.Canvas.Handle, 0, 0, SRCCOPY);
end;
procedure TAnimThread.Execute;
begin
inherited;
//反复执行,直至线程终止
repeat
FIndex := FIndex mod 6;
//同步绘制过程DrawAnimPic
Synchronize (DrawAnimPic);
Sleep (300);
Inc (FIndex);
until Terminated;
end;
说明:① 在绘制过程DrawAnimPic所使用到的变量定义在单元文件内,其定义:
AnimBmp: array[0..5] of TBitmap;
nCount: array[0..5] of Cardinal;
TRData: array[0..5] of PRgnData;
以上变量均在窗体创建过程中赋值,在窗体销毁前释放。
②在线程的执行(Execute)过程中,不能直接调用DrawAnimPic过程,以免产生VCL组件读写冲突,所以必须使用同步函数Synchronize进行协调。
五、结束语
通过本次学习,让读者初步了解Delphi编程中线程的创建及使用,同时掌握如何在Delphi编程过程中调用Windows 的API函数,来建立个性化的应用程序。本文简述了一个动画窗体的实现过程,当然要真正作为一个宠物,它必须有自己的“思想”,会随机地做出一些动作,这就需要在程序中可以随机地调取一些动作序列,其程序过程读者可根据自己的 兴趣进一步完善。
delphi 不规则窗体与桌面宠物的更多相关文章
- Delphi 实现不规则窗体
最近为了要兼容XP系统(守旧的市场),又需要做出产品的特效,不得不从头学习一下这门 “聪明的语言” . 开发环境: win10 Delphi 10.2 Version 25.0.26309.314 产 ...
- WPF中不规则窗体与WebBrowser控件的兼容问题解决办法
原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...
- Qt 不规则窗体 – 鼠标点击穿透(Linux也可以,有对x11的配置的方法)
之前写过如何用 Qt 现成的方法写出无边框半透明的不规则窗体:<Qt 不规则窗体 – 无边框半透明> 其实有一个很特殊的窗体属性一直以来都伴随着不规则窗体出现,这就是本文要介绍的鼠标点击穿 ...
- WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案
首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如 WPF中不规则窗体与WebBrowser控件的兼 ...
- WPF窗体置于桌面最底层
在WPF中设置窗体的Topmost属性可以将窗体永远置于顶部,但是没有提供Bottommost属性将窗体置底.若果要将窗体置于桌面的最底部,就需要使用Windows API来实现了.解决方案如下: 1 ...
- QT实现不规则窗体
看到网上有很多不规则窗体的实现,效果很酷.于是使用QT也实现了一个,QT的不规则窗体实现非常简单,只需要设置一个mask(遮掩)图片,这个图片的格式可以使用png或bmp格式,我使用了png格式,默认 ...
- WPF界面设计技巧(1)—不规则窗体图文指南
原文:WPF界面设计技巧(1)-不规则窗体图文指南 初到园子,奉上第一篇入门级教程,请勿见笑. 以往WinForm编程中,实现不规则窗体是有一定难度的,更难的是不规则窗体的边缘抗锯齿及局部透明处理.而 ...
- [小结][N种方法]实现WPF不规则窗体
原文:[小结][N种方法]实现WPF不规则窗体 WPF实现不规则窗体,方法很多很多多.... 本文总结DebugLZQ认为简洁高效的几种方法 实现WPF不规则窗体的几种常用的方法如下: 1.使用Ble ...
- WPF设计の不规则窗体
我们在工作中,经常会需要画一些不规则的窗体,现在总结如下. 一.利用VisualBrush实现.这依赖于VisualBrush的特性,任何控件可以作为画刷,而画刷又可以作为背景. 此种方法可以用于实现 ...
随机推荐
- HIVE常用函数(1)聚合函数和序列函数
SUM--sum(汇总字段) over (partition by 分组字段 order by 排序字段) 如果不指定ROWS BETWEEN,默认为从起点到当前行;如果不指定ORDER BY,则将分 ...
- SQL LIKE 运算符
SQL LIKE 运算符 在WHERE子句中使用LIKE运算符来搜索列中的指定模式. SQL LIKE 操作符 LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式. 有两个通配符与LIKE运 ...
- HTML5新表单新功能解析
HTML5新增了很多属性功能.但是有兼容性问题,因为这些表单功能新增的.我这里做了一个简单的练习,方便参考.如果完全兼容的话,那我们写表单的时候就省了很多代码以及各种判断. <!DOCTYPE ...
- css创建
CSS 创建 当读到一个样式表时,浏览器会根据它来格式化 HTML 文档. 如何插入样式表 插入样式表的方法有三种: 外部样式表(External style sheet) 内部样式表(Interna ...
- 火狐RESTClient和HttpRequester, Chrome的Postman使用详解
Chrome下有著名的Postman,那火狐也有它的左膀右臂,那就是RESTClient和HttpRequester.这两款工具都是火狐的插件,主要用来模拟发送HTTP请求,HTTP请求最常用的两种方 ...
- robotframework悬浮菜单定位问题
有些菜单是悬浮菜单,鼠标点上去下级元素才会显示.比如在第一个菜单中选择后会触发二级菜单的某事件,触发二级菜单又去点三级菜单.. 最开始就用click element去点击了,可是菜单会缩回去,就有 ...
- error LNK2019: 无法解析的外部符号 _PhInitializePhLib,该符号在函数 _EnumHandle 中被引用
编译时提示上面的错误,而确实应用了该函数的库文件,直接搜索lib文件内容,发送该函数的声明如下_PhInitializePhLib@0 说明函数的编译方式和库文件的编译方式不同,发现该工程的调用约定为 ...
- 数据可视化(Echart) :柱状图、折线图、饼图等六种基本图表的特点及适用场合
数据可视化(Echart) 柱状图.折线图.饼图等六种基本图表的特点及适用场合 参考网址 效果图 源码 <!DOCTYPE html> <html> <head> ...
- Lilo的实现
书承上文:http://www.cnblogs.com/long123king/p/3549267.html 我们找一份Lilo的源码来看一下 http://freecode.com/projects ...
- UVA 11178 Morley's Theorem (坐标旋转)
题目链接:UVA 11178 Description Input Output Sample Input Sample Output Solution 题意 \(Morley's\ theorem\) ...