PowerBuilder中创建的窗口都是标准的矩形,借助API的CreateEllipticRgn()和SetWindowRgn()函数能实现圆形窗口
CreateEllipticRgn()函数的功能是创建一个椭圆,该椭圆与X1,Y1和X2,Y2坐标点确定矩形内切,执行成功则为区域句柄,失败则为0
SetWindowRgn()是一个改变窗口区域的API函数,通常所有的windows窗口都是矩形的,窗口一旦存在就含有一个矩形区域。此汉书允许放弃该区域,并创建圆形,星形窗口,甚至是任意形状,执行成功为非0值,失败则为0
参数说明:hWnd :将设置区域的窗口;
hRgn:将设置区域的句柄;
hRedraw:若为true,则立即重画窗口;
注意:在窗口的适当位置防止用于关闭窗口的命令按钮,因为形状窗口没有右上角的关闭按钮
实操:1.在GlobalExternal Functions申明函数
//圆形窗口设置
FUNCTION ulong CreateEllipticRgn(ulong X1,ulong Y1,ulong X2,ulong Y2) LIBRARY "gdi32.dll"
FUNCTION ulong SetWindowRgn(ulong hWnd,ulong hRgn,boolean bRedraw) LIBRARY "user32.dll"
2.在窗口的open事件中添加代码
long ll_handle
//创建圆形,其中参数为左上到右下的坐标值
ll_handle = CreateEllipticRgn (30, 30,600,600)
SetWindowRgn(handle(this), ll_handle, true)
下面我介绍一下程序中主要用到的几个 API 函数:
1. 创建一个圆角矩形 CreateRoundRectRgn
CreateRoundRectRgn
PB 声明
FUNCTION ulong CreateRoundRectRgn(Long x1, Long y1, Long x2, Long y2, Long x3, Long y3) library “gdi32”
说明
创建一个圆角矩形,该矩形由 X1, Y1-X2, Y2 确定,并由 X3, Y3 确定的椭圆描述圆角弧度
返回值
Long,执行成功则为区域句柄,失败则为 0
参数表
参数 类型及说明
X1,Y1 Long,矩形左上角的 X, Y 坐标
X2,Y2 Long,矩形右下角的 X, Y 坐标
X3 Long,圆角椭圆的宽。其范围从 0(没有圆角)到矩形宽(全圆)
Y3 Long,圆角椭圆的高。其范围从 0(没有圆角)到矩形高(全圆)
注解
不用时一定要用 DeleteObject 函数删除该区域
用该函数创建的区域与用 RoundRect API 函数画的圆角矩形不完全相同,因为本矩形的右边和下边不包括
在区域之内
2. 创建一个由一系列点围成的区域 CreatePolygonRgn
CreatePolygonRgn
PB 声明
FUNCTION ulong CreatePolygonRgn (ref ws_position lppt[], int cPoints, int fnPolyFillMode ) Library “gdi32”
说明
创建一个由一系列点围成的区域。 windows 在需要时自动将最后点与第一点相连以封闭多边形
返回值
Long,执行成功为创建的区域句柄,失败则为 0
参数表
参数 类型及说明
//其中第 1 个参数为多边形各个顶点坐标值的数组
//其中第 2 个参数为多边形边数,可修改,配合数组值
//其中第 3 个参数为填充模式 ALTERNATE /WINDING
lpPoint POINTAPI, nCount 个 POINTAPI 结构中的第一个 POINTAPI 结构
Long,描述多边形填充模式。可为 ALTERNATE 或 WINDING 常数。参考
SetPolyFillMode 函数对多边形填充模式的解释
注解
不用时一定要用 DeleteObject 函数删除该区域
3. 创建一个椭圆 CreateEllipticRgn
CreateEllipticRgn
PB 声明
FUNCTION ulong CreateEllipticRgn( Long x1, Long y1, Long x2, Long y2) library “gdi32”
说明
创建一个椭圆,该椭圆与 X1, Y1 和 X2, Y2 坐标点确定的矩形内切
返回值
Long,执行成功则为区域句柄,失败则为零
参数表
参数 类型及说明
X1,Y1 Long,矩形左上角 X, Y 坐标
X2,Y2 Long,矩形右下角 X, Y 坐标
注解
不用时一定要用 DeleteObject 函数删除区域。用 Ellipse API 函数绘出的椭圆与该椭圆区域不完全相同,
因为本函数的绘图计算不包括矩形的下边和右边
4. 改变窗口的区域 SetWindowRgn, 这是最重要的一个函数
SetWindowRgn
PB 声明
FUNCTION ulong SetWindowRgn(ulong hWnd,ulong hRgn,boolean bRedraw) LIBRARY “user32”
说明
这是那些很难有人注意到的对编程者来说是个巨大的宝藏的隐含的 API 函数中的一个。 本函数允许您改变
窗口的区域。 通常所有窗口都是矩形的——窗口一旦存在就含有一个矩形区域。 本函数允许您放弃该区域。
这意味着您可以创建圆的、星形的窗口,也可以将它分为两个或许多部分——实际上可以是任何形状
返回值
Long,执行成功为非零值,失败为 0
参数表
参数 类型及说明
hWnd Long,将设置其区域的窗口
hRgn
Long,将设置的区域的句柄,一旦设置了该区域, 就不能使用或修改该区域句
柄,也不要删除它
bRedraw Boolean,若为 TRUE,则立即重画窗口
注解
为区域指定的所有坐标都以窗口坐标(不是客户坐标) 表示, 它们以整个窗口(包括标题栏和边框) 的左
上角为起点
5. 合并区域函数 CombineRgn
CombineRgn
PB 声明
FUNCTION ulong CombineRgn(Long hDestRgn, Long hSrcRgn1, Long hSrcRgn2, Long nCombineMode )
LIBRARY “gdi32”
说明
将两个区域组合为一个新区域
返回值
Long,下列常数之一:
COMPLEXREGION:区域有互相交叠的边界
SIMPLEREGION:区域边界没有互相交叠
NULLREGION:区域为空
ERRORAPI: 不能创建组合区域
参数表
参数 类型及说明
hDestRgn Long,包含组合结果的区域句柄
hSrcRgn1 Long,源区域 1
hSrcRgn2 Long,源区域 2
Long,组合两区域的方法。可设为下述常数
RGN_AND hDestRgn 被设置为两个源区域的交集
RGN_COPY hDestRgn 被设置为 hSrcRgn1 的拷贝
RGN_DIFF
hDestRgn 被 设 置 为 hSrcRgn1 中 与
hSrcRgn2 不相交的部分
RGN_OR hDestRgn 被设置为两个区域的并集
nCombineMode
RGN_XOR
hDestRgn 被设置为除两个源区域 OR 之
外的部分
6. 删除 GDI 对象 DeleteObject
DeleteObject
PB 声明
FUNCTION ulong DeleteObject(ulong hObject) LIBRARY “gdi32.dll”
说明
用这个函数删除 GDI 对象, 比如画笔、 刷子、 字体、 位图、 区域以及调色板等等。 对象使用的所有系统资
源都会被释放
返回值
Long,非零表示成功,零表示失败
参数表
参数 类型及说明
hObject Long,一个 GDI 对象的句柄
注解
不要删除一个已选入设备场景的画笔、 刷子或位图。 如删除以位图为基础的阴影(图案) 刷子,位图不会
由这个函数删除——只有刷子被删掉
三、部分核心实现代码
圆形窗口的代码:
long ll_x1, ll_x2, ll_x3
long ll_y1, ll_y2, ll_y3
long ll_handle
long ll_data
//取窗口的宽度
ll_data = UnitsToPixels(parent.width, xunitstopixels!)
ll_data = PixelsToUnits(ll_data, ypixelstounits!)
parent.height = ll_data
ll_x1 = 10
ll_y1 = 25
ll_x2 = UnitsToPixels(parent.width, xunitstopixels!) - 10
ll_y2 = UnitsToPixels(parent.height, yunitstopixels!) - 10
//创建一个圆形区域
ll_handle = CreateEllipticRgn(ll_x1, ll_y1, ll_x2, ll_y2)
SetwindowRgn(handle(parent), ll_handle, true)
return 1