To perform very complex clipping operations you can use a set of clipping APIs. From this sample code you will learn several techniques of clipping.
A clipping region is a region with edges that are either straight lines or curves. You can create simple or complex regions using various region APIs (i.e. CreateEllipticRgnIndirect, CreateRectRgnIndirect, CombineRgn etc.) and then select region for clipping using SelectClipRgn or ExtSelectClipRgn and then you can draw to the clipped DC whatever you want and your drawing will appear only within the clipped boundary. You can not draw outside the Clipped boundary of the DC until you remove clipping for the DC. A clip path is a region with edges that are straight lines, Bzier curves, or combinations of both. You can create simple or complex path using path APIs (i.e. BeginPath, EndPath etc.). You can convery path to region using PathToRegion and then call SelectClipRgn or ExtSelectClipRgn to clipping the generated region from path or you can directly call SelectClipPath which doesn't require extra call to PathToRegion API.
Here is the summary of some clipping APIs used in this example
SelectClipPath :This API generates a clipped area for a given DC. You can create path by calling BeginPath, some drawing APIs and then EndPath.
SelectClipRgn :This API generates a clipped area for a given DC. This function requires a handle to the exising Window Region. You can create Region by calling region APIs (i.e. CreateEllipticRgnIndirect, CreateRectRgnIndirect, CombineRgn etc.). Passing Null region removes the clipping from DC.
ExtSelectClipRgn :The ExtSelectClipRgn function combines the specified region with the current clipping region using the specified mode.
GetClipRgn :The GetClipRgn function retrieves a handle identifying the current application-defined clipping region for the specified device context. You can always get a copy of current clipped region for DC by calling GetClipRgn and later you can restore it by calling SelectClipRgn or ExtSelectClipRgn.
GetClipRgn :The GetClipBox function retrieves the dimensions of the tightest bounding rectangle that can be drawn around the current visible area on the device. The visible area is defined by the current clipping region or clip path, as well as any overlapping windows.
OffsetClipRgn :The OffsetClipRgn function moves the clipping region of a device context by the specified offsets.
IntersectClipRect :The IntersectClipRect function creates a new clipping region from the intersection of the current clipping region and the specified rectangle.
ExcludeClipRect :The ExcludeClipRect function creates a new clipping region that consists of the existing clipping region minus the specified rectangle.
PtVisible :The PtVisible function determines whether the specified point is within the clipping region of a device context.
RectVisible :The RectVisible function determines whether any part of the specified rectangle lies within the clipping region of a device context.
Now lets have real fun.
Step-By-Step Example
- Create a standard exe project - Add two command buttons and one picturebox ontrol on the form1. Set any image to Picture1 (Picturebox) - Add the following code to form1 |
Click here to copy the following block | Private Const SRCCOPY = &HCC0020
Private Const RGN_AND = 1 Private Const RGN_COPY = 5 Private Const RGN_DIFF = 4 Private Const RGN_OR = 2 Private Const RGN_XOR = 3
Private Type POINTAPI X As Long Y As Long End Type
Private Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type
Private Declare Function BeginPath Lib "gdi32" ( _ ByVal hdc As Long) As Long
Private Declare Function EndPath Lib "gdi32" ( _ ByVal hdc As Long) As Long
Private Declare Function PathToRegion Lib "gdi32" ( _ ByVal hdc As Long) As Long
Private Declare Function SelectClipPath Lib "gdi32.dll" ( _ ByVal hdc As Long, _ ByVal iMode As Long) As Long
Private Declare Function SelectClipRgn Lib "gdi32" ( _ ByVal hdc As Long, ByVal hRgn As Long) As Long
Private Declare Function ExtSelectClipRgn Lib "gdi32.dll" ( _ ByVal hdc As Long, _ ByVal hRgn As Long, _ ByVal fnMode As Long) As Long
Private Declare Function GetClipRgn Lib "gdi32" ( _ ByVal hdc As Long, ByVal hRgn As Long) As Long
Private Declare Function GetClipBox Lib "gdi32.dll" ( _ ByVal hdc As Long, _ ByRef lpRect As RECT) As Long
Private Declare Function OffsetClipRgn Lib "gdi32.dll" ( _ ByVal hdc As Long, _ ByVal X As Long, _ ByVal Y As Long) As Long
Private Declare Function IntersectClipRect Lib "gdi32.dll" ( _ ByVal hdc As Long, _ ByVal X1 As Long, _ ByVal Y1 As Long, _ ByVal X2 As Long, _ ByVal Y2 As Long) As Long
Private Declare Function ExcludeClipRect Lib "gdi32.dll" ( _ ByVal hdc As Long, _ ByVal X1 As Long, _ ByVal Y1 As Long, _ ByVal X2 As Long, _ ByVal Y2 As Long) As Long
Private Declare Function PtVisible Lib "gdi32.dll" ( _ ByVal hdc As Long, _ ByVal X As Long, _ ByVal Y As Long) As Long
Private Declare Function RectVisible Lib "gdi32.dll" ( _ ByVal hdc As Long, _ ByRef lpRect As RECT) As Long
Private Declare Function BitBlt Lib "gdi32" ( _ ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, _ ByVal nWidth As Long, ByVal nHeight As Long, _ ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, _ ByVal dwRop As Long) As Long
Private Declare Function PolyPolyline Lib "gdi32.dll" ( _ ByVal hdc As Long, lpPoint As POINTAPI, lpdwPolyPoints As Long, ByVal cCount As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" ( _ ByVal hObject As Long) As Long
Private Declare Function CombineRgn Lib "gdi32.dll" ( _ ByVal hDestRgn As Long, _ ByVal hSrcRgn1 As Long, _ ByVal hSrcRgn2 As Long, _ ByVal nCombineMode As Long) As Long
Private Declare Function CreateEllipticRgnIndirect Lib "gdi32.dll" ( _ ByRef lpRect As RECT) As Long
Private Declare Function CreateRectRgnIndirect Lib "gdi32.dll" ( _ ByRef lpRect As RECT) As Long
Private Declare Function OffsetRect Lib "user32.dll" ( _ ByRef lpRect As RECT, _ ByVal X As Long, _ ByVal Y As Long) As Long
Private Sub ClipPathDemo() Dim R As RECT Dim PtCnt, BlkCnt As Long Dim myPT() As POINTAPI, myRGN As Long, myOLDRgn As Long Dim numpoints() As Long
Me.Cls
BlkCnt = 2 PtCnt = 9
ReDim myPT(PtCnt - 1) ReDim numpoints(BlkCnt - 1)
myPT(0).X = 50: myPT(0).Y = 55 myPT(1).X = 300: myPT(1).Y = 57 myPT(2).X = 58: myPT(2).Y = 189 myPT(3).X = 150: myPT(3).Y = 180 myPT(4).X = 50: myPT(4).Y = 55 numpoints(0) = 5
myPT(5).X = 325: myPT(5).Y = 57 myPT(6).X = 310: myPT(6).Y = 200 myPT(7).X = 35: myPT(7).Y = 195 myPT(8).X = 325: myPT(8).Y = 57 numpoints(1) = 4
GetClipRgn Me.hdc, myOLDRgn
With Me.Font .Name = "Times New Roman" .Italic = True .Bold = True .Size = 100 End With
BeginPath (Me.hdc) Call PolyPolyline(Me.hdc, myPT(0), numpoints(0), BlkCnt) Me.CurrentX = 25: Me.CurrentY = 50 Me.Print "GDI" EndPath (Me.hdc)
Me.ForeColor = vbYellow Me.DrawWidth = 2
Call PolyPolyline(Me.hdc, myPT(0), numpoints(0), BlkCnt)
SelectClipPath Me.hdc, RGN_AND
Call DrawImageOnForm
Call PointVisibleDemo(Me.hdc, 210, 150) Call PointVisibleDemo(Me.hdc, 320, 150)
GetClipBox Me.hdc, R
SelectClipRgn Me.hdc, ByVal 0& Me.ForeColor = vbBlue Me.DrawWidth = 2 Me.Line (R.Left, R.Top)-(R.Right, R.Bottom), , B Me.Caption = "Region Bound => (" & R.Left & "," & R.Top & ")(" & R.Right & "," & R.Bottom & ")"
SelectClipRgn Me.hdc, myOLDRgn
If myRGN > 0 Then DeleteObject myRGN End Sub
Private Sub ClipRegionDemo() Dim R As RECT, RectNULL As RECT Dim hRgn1 As Long, hRgn2 As Long, hRgnCombine As Long, myOLDRgn As Long R.Left = 50: R.Top = 50: R.Right = 200: R.Bottom = 200
hRgn1 = CreateEllipticRgnIndirect(R) OffsetRect R, 50, 50 hRgn2 = CreateRectRgnIndirect(R) hRgnCombine = CreateRectRgnIndirect(RectNULL) CombineRgn hRgnCombine, hRgn1, hRgn2, RGN_OR
GetClipRgn Me.hdc, myOLDRgn
ExtSelectClipRgn Me.hdc, hRgnCombine, RGN_AND
OffsetClipRgn Me.hdc, -50, 0 Call DrawImageOnForm MsgBox "Check the Offset demo" Me.Cls
SelectClipRgn Me.hdc, hRgnCombine OffsetClipRgn Me.hdc, 50, 0 Call DrawImageOnForm Me.ForeColor = vbYellow Me.DrawWidth = 4
MsgBox "Check the intersect rect with clipped region demo" Me.Cls
SelectClipRgn Me.hdc, hRgnCombine IntersectClipRect Me.hdc, R.Left - 50, R.Top - 30, R.Right + 50, R.Bottom - 50 Call DrawImageOnForm Me.Line (R.Left - 50, R.Top - 30)-(R.Right + 50, R.Bottom - 50), , B
MsgBox "Check again" Me.Cls
SelectClipRgn Me.hdc, hRgnCombine IntersectClipRect Me.hdc, R.Left - 50, R.Top, R.Right, R.Bottom Call DrawImageOnForm Me.Line (R.Left - 50, R.Top)-(R.Right, R.Bottom), , B MsgBox "Check the exclude rectangle from clipped region" Me.Cls
SelectClipRgn Me.hdc, hRgnCombine ExcludeClipRect Me.hdc, R.Left - 150, R.Top + 30, R.Right - 50, R.Bottom - 60 Call DrawImageOnForm Me.Line (R.Left - 150, R.Top + 30)-(R.Right - 50, R.Bottom - 60), , B R.Left = 10: R.Top = 10: R.Right = 150: R.Bottom = 100
Me.ForeColor = vbRed If RectVisible(Me.hdc, R) = 1 Then Me.Line (R.Left, R.Top)-(R.Right, R.Bottom), , B MsgBox "Some part of rectangle falls under the clipped region (Check the Red Rectangle)" Else Me.Line (R.Left, R.Top)-(R.Right, R.Bottom), , B MsgBox "Rectangle is fully outside the clipped region (Check the Red Rectangle)" End If
SelectClipRgn Me.hdc, myOLDRgn
DeleteObject hRgn1 DeleteObject hRgn2 DeleteObject hRgnCombine End Sub
Sub PointVisibleDemo(hdc As Long, xTest As Long, yTest As Long) Me.ForeColor = vbGreen Me.DrawWidth = 2 Me.Circle (xTest, yTest), 15 Me.Line (xTest - 25, yTest)-(xTest + 25, yTest) Me.Line (xTest, yTest - 25)-(xTest, yTest + 25)
If PtVisible(hdc, xTest, yTest) = 1 Then MsgBox "(" & xTest & "," & yTest & ") is visible for form1 hDC clipping region" Else MsgBox "(" & xTest & "," & yTest & ") is not visible for form1 hDC clipping region" End If End Sub
Private Sub Command1_Click() Me.Cls ClipPathDemo End Sub
Private Sub Command2_Click() Me.Cls ClipRegionDemo End Sub
Private Sub Form_load() Picture1.AutoRedraw = True Me.AutoRedraw = True Picture1.AutoSize = True Picture1.Visible = False Me.ScaleMode = 3 Command1.Caption = "Clipping Path Demo" Command2.Caption = "Clipping Region Demo"
Call DrawImageOnForm End Sub
Sub DrawImageOnForm() BitBlt Me.hdc, 0, 52, 350, 150, Picture1.hdc, 0, 0, SRCCOPY End Sub Private Sub l8_Click() Shell "explorer http://www.binaryworld.net", vbNormalFocus End Sub |
|