如果有一个不规则的封闭区域,我们如何确定Mouse是在该范围之内呢?假设有一区域 如下: + + P3 (110, 30) ┃ ┃ ┃ ┃ P6+ + + + P1(150,70) ┃ / P7+ + / P8 / * P0 (100,100)
上面的这个区域,是由9个点所围成的(* 及 + 代表点),我们以* 的那个点为P0,以反时锺 方向循行各个点,分别是P1到P8,其萤幕座标如下: 点 = ( X , Y ) P0 = (100, 100) P1 = (150, 70) P2 = (110, 70) P3 = (110, 30) P4 = (50, 30) P5 = (50, 70) P6 = ( 30, 70) P7 = (30, 85) P8 = (85, 85)
假设有一个点(Px, Py),那这个点有没有落在该区呢?这需要使用Region的观念,PtInRegion API 函数可用来检验某个点标是否位於某一区域内,PtInRegion API函数含有三个叁数, 叁数一须传入 hRegion(handle of Region,区域代码)、叁数二、三传入位置 (X, Y),如果 (X, Y) 位於 hRegion 所定义的区域之内,则 PtInRegion 传回非0的值,否则传回 0
Declare Function PtInRegion Lib "gdi32" (ByVal hRgn As Long, ByVal X As Long, ByVal Y As Long) As Long
那麽剩下的就是hRegion如何取得了,有以下几种方式: hRegion = CreateRectRgn(Px1, Py1,Px2, Py2) 产生一榘形Region ,(Px1, Py1) (Px2,Py2)是榘形的角两点
hRegion = CreateRectRgn(Px1, Py1,Px2, Py2) 则是 建立圆形Region,(Px1, Py1) (Px2,Py2)「围住圆形之最小方形的两个对角」
而本例中的9个点则是 p(0).X = 100: p(0).Y = 100 p(1).X = 150: p(1).Y = 70 p(2).X = 110: p(2).Y = 70 p(3).X = 110: p(3).Y = 30 p(4).X = 50: p(4).Y = 30 p(5).X = 50: p(5).Y = 70 p(6).X = 30: p(6).Y = 70 p(7).X = 30: p(7).Y = 85 p(8).X = 85: p(8).Y = 85
' 叁数一传入阵列,叁数二传入点数,叁数三指定成 ALTERNATE 常数 hRegion = CreatePolygonRgn(p(0), 9, ALTERNATE)
好了,这个东东另外可应用於何处呢?第一个,它可以用在於Region中显示图形,也就是 说,如果您的Region是不规则的或圆形的,那麽该图就会只显示Region范围,这需另外用
Call FillRgn(hdc, hRegion, hBrush)
第三个叁数是hBrush,那代表於hDc的hRegion区域中,以hBrush的Brush将该Region填满, 如果是NT,那麽hBrush可以是一个很大的BitMap图,但95只能是一个8*8的BitMap,超过了 也没有用,所以了,在NT中,我们可以将一个大大的图,画在Region中,而且超出Region 的部份不会画出来,那是否很有趣?而95的使用者就没有办法看到。如果,您使用SelectObject 如: Call SelectObject ( form1.hDc, hRegion ) 那麽,您在form1上的绘图,就被局限在hRegion所指的范围,画不出去了。例如上例中
me.ScaleMode = 3 hRegion = CreatePolygonRgn(p(0), 9, ALTERNATE) Call SelectObject(Me.hDc, hRegion) Me.Line (10, 70) - (200, 70)
原本会在(10,70) - (200, 70) 有一条水平线,但是,现在会发现线条仅在hRegion所指的区域中 出现,这个留给您Testing;如果单只这个功能还没有什麽,不同的Region尚可以合并成 一个Region,而且可以选择使用and、or、xor、diff、copy的方式来合并,(使用以下API) 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
Public Const RGN_AND = 1 Public Const RGN_COPY = 5 Public Const RGN_DIFF = 4 Public Const RGN_OR = 2 Public Const RGN_XOR = 3
如此设计出来的Region之形状可能就变得很复杂,在上绘图便会有特殊效果。这个我也没 有范例,若有兴趣的人可以试看看,而後将程式码给我,以便分享。
另外,更可以用在不规则形Button的 模拟,怎麽做呢,首先,您需自行画不规则的图, 看您的Form需几个这种Button就同时画在同一张图,并安排好其位置,因为这张图等一下 要当作Form的底图,如此,该Form就有表面上看来有不规则的Button了,而再来便是定义 该不规则区域的Region,产生hRegion,而後便可以在Form_MouseDown中来模拟Mouse按 下的效果了。 最後,我也用这个技术模拟Run Time中移动Line 物件,记不记得Line物件只能在Design Time 中来改变位置、大小,Run Time时只能乾瞪眼,这看一下Run Time 移动Line物件 Option ExplicitConst ALTERNATE = 1Const WINDING = 2Private Type POINTAPI X As Long Y As LongEnd TypePrivate Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As LongPrivate Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As LongPrivate Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As LongPrivate Declare Function PtInRegion Lib "gdi32" (ByVal hRgn As Long, ByVal X As Long, ByVal Y As Long) As LongPrivate Declare Function FillRgn Lib "gdi32" (ByVal hdc As Long, ByVal hRgn As Long, ByVal hBrush As Long) As LongPrivate Declare Function CreatePatternBrush Lib "gdi32" (ByVal hBitmap As Long) As LongPrivate Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As LongPrivate Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As LongDim hRegion As LongDim hBrush As LongDim pic1 As New StdPicturePrivate Sub Command1_Click()Call FillRgn(Me.hdc, hRegion, hBrush)End SubPrivate Sub Form_Load()Dim p(8) As POINTAPIMe.ScaleMode = 3p(0).X = 100: p(0).Y = 100p(1).X = 150: p(1).Y = 70p(2).X = 110: p(2).Y = 70p(3).X = 110: p(3).Y = 30p(4).X = 50: p(4).Y = 30p(5).X = 50: p(5).Y = 70p(6).X = 30: p(6).Y = 70p(7).X = 30: p(7).Y = 85p(8).X = 85: p(8).Y = 85hRegion = CreatePolygonRgn(p(0), 9, ALTERNATE)hBrush = CreateSolidBrush(RGB(255, 0, 0)) '在95中用这一行' 如果是NT的使用者,可以改用以下两行,并自行更动图形档' Set pic1 = LoadPicture("e:\logo.bmp")' hBrush = CreatePatternBrush(pic1.Handle)End SubPrivate Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) If PtInRegion(hRegion, X, Y) Then Debug.Print "In 在多边形区域" End IfEnd SubPrivate Sub Form_Unload(Cancel As Integer)DeleteObject hRegionDeleteObject hBrushEnd Sub
Mouse是否处於不规则区域内 |