BitBlt-Funktion erzeugt Bitmap leer, wenn für X 86 in NET 2.0 VB app kompilierten

StackOverflow https://stackoverflow.com/questions/3858389

  •  27-09-2019
  •  | 
  •  

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

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top