Kdev
June 14th, 2001, 03:21 PM
I'm not sure if this is related to BitBlt or not but I am using a library of functions that allows me to do screen capturing from my application.
My application captures the client area of its own main form. This works fine when I am running this on a system with just one video card and monitor, but this program normally runs on a system with 2 video cards and 2 monitors (on the secondary monitor). When I try to do the screen capture it comes out as just a blur of colors.
Here is the function that I use to capture the screen:
#If Win32 then
public Function CaptureWindow(byval hWndSrc as Long, _
byval Client as Boolean, byval LeftSrc as Long, _
byval TopSrc as Long, byval WidthSrc as Long, _
byval HeightSrc as Long, optional RasterOp) as Picture
Dim hDCMemory as Long
Dim hBmp as Long
Dim hBmpPrev as Long
Dim r as Long
Dim hDCSrc as Long
Dim hPal as Long
Dim hPalPrev as Long
Dim RasterCapsScrn as Long
Dim HasPaletteScrn as Long
Dim PaletteSizeScrn as Long
#ElseIf Win16 then
public Function CaptureWindow(byval hWndSrc as Integer, _
byval Client as Boolean, byval LeftSrc as Integer, _
byval TopSrc as Integer, byval WidthSrc as Long, _
byval HeightSrc as Long, optional RasterOp) as Picture
Dim hDCMemory as Integer
Dim hBmp as Integer
Dim hBmpPrev as Integer
Dim r as Integer
Dim hDCSrc as Integer
Dim hPal as Integer
Dim hPalPrev as Integer
Dim RasterCapsScrn as Integer
Dim HasPaletteScrn as Integer
Dim PaletteSizeScrn as Integer
#End If
Dim LogPal as LOGPALETTE
Dim lRasterOp as Long
If IsMissing(RasterOp) then
lRasterOp = vbSrcCopy
else
lRasterOp = RasterOp
End If
' Depending on the value of Client get the proper device context.
If Client then
hDCSrc = GetDC(hWndSrc) ' get device context for client area.
else
hDCSrc = GetWindowDC(hWndSrc) ' get device context for entire
' window.
End If
' Create a memory device context for the copy process.
hDCMemory = CreateCompatibleDC(hDCSrc)
' Create a bitmap and place it in the memory DC.
hBmp = CreateCompatibleBitmap(hDCSrc, WidthSrc, HeightSrc)
hBmpPrev = SelectObject(hDCMemory, hBmp)
' get screen properties.
RasterCapsScrn = GetDeviceCaps(hDCSrc, RASTERCAPS) ' Raster
' capabilities.
HasPaletteScrn = RasterCapsScrn And RC_PALETTE ' Palette
' support.
PaletteSizeScrn = GetDeviceCaps(hDCSrc, SIZEPALETTE) ' Size of
' palette.
' If the screen has a palette make a copy and realize it.
If HasPaletteScrn And (PaletteSizeScrn = 256) then
' Create a copy of the system palette.
LogPal.palVersion = &H300
LogPal.palNumEntries = 256
r = GetSystemPaletteEntries(hDCSrc, 0, 256, _
LogPal.palPalEntry(0))
hPal = CreatePalette(LogPal)
' Select the new palette into the memory DC and realize it.
hPalPrev = SelectPalette(hDCMemory, hPal, 0)
r = RealizePalette(hDCMemory)
End If
' Copy the on-screen image into the memory DC.
r = BitBlt(hDCMemory, 0, 0, WidthSrc, HeightSrc, hDCSrc, _
LeftSrc, TopSrc, lRasterOp)
' Remove the new copy of the on-screen image.
hBmp = SelectObject(hDCMemory, hBmpPrev)
' If the screen has a palette get back the palette that was
' selected in previously.
If HasPaletteScrn And (PaletteSizeScrn = 256) then
hPal = SelectPalette(hDCMemory, hPalPrev, 0)
End If
' Release the device context resources back to the system.
r = DeleteDC(hDCMemory)
r = ReleaseDC(hWndSrc, hDCSrc)
' Call CreateBitmapPicture to create a picture object from the
' bitmap and palette handles. then return the resulting picture
' object.
set CaptureWindow = CreateBitmapPicture(hBmp, hPal)
End Function
I call this function in this manner:
set frmMain.pictScreen.Picture = CaptureWindow(frmMain.hWnd, true, _
(frmMain.Left + 45) / Screen.TwipsPerPixelX, (frmMain.Top + 25) / Screen.TwipsPerPixelY, _
(frmMain.Width - 130) / Screen.TwipsPerPixelX, (frmMain.Height - 300) / Screen.TwipsPerPixelY)
I cannot figure out why this works with one video card but not 2. Please help.
-K
My application captures the client area of its own main form. This works fine when I am running this on a system with just one video card and monitor, but this program normally runs on a system with 2 video cards and 2 monitors (on the secondary monitor). When I try to do the screen capture it comes out as just a blur of colors.
Here is the function that I use to capture the screen:
#If Win32 then
public Function CaptureWindow(byval hWndSrc as Long, _
byval Client as Boolean, byval LeftSrc as Long, _
byval TopSrc as Long, byval WidthSrc as Long, _
byval HeightSrc as Long, optional RasterOp) as Picture
Dim hDCMemory as Long
Dim hBmp as Long
Dim hBmpPrev as Long
Dim r as Long
Dim hDCSrc as Long
Dim hPal as Long
Dim hPalPrev as Long
Dim RasterCapsScrn as Long
Dim HasPaletteScrn as Long
Dim PaletteSizeScrn as Long
#ElseIf Win16 then
public Function CaptureWindow(byval hWndSrc as Integer, _
byval Client as Boolean, byval LeftSrc as Integer, _
byval TopSrc as Integer, byval WidthSrc as Long, _
byval HeightSrc as Long, optional RasterOp) as Picture
Dim hDCMemory as Integer
Dim hBmp as Integer
Dim hBmpPrev as Integer
Dim r as Integer
Dim hDCSrc as Integer
Dim hPal as Integer
Dim hPalPrev as Integer
Dim RasterCapsScrn as Integer
Dim HasPaletteScrn as Integer
Dim PaletteSizeScrn as Integer
#End If
Dim LogPal as LOGPALETTE
Dim lRasterOp as Long
If IsMissing(RasterOp) then
lRasterOp = vbSrcCopy
else
lRasterOp = RasterOp
End If
' Depending on the value of Client get the proper device context.
If Client then
hDCSrc = GetDC(hWndSrc) ' get device context for client area.
else
hDCSrc = GetWindowDC(hWndSrc) ' get device context for entire
' window.
End If
' Create a memory device context for the copy process.
hDCMemory = CreateCompatibleDC(hDCSrc)
' Create a bitmap and place it in the memory DC.
hBmp = CreateCompatibleBitmap(hDCSrc, WidthSrc, HeightSrc)
hBmpPrev = SelectObject(hDCMemory, hBmp)
' get screen properties.
RasterCapsScrn = GetDeviceCaps(hDCSrc, RASTERCAPS) ' Raster
' capabilities.
HasPaletteScrn = RasterCapsScrn And RC_PALETTE ' Palette
' support.
PaletteSizeScrn = GetDeviceCaps(hDCSrc, SIZEPALETTE) ' Size of
' palette.
' If the screen has a palette make a copy and realize it.
If HasPaletteScrn And (PaletteSizeScrn = 256) then
' Create a copy of the system palette.
LogPal.palVersion = &H300
LogPal.palNumEntries = 256
r = GetSystemPaletteEntries(hDCSrc, 0, 256, _
LogPal.palPalEntry(0))
hPal = CreatePalette(LogPal)
' Select the new palette into the memory DC and realize it.
hPalPrev = SelectPalette(hDCMemory, hPal, 0)
r = RealizePalette(hDCMemory)
End If
' Copy the on-screen image into the memory DC.
r = BitBlt(hDCMemory, 0, 0, WidthSrc, HeightSrc, hDCSrc, _
LeftSrc, TopSrc, lRasterOp)
' Remove the new copy of the on-screen image.
hBmp = SelectObject(hDCMemory, hBmpPrev)
' If the screen has a palette get back the palette that was
' selected in previously.
If HasPaletteScrn And (PaletteSizeScrn = 256) then
hPal = SelectPalette(hDCMemory, hPalPrev, 0)
End If
' Release the device context resources back to the system.
r = DeleteDC(hDCMemory)
r = ReleaseDC(hWndSrc, hDCSrc)
' Call CreateBitmapPicture to create a picture object from the
' bitmap and palette handles. then return the resulting picture
' object.
set CaptureWindow = CreateBitmapPicture(hBmp, hPal)
End Function
I call this function in this manner:
set frmMain.pictScreen.Picture = CaptureWindow(frmMain.hWnd, true, _
(frmMain.Left + 45) / Screen.TwipsPerPixelX, (frmMain.Top + 25) / Screen.TwipsPerPixelY, _
(frmMain.Width - 130) / Screen.TwipsPerPixelX, (frmMain.Height - 300) / Screen.TwipsPerPixelY)
I cannot figure out why this works with one video card but not 2. Please help.
-K