【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 2215|回复: 0

创建不规则窗体经验总汇

[复制链接]
发表于 2005-9-30 13:36:08 | 显示全部楼层 |阅读模式
很多人都很热衷于创建形状奇怪的窗体。而且不断的有热心的家伙们将他们的发现放到我们这里与大家分享。今天我将我所知道的方法总结一下。希望对大家有所帮助。<BR>一般来说,要创建一个不规则的窗体。我们需要使用一个Win32 API: SetwindowRgn。这个API您可以在Api浏览器中找到。这个Api的作用就是将窗体的“剪”成一个指定的形状。下面是这个Api声明于解释:<BR>Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long,ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long<BR>它有三个参数。<BR>第一个(hWnd)是用来指定被剪切的对象的句柄,比如Picture图形框等, 我们一般就是用窗体的hWnd属性;<BR>第二个(hRgb)指明剪切的形状, 即指定的几何图形特征, 此参数也必须由相应的API 函数提供说明。用那些APi可以创建一个您想要的区域(窗体的形状)。然后这些Api会返回一个数值。这个数值就是这个形状在Windows中的句柄(可以理解为身份证号码)。SetWindowsRgn可以通过这个数值来找到我们创建的那个区域;<BR>第三个(bRedraw)是一个布尔变量, 一般可设置为真(True)。<BR><BR>看来仅仅有SetWindowsRgn还不行。我们还必须创建一个区域。创建区域可以使用如下的一些Api:<BR>CreateRectRgn :  建立矩形区域,其参数分别为矩形的左上角坐标及右下角坐标。但是由于窗体默认就是一个矩形,所我们应该用不到它;<BR><BR><BR>CreateRoundRectRgn:建立圆角矩形区域,其参数分别为左上角及右下角坐标, 还有圆角直径等, 当圆角直径接近或超过矩形的长度时, 将呈现为圆或椭圆形;<BR><BR><BR>CreateEllipticRgn :建立椭圆矩形区域,参数分别椭圆的约束矩形左上角与左下角顶点的坐标;;<BR><BR><BR>所以现在我们就可以创建一下形状比较简单的窗体了。比如下面的代码我们就创建了一个椭圆形的窗体:<BR><BR>Option Explicit<BR>'Win32 Api 的声名<BR>rivate Declare Function CreateEllipticRgn Lib "gdi32" Alias "CreateEllipticRgn" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long<BR>rivate Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long,ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long<BR><BR>rivate Sub Form_Load()<BR>Dim Result As Long '声明变量用于保存“区域”的句柄<BR>Me.Show<BR>Result = CreateEllipticRgn(0, 0, 300, 200) '创建“区域”并将其句柄保存到变量中<BR>SetWindowRgn Me.Hwnd, Result, True '根据前面创建的区域对窗体进行“剪裁”<BR>End Sub <BR><BR>但是你要说,我想创建的窗体是一个人的形状或者是其他的不规则的形状呀!是的,上面的方法只能创建一些简单的几何图形。创建比较复杂形状的窗体我们仍然需要使用SetWindowRgb这个Api来对窗体进行“剪裁”。但是我们需要用其它的Api来创建复杂的“区域”。一般的,我们会用到下面的Api。这些Api配合使用就会得到复杂形状的区域。从而我们可以使用SetWindowRgb裁出窗体。<BR><BR>CreatePolygonRgn : 用于通过连接各个点来创建一个区域<BR><BR>CombineRgn: 用于对两个区域进行运算。比如合并两个区域或这是将两个区域相减、求交集等等。<BR><BR>下面我们来详细的介绍一下这两个Api:<BR>CreatePolygonRgb<BR><BR>Declare Function CreatePolygonRgn Lib "gdi32" Alias "CreatePolygonRgn" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long<BR><BR>参数一(lpPoint): POINTAPI类型的变量。POINTAPI是一个用于描述点坐标的结构。他有两个成员x与y。您可以在Api浏览器中找到它。在这里我们需要一个数组,并将这个属组的第一个元素作为这里的参数。<BR>参数二(nCount): 区域顶点的个数。比如一个三角形的区域有三个顶点。我们应该根据这个参数来确定上一个参数使用的数组的大小;<BR>参数三(nPolyFillMode): 指定区域的填充模式。我们可以使用两个常量作为参数:ALTERNATE和WINDING。这两个常量可以在Api浏览器中找到。我们在这里可以直接使用1.<BR><BR>CombineRgb<BR>Declare Function CombineRgn Lib "gdi32" Alias "CombineRgn" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long<BR><BR>参数一(hDestRgn): 目标区域的句柄;<BR>参数二(hSrcRgn1): 源区域一的句柄;<BR>参数三(hScrRgn2): 源区域二的句柄。<BR>参数四(nCombineMode): 合并模式。我们可以在Api浏览器中到这些常量作为它的参数:<BR>RGN_AND<BR>Creates the intersection of the two combined regions.<BR>RGN_COPY<BR>Creates a copy of the region identified by hrgnSrc1.<BR>RGN_DIFF<BR>Combines the parts of hrgnSrc1 that are not part of hrgnSrc2.<BR>RGN_OR<BR>Creates the union of two combined regions.<BR>RGN_XOR<BR>Creates the union of two combined regions except for any overlapping areas.<BR><BR>好了,下面我们来创建一个沙漏形的区域。<BR><BR>Option Explicit<BR>'Win32 API的声明<BR>rivate Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long<BR>rivate Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long<BR>rivate Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long<BR>rivate Type POINTAPI<BR>x As Long<BR>y As Long<BR>End Type<BR><BR>rivate Sub Form_Load()<BR>'声明变量<BR>Dim Result As Long<BR>Dim Points(5) As POINTAPI<BR><BR>'更改窗体大小<BR>With Me<BR>.Width = 5000<BR>.Height = 10000<BR>End With<BR><BR>'将区域的顶点坐标存入变量<BR>oints(0).x = 0<BR>oints(0).y = 0<BR>Points(1).x = 300<BR>Points(1).y = 0<BR>Points(2).x = 175<BR>Points(2).y = 300<BR>Points(3).x = 300<BR>Points(3).y = 600<BR>Points(4).x = 0<BR>Points(4).y = 600<BR>Points(5).x = 125<BR>Points(5).y = 300<BR><BR>'创建区域<BR>Result = CreatePolygonRgn(Points(0), 6, 1)<BR><BR>'“裁剪”窗体<BR>SetWindowRgn Me.hwnd, Result, True<BR><BR><BR>End Sub<BR><BR>另外,我们还应该注意一个Win32 ApieleteObject。 我们用Api创建了一个区域。虽然不可见,但是它却是一个对象。如果我们不将其删除,它就会存在于系统中消耗系统资源,所以我们不用的时候就应该将它删除掉。这个Api只有一个参数就是指定要删除对象的句柄。<BR><BR>好了,先讲到这里吧。下次我会教大家一种更奇妙的区域创建方法! <BR>
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2025-5-6 03:06

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表