Option Explicit On 
Option Strict On

'##############################
'Class: BlitterChip
'Author: Adam "wossname" Ward
'Date: 27 April 2005
'Purpose: Wrapper for the WIN32 BitBlt() API Function
'##############################

Public NotInheritable Class BlitterChip

	Public Enum BLITMODE As Integer
		DestInvert = &H550009		  'Inverts the destination bitmap.
		MergeCopy = &HC000CA		  'Combines the pattern and the source bitmap.
		MergePaint = &HBB0226		 'Combines the inverted source bitmap with the destination bitmap.
		NotSrcCopy = &H330008		 'Copies the inverted source bitmap to the destination.
		NotSrcErase = &H1100A6		 'Inverts the result of combining the destination and source bitmaps.
		SrcAnd = &H8800C6		  'Combines pixels of the destination and source bitmaps.
		SrcCopy = &HCC0020		 'Copies the source bitmap to the destination bitmap.
		SrcErase = &H440328		 'Inverts the destination bitmap; combines the result with the source bitmap.
		SrcInvert = &H660046		 'Combines pixels of the destination and source bitmaps.
		SrcPaint = &HEE0086		 'Combines pixels of the destination and source bitmaps.
	End Enum

	'the main function
	Private Declare Auto Function BitBlt Lib "gdi32" Alias "BitBlt" (ByVal hDestDC As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hSrcDC As Integer, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal dwRop As Integer) As Integer
	Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) As Integer

	Public Shared Function ScreenGrab(ByVal GrabRect As Rectangle) As Bitmap
		'returns a screengrab of a known area of the desktop

		Dim destBMP As Bitmap = New Bitmap(GrabRect.Width, GrabRect.Height)
		Dim gDest As Graphics = Graphics.FromImage(destBMP)
		Dim DestHDC As IntPtr = gDest.GetHdc()

		'copy the pixel data
		BitBlt(DestHDC.ToInt32, 0, 0, GrabRect.Width, GrabRect.Height, GetDC(0), GrabRect.Left, GrabRect.Top, &HCC0020)

		gDest.ReleaseHdc(DestHDC)
		gDest.Dispose()

		Return destBMP

	End Function

	'straightforward 1:1 wrapper
	Public Shared Sub Blit(ByVal destHDC As IntPtr, ByVal destX As Integer, ByVal destY As Integer, ByVal width As Integer, ByVal height As Integer, ByVal srcHDC As IntPtr, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal mode As BLITMODE)

		BitBlt(destHDC.ToInt32, destX, destY, width, height, srcHDC.ToInt32, xSrc, ySrc, mode)

	End Sub

	'straightforward 1:1 wrapper with point and rect objects for simplicity
	Public Shared Sub Blit(ByVal destHDC As IntPtr, ByVal destPoint As Point, ByVal srcHDC As IntPtr, ByVal srcRect As Rectangle, ByVal mode As BLITMODE)

		BitBlt(destHDC.ToInt32, destPoint.X, destPoint.Y, srcRect.Width, srcRect.Height, srcHDC.ToInt32, srcRect.Left, srcRect.Top, mode)

	End Sub

	'accepts 2 Graphics objects instead of device contexts
	Public Shared Sub Blit(ByVal destSurface As Graphics, ByVal destPoint As Point, ByVal srcSurface As Graphics, ByVal srcRect As Rectangle, ByVal mode As BLITMODE)

		'grab DC handles
		Dim destHDC As IntPtr = destSurface.GetHdc()
		Dim srcHDC As IntPtr = srcSurface.GetHdc()

		'do the blitting operation
		Blit(destHDC, destPoint, srcHDC, srcRect, mode)

		'free the handles again to avoid re-use of existing handles
		destSurface.ReleaseHdc(destHDC)
		srcSurface.ReleaseHdc(srcHDC)

	End Sub

	'accepts 2 control objects instead of device contexts or Graphics objects
	Public Shared Sub Blit(ByVal destControl As Control, ByVal destPoint As Point, ByVal srcControl As Control, ByVal srcRect As Rectangle, ByVal mode As BLITMODE)

		'grab graphics objects
		Dim destSurface As Graphics = destControl.CreateGraphics
		Dim srcSurface As Graphics = srcControl.CreateGraphics

		'do the blitting operation
		Blit(destSurface, destPoint, srcSurface, srcRect, mode)

		'tidy up
		destSurface.Dispose()
		srcSurface.Dispose()

	End Sub

End Class






