0

我的 VB 项目中有一个 BitBlt 包装函数。当编译为任何 CPU 时它工作得很好,但是当我将它瞄准 x86 时它会创建一个空位图。我必须使用 x86,因为应用程序的其他部分需要它。有什么想法可能是错的吗?这是代码:

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

谢谢,布赖恩

4

1 回答 1

2

这是 VB.NET 的一个非常经典的问题,pinvoke 声明是错误的。您使用的仅适用于 VB6,由于历史原因,这种语言使用 Integer 表示 16 位数,Long 表示 32 位数。这可以追溯到在 16 位操作系统上运行的早期 VB 版本。VB.NET 被重新设计为在 32 位操作系统上运行良好,它的 Integer 是 32 位,它的 Long 是 64 位。您必须将参数声明为整数。它偶然在64位模式下工作。

使用pinvoke.net获得正确的声明。

并仔细查看 Graphics.CopyFromScreen 和 Control.DrawToBitmap 以获得非常相似的功能,而无需 pinvoke。

于 2010-10-04T19:34:04.497 回答