Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools

How to perform clipping using API
[ All Languages » VB »  Region]

Total Hit ( 5552)

Rate this article:     Poor     Excellent 

 Submit Your Question/Comment about this article

Rating


Click here to download the attached file  


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

'// Some Path APIs
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

'// Some Clipping APIs
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

'//Some Drawing APIs
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

'//Some Region APIs
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 ' the number of points in each set

  Me.Cls

  BlkCnt = 2
  PtCnt = 9

  ReDim myPT(PtCnt - 1)
  ReDim numpoints(BlkCnt - 1)

  'We will draw 2 polygones using PolyPolyline
  'Note that since the first and last points are not connected in both polygones,
  'the beginning point is also specified as the last point in order
  'to close the figures.

  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

  ' save old clip region
  GetClipRgn Me.hdc, myOLDRgn

  With Me.Font       ' Set demo font
    .Name = "Times New Roman"
    .Italic = True
    .Bold = True
    .Size = 100
  End With

  ' OK. Start scanning drawing path

  BeginPath (Me.hdc)
  'draw anything
  Call PolyPolyline(Me.hdc, myPT(0), numpoints(0), BlkCnt)  ' draw polygons
  Me.CurrentX = 25: Me.CurrentY = 50
  Me.Print "GDI"      '//Draw Text
  EndPath (Me.hdc)

  '//Now actual draw on dc with red outlines
  Me.ForeColor = vbYellow
  Me.DrawWidth = 2

  Call PolyPolyline(Me.hdc, myPT(0), numpoints(0), BlkCnt)

  '///////////////////////////////////////////
  '//create region from scanned path
  'myRGN = PathToRegion(Me.hdc)
  '//clipping from region
  'SelectClipRgn Me.hdc, myRGN
  '///////////////////////////////////////////
  'or
  '//clipping from path
  SelectClipPath Me.hdc, RGN_AND

  '//draw bitmap from Picture1 (picturebox)
  Call DrawImageOnForm


  '//Check point is in clipping region for a specified "DC"
  Call PointVisibleDemo(Me.hdc, 210, 150)
  Call PointVisibleDemo(Me.hdc, 320, 150)

  '//Retrieves the dimensions of the tightest bounding rectangle that
  '//can be drawn around the current visible area on the device.
  '//(We will draw this rect later coz u can only draw on the clipped region for DC)
  GetClipBox Me.hdc, R

  SelectClipRgn Me.hdc, ByVal 0&  '//Pass NULL to remove clipping to draw outside the clipped area
  '//Now we can draw Region Bound coz device context clipping is removed
  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 & ")"

  '//restore old clip region
  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
  '////////////////////////////////////////////////////
  '//Create a combined Region
  R.Left = 50: R.Top = 50: R.Right = 200: R.Bottom = 200

  hRgn1 = CreateEllipticRgnIndirect(R)
  OffsetRect R, 50, 50
  hRgn2 = CreateRectRgnIndirect(R)
  '//We must pass some already existing region as a destination region so just create any empty rgn
  hRgnCombine = CreateRectRgnIndirect(RectNULL)
  CombineRgn hRgnCombine, hRgn1, hRgn2, RGN_OR  '//Take union of both regions

  '//save old clip region before you mess with that
  GetClipRgn Me.hdc, myOLDRgn

  '////////////////////////////////////////////////////

  '//set new clip region

  '//You can use SelectClipRgn or ExtSelectClipRgn to select clipping region but
  '//ExtSelectClipRgn gives you more option. Using ExtSelectClipRgn you can
  '//define how you want to select cliping region (i.e AND, OR, XOR)

  'SelectClipRgn Me.hdc, hRgnCombine
  'or
  ExtSelectClipRgn Me.hdc, hRgnCombine, RGN_AND
  'ExtSelectClipRgn Me.hdc, hRgnCombine, RGN_XOR '//Try this also

  '//After selecting you can offset clip region
  OffsetClipRgn Me.hdc, -50, 0
  '//draw bitmap from Picture1 (picturebox)
  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
  '////////////////////////////////////////////////////
  'Rectangle collision test with clipped area
  R.Left = 10: R.Top = 10: R.Right = 150: R.Bottom = 100
  'R.Left = 10: R.Top = 10: R.Right = 50: R.Bottom = 50 '//Try this

  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
  '////////////////////////////////////////////////////////

  '//restore old clip region
  SelectClipRgn Me.hdc, myOLDRgn

  'Now we dont need regions so remove them
  DeleteObject hRgn1
  DeleteObject hRgn2
  DeleteObject hRgnCombine
End Sub

Sub PointVisibleDemo(hdc As Long, xTest As Long, yTest As Long)
  '//Test visibility of a point for a specified DC using PtVisible API
  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()
  ' draw bitmap from Picture1 (picturebox)
  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


Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.