función BitBlt produce mapa de bits vacío cuando compilado para x86 en .NET aplicación 2.0 VB

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

  •  27-09-2019
  •  | 
  •  

Pregunta

Tengo una función de contenedor BitBlt en mi proyecto de VB. Funciona muy bien cuando se compila como cualquiera de las CPU, pero cuando me apunto al 86 crea un mapa de bits vacío. Debo usar x86 como otras partes de la aplicación así lo requieran. ¿Alguna idea sobre que podría ir mal? Aquí está el código:

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

Gracias, Brian

¿Fue útil?

Solución

Es un problema bastante clásico con VB.NET, la declaración PInvoke está mal. El que sólo utiliza trabaja para VB6, un lenguaje que por razones históricas utiliza un número entero de 16 bits, mucho tiempo para un número de 32 bits. Esto se remonta a las primeras versiones de VB que se ejecutaban en sistemas operativos de 16 bits. VB.NET fue rediseñada para funcionar bien en sistemas operativos de 32 bits, el número entero es de 32 bits, su largo es de 64 bits. Usted tiene que declarar los argumentos como enteros. Funciona en modo de 64 bits por accidente.

pinvoke.net para obtener la declaración correspondiente.

Y echar un vistazo bueno en Graphics.CopyFromScreen y Control.DrawToBitmap para una funcionalidad muy similar sin necesidad PInvoke.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top