Code:
Private Declare Function CreateDIBSectionPtr Lib "gdi32.dll" Alias "CreateDIBSection" (ByVal hDC As Long, ByRef pBMI As Any, ByVal iUsage As Long, ByRef ppvBits As Long, ByVal hSection As Long, ByVal dwOffset As Long) As Long
Public Function CaptureCurrentImage() As Boolean
Dim BufferPointer As Long, BufferLength As Long
Dim lheap As Long
Dim oBasicVideo As IAMBasicVideo
Dim bResult As Boolean
On Error Resume Next
Set oBasicVideo = m_objManager
Call oBasicVideo.GetCurrentImage(BufferLength, ByVal 0&)
If BufferLength > 0& Then
lheap = GetProcessHeap()
'BufferPointer is a packed DIB
BufferPointer = HeapAlloc(lheap, HEAP_GENERATE_EXCEPTIONS Or HEAP_ZERO_MEMORY, BufferLength)
If BufferPointer <> 0 Then
Call oBasicVideo.GetCurrentImage(BufferLength, ByVal BufferPointer)
Set oBasicVideo = Nothing
If (Err.Number = 0&) Then
Select Case m_eDSVideoOutputMode
Case eSaveAsFile
If Len(m_sOutputFileName) Then
CaptureCurrentImage = SaveToBitmap(m_uBIH, BufferPointer, BufferLength, m_sOutputFileName)
End If
HeapFree lheap, 0, BufferPointer
m_bCaptureInProgress = False
Exit Function
Case eCopytoClipboard
If (CopyPackedDIBtoClipboard(BufferPointer)) Then
bResult = HeapFree(lheap, 0&, BufferPointer)
If Not bResult Then
'MsgBox "Call to HeapFree has failed", vbCritical, "HeapFree Failed"
End If
CaptureCurrentImage = True
m_bCaptureInProgress = False
Exit Function
End If
Case eCopytoDIBSection
Dim DIBDataPtr As Long, hDC As Long, hOldDIB As Long, dDC As Long, hDIB As Long
dDC = GetDC(GetDesktopWindow())
hDC = CreateCompatibleDC(dDC)
ReleaseDC GetDesktopWindow(), dDC
If (hDC <> 0) Then
hDIB = CreateDIBSectionPtr(hDC, ByVal BufferPointer, DIB_RGB_COLORS, DIBDataPtr, 0&, 0&)
If (hDIB <> 0) Then
hOldDIB = SelectObject(hDC, hDIB)
Else
Call DeleteDC(hDC)
End If
If (hDIB) Then ' Copy Bitmap data into DIBSection
'BufferPointer is a packed DIB,we need to retrieve raw DIB bits (DIBSection)
Call RtlMoveMemory(ByVal DIBDataPtr, ByVal (BufferPointer + 40), BufferLength - 40)
' Return DIBSection handle
RaiseEvent DSCopyFrametoDIB(hDIB)
CaptureCurrentImage = True
m_bCaptureInProgress = False
End If
End If
If (hDC <> 0) Then
If (hDIB <> 0) Then
Call SelectObject(hDC, hOldDIB)
Call DeleteObject(hDIB)
End If
Call DeleteDC(hDC)
End If
'-- Reset DIB vars.
hDC = 0
hDIB = 0
hOldDIB = 0
End Select
End If
End If
HeapFree lheap, 0, BufferPointer
Call Err.Clear
End If
Set oBasicVideo = Nothing
End Function
Private Function SaveToBitmap(tBIH As BITMAPINFOHEADER, ByVal lPtrBits As Long, ByVal PtrBitsSize As Long, ByVal sFileName As String) As Boolean
Dim uBFH As BITMAPFILEHEADER
Dim hFile As Long
Dim lBytesWritten As Long
Dim lSize As Long
Dim lRet As Long
Dim bErr As Boolean
Dim lheap As Long, lPtr As Long
Dim lErr As Long
Dim lColors As Long
Dim bOk As Boolean
' Prepare the BITMAPFILEHEADER
bOk = DeleteTheFile(sFileName, m_bUseUnicode)
'If Not bOK Then Exit Function
hFile = CreateTheFile(sFileName, False, m_bUseUnicode)
lErr = Err.LastDllError
If (hFile = INVALID_HANDLE_VALUE) Then
' error
Exit Function
Else
'-- Get palette entries count
lColors = IIf(tBIH.biBitCount <= 8, 2 ^ tBIH.biBitCount, 0)
With uBFH
.bfType = BITMAPTYPE
.bfSize = Len(tBIH) + 4 * lColors + tBIH.biSizeImage
.bfOffBits = Len(uBFH) + Len(tBIH) + 4 * lColors
End With
' Writing the BITMAPFILEINFOHEADER is somewhat painful
' due to non-byte alignment of structure...
lheap = GetProcessHeap()
lPtr = HeapAlloc(lheap, HEAP_GENERATE_EXCEPTIONS Or HEAP_ZERO_MEMORY, Len(uBFH))
CopyMemory ByVal lPtr, uBFH.bfType, 2
CopyMemory ByVal lPtr + 2, uBFH.bfSize, 4
CopyMemory ByVal lPtr + 6, 0&, 4
CopyMemory ByVal lPtr + 10, uBFH.bfOffBits, 4
lSize = Len(uBFH)
lRet = WriteFile(hFile, ByVal lPtr, lSize, lBytesWritten, ByVal 0&)
HeapFree lheap, 0, lPtr
' Add the BITMAPINFOHEADER and colour palette:
bErr = FileErrHandler(lRet, lSize, lBytesWritten)
If Not bErr Then
lSize = Len(tBIH)
lRet = WriteFile(hFile, tBIH, lSize, lBytesWritten, ByVal 0&)
bErr = FileErrHandler(lRet, lSize, lBytesWritten)
Else
CloseHandle hFile
End If
If Not bErr Then
' Its easy to write the bitmap data, though...
lSize = PtrBitsSize 'tBIH.biSizeImage
lRet = WriteFile(hFile, ByVal (lPtrBits + Len(tBIH)), lSize, lBytesWritten, ByVal 0&)
bErr = FileErrHandler(lRet, lSize, lBytesWritten)
Else
CloseHandle hFile
End If
bErr = FileErrHandler(lRet, lSize, lBytesWritten)
CloseHandle hFile
SaveToBitmap = Not (bErr)
End If
End Function
Private Function FileErrHandler(ByVal lR As Long, ByVal lSize As Long, ByVal lBytes As Long) As Boolean
If (lR = 0) Or Not (lSize = lBytes) Then
'Err.Raise
FileErrHandler = True
End If
End Function
Private Function pvByteAlignOnWord(ByVal BitDepth As Byte, ByVal Width As Long) As Long
' function to align any bit depth on dWord boundaries
pvByteAlignOnWord = (((Width * BitDepth) + &H1F&) And Not &H1F&) \ &H8&
End Function
Private Function CopyPackedDIBtoClipboard(ByVal hGlobal As OLE_HANDLE) As Boolean
If hGlobal = 0& Then Exit Function
If (0& <> OpenClipboard(0&)) Then
If (0& <> EmptyClipboard()) Then
CopyPackedDIBtoClipboard = CBool(SetClipboardData(vbCFDIB, hGlobal) <> 0)
End If
Call CloseClipboard
End If
End Function