BitBlt-Funktion erzeugt Bitmap leer, wenn für X 86 in NET 2.0 VB app kompilierten
Frage
Ich habe eine BitBlt Wrapper-Funktion in meinem VB-Projekt. Es funktioniert gut, wenn sie als Any CPU kompiliert, aber wenn ich es auf x86 Ziel schafft es eine leere Bitmap. Ich muss x86 verwenden als andere Teile der App es erfordern. Irgendwelche Ideen, was könnte falsch sein? Hier ist der Code:
Imports System.Drawing.Imaging
''' <summary>
''' Provides the static method ControlCapture used to
''' take screenshots of the specified control.
''' </summary>
''' <remarks>This fails unless compiled targeting Any CPU!!!</remarks>
Public Class ControlCapture
''' <summary>
''' Pointer to gdi.exe win32 function.
''' </summary>
''' <param name="hDestDC">destination device context</param>
''' <param name="x">x coord. of output rectangle</param>
''' <param name="y">y coord. of output rectangle</param>
''' <param name="nWidth">width of source and dest. rectangle</param>
''' <param name="nHeight">height of source and dest. rectangle</param>
''' <param name="hSrcDC">source device context</param>
''' <param name="xSrc">x coord. of rectangle to capture</param>
''' <param name="ySrc">y coord. of rectangle to capture</param>
''' <param name="dwRop">mode (raster op)</param>
''' <returns>0 on failure, non-zero on success</returns>
''' <remarks>from http://support.microsoft.com/kb/147810 </remarks>
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
''' <summary>
''' Grab a screen capture of the given control.
''' </summary>
''' <param name="control">control to grab</param>
''' <returns>Bitmap image</returns>
''' <remarks>used by mappoint map viewer and bing map viewer</remarks>
Public Shared Function ControlCapture(ByVal control As Control) As Bitmap
'capture params
Dim width As Integer = control.Width
Dim height As Integer = control.Height
'output object
Dim bitmap As Bitmap = New Bitmap(width, height, PixelFormat.Format32bppArgb)
'get handles to source and destination objects as graphics
Dim sourceGraphics As Graphics = control.CreateGraphics()
Dim destGrahpics As Graphics = Drawing.Graphics.FromImage(bitmap)
'actual handles
Dim sourceGraphicsPointer As System.IntPtr = sourceGraphics.GetHdc()
Dim destGraphicsPointer As System.IntPtr = destGrahpics.GetHdc()
'get references as ints
Dim destAddress As Integer = destGraphicsPointer
Dim sourceAddress As Integer = sourceGraphicsPointer
'call win32 api
BitBlt(destAddress, 0, 0, width, height, sourceAddress, 0, 0, Codes.SourceCopy)
'clean up
sourceGraphics.ReleaseHdc(sourceGraphicsPointer)
destGrahpics.ReleaseHdc(destGraphicsPointer)
Return bitmap
End Function
''' <summary>
''' SRCCOPY(CC0020) Copies the source bitmap to destination bitmap.
''' </summary>
''' <remarks>From http://support.microsoft.com/kb/147810 </remarks>
Private Enum Codes
SourceCopy = &HCC0020
End Enum
End Class
Danke, brian
Lösung
Es ist ein ziemlich klassisches Problem mit VB.NET, die pinvoke Erklärung ist falsch. Diejenige, die Sie nur verwenden, arbeitet für VB6, eine Sprache, die aus historischen Gründen verwenden Integer für eine 16-Bit-Zahl, Lange für eine 32-Bit-Zahl. Dies geht auf frühe Versionen von VB zurück, dass RAN auf 16-Bit-Betriebssystemen. VB.NET neu gestaltet wurde auch Systeme auf 32-Bit-Betrieb zu arbeiten, seine Integer 32 Bit, seine Long ist 64 Bit. Sie müssen die Argumente als Integer deklarieren. Es funktioniert in 64-Bit-Modus durch Zufall.
Verwenden Sie pinvoke.net die richtige Erklärung erhalten.
Und nehmen Sie einen guten Blick auf Graphics.CopyFromScreen und Control.DrawToBitmap für sehr ähnliche Funktionalität ohne pinvoke zu benötigen.