只有dib的句柄,请问怎样显示出来呢?Private Declare Function SetDIBitsToDevice Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dX As Long, ByVal dY As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As Any, ByVal wUsage As Long) As Long
Private Type BITMAPINFOHEADER
    biSize As Long
    biWidth As Long
    biHeight As Long
    biPlanes As Integer
    biBitCount As Integer
    biCompression As Long
    biSizeImage As Long
    biXPelsPerMeter As Long
    biYPelsPerMeter As Long
    biClrUsed As Long
    biClrImportant As Long
End Type
Private Const BI_RGB As Long = 0&
Private Const DIB_RGB_COLORS As Long = 0
' Image Size
Private Const ImgWidth As Long = 1024
Private Const ImgHeight As Long = 768' Image
Private m_BI As BITMAPINFOHEADER
dim myData as longmyData = LTMMCapture.CaptureDIB
Call SetDIBitsToDevice(Picture1.hdc, 0, 0, m_BI.biWidth, m_BI.biHeight, 0, 0, 0, m_BI.biHeight, myData, m_BI, DIB_RGB_COLORS)
执行代码后不显示也不报错,不知道是什么原因。数据是从设备中抓出来的,目前的数据内容是我的屏幕内容,BITMAPINFOHEADER的数据应该如何填充呢?
我查msdn上面说:
The memory device context was created properly but has not had a bitmap selected into it.In Windows, all memory DCs are created with a default 1-pixel by 1-pixel monochrome bitmap. If an application does not select an HBITMAP object into the memory DC, the only source or destination for the image bits is the single pixel in the default bitmap.
不知道应该怎么解决,在论坛上看到vc版有人有类似问题,但是用SetDIBitsToDevice就显示出来了,并没有涉及到HBITMAP,请知道的朋友指点一下啊!!谢谢!!!

解决方案 »

  1.   

    Picture1.AutoRedraw=TRUE '加上这一句试试
    Call SetDIBitsToDevice(Picture1.hdc, 0, 0, m_BI.biWidth, m_BI.biHeight, 0, 0, 0, m_BI.biHeight, myData, m_BI, DIB_RGB_COLORS)
      

  2.   

    Call SetDIBitsToDevice(Picture1.hdc, 0, 0, m_BI.biWidth, m_BI.biHeight, 0, 0, 0, m_BI.biHeight, myData, m_BI, DIB_RGB_COLORS)注意红色标识处的0,如果你的m_BI.biHeight<0时,才会为0,则否,为最底部的那条扫描线编号.
      

  3.   

    此外,你可先用SetBits试试,看你的图像数据是否正确.
      

  4.   

    我找了半天,没看见SetBits 这个函数用法啊,网上说是flash里面用的??
    Call SetDIBitsToDevice(Picture1.hdc, 0, 0, m_BI.biWidth, m_BI.biHeight, 0, 0, 0, m_BI.biHeight, myData, m_BI, DIB_RGB_COLORS) 这个 0 我查到是:缓冲区中第一条扫描线的编号。如lpbmi之BITMAPINFOHEADER部分的biHeight字段是正数,那么这条扫描线就会从位图的底部开始计算;如果是负数,就从顶部开始计算。那在我这个里面应该填啥数呢?
      

  5.   

    写错了,应该是SetDIBits,该函数只是简单地复制数据,而不指定复制的范围.
    你把代码发给我,我帮你修改.(懒得从头写).
      

  6.   

    你好,太感谢你了,本想给你发短信,可是发短信的网页打不开。
    下面的代码里面有一个 LTMMCapture 是一个视频控件,提供了一个CaptureDIB的方法,我就是想把捕获的dib数据显示在picture1 里面,可是就是现实不出来。
    Option Explicit
    Private Declare Function SetDIBitsToDevice Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dX As Long, ByVal dY As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As Any, ByVal wUsage As Long) As Long
    Private Type BITMAPINFOHEADER
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
    End Type
    Private Const BI_RGB As Long = 0&
    Private Const DIB_RGB_COLORS As Long = 0
    '#################################################
    '#################################################
    '#################################################' Image Size
    Private Const ImgWidth As Long = 1024
    Private Const ImgHeight As Long = 768' Image
    Private m_BI As BITMAPINFOHEADER
    Private m_LineBytes As Long
    Private m_MapData() As BytePrivate Sub Command1_Click()
       LTMMCapture.VideoDevices.Selection = 0
       LTMMCapture.PreviewSource = 1
       LTMMCapture.AudioBufferSize = 0.125
       LTMMCapture.Preview = True
       End SubPrivate Sub Command2_Click()
    Dim myData As Long
    myData = LTMMCapture.CaptureDIB  '这个LTMMCapture是一个控件,这里调用的这个方法。
    Call SetDIBitsToDevice(Picture1.hdc, 0, 0, m_BI.biWidth, m_BI.biHeight, 0, 0, 0, m_BI.biHeight, myData, m_BI, DIB_RGB_COLORS)
    End SubPrivate Sub Form_Load()
        With m_BI
            .biSize = Len(m_BI)
            .biWidth = ImgWidth
            .biHeight = ImgHeight
            .biBitCount = 24
            .biPlanes = 1
            .biCompression = BI_RGB
    '        m_LineBytes = ((.biWidth * .biBitCount + 31) And &HFFFFFFE0) \ 8
    '        .biSizeImage = m_LineBytes * .biHeight
    '        ReDim m_MapData(0 To .biSizeImage - 1)
        End WithEnd Sub
      

  7.   

    你虽然捕获了DIB,但没有得到这幅DIB的相关信息,如高和宽,所以SetDIBitsToDevice(Picture1.hdc, 0, 0, m_BI.biWidth, m_BI.biHeight, 0, 0, 0, m_BI.biHeight, myData, m_BI, DIB_RGB_COLORS)中m_BI没有数据,因此无法正确显示,因为我没有使用过你说的那个控件,不知道它是否提供DIB的有关信息,也不知它的数据中是否包括BITMAP信息,如果有的话,你可以在Call SetDIBitsToDevice(Picture1.hdc, 0, 0, m_BI.biWidth, m_BI.biHeight, 0, 0, 0, m_BI.biHeight, myData, m_BI, DIB_RGB_COLORS)前加上:GetObject myData,Len(m_BI),m_BI。
    下面是SetDIBitsToDevice示例代码:
    Option ExplicitPrivate Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
    Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As LongPrivate Type RGBQUAD
            rgbBlue As Byte
            rgbGreen As Byte
            rgbRed As Byte
            rgbReserved As Byte
    End Type
    Private Type BITMAPINFOHEADER '40 bytes
            biSize As Long
            biWidth As Long
            biHeight As Long
            biPlanes As Integer
            biBitCount As Integer
            biCompression As Long
            biSizeImage As Long
            biXPelsPerMeter As Long
            biYPelsPerMeter As Long
            biClrUsed As Long
            biClrImportant As Long
    End Type
    Private Type BITMAPINFO
            bmiHeader As BITMAPINFOHEADER
            bmiColors As RGBQUAD
    End Type
    Private Const DIB_RGB_COLORS = 0 '  color table in RGBs
    Private Const DIB_PAL_COLORS = 1 '  color table in palette indicesPrivate Sub Command1_Click()
        '由于没有你所说的LTMMCapture控件,我模拟了一下,即先把Picture1中的位图转换成DIB数据,然后复制到Picture2中    Dim BI As BITMAPINFO
        Dim Bits() As Byte
        
        With BI
            .bmiHeader.biSize = 40
        End With
        
        If GetDIBits(Picture1.hdc, Picture1.Picture.Handle, 0, 0, 0, BI, DIB_RGB_COLORS) <> 0 Then
            ReDim Bits(1 To BI.bmiHeader.biSizeImage)
            If GetDIBits(Picture1.hdc, Picture1.Picture.Handle, 0, BI.bmiHeader.biHeight - 1, Bits(1), BI, DIB_RGB_COLORS) <> 0 Then
                SetDIBitsToDevice Picture2.hdc, 0, 0, BI.bmiHeader.biWidth, BI.bmiHeader.biHeight, 0, 0, 0, BI.bmiHeader.biHeight, Bits(1), BI, DIB_RGB_COLORS
            End If
        End IfEnd SubPrivate Sub Form_Load()
        Me.Picture1.AutoRedraw = True
        Me.Picture2.AutoRedraw = True
        Me.Picture1.ScaleMode = vbPixels
        Me.Picture2.ScaleMode = vbPixels
        Set Me.Picture1.Picture = LoadPicture("e:\temp.jpg")
    End Sub
      

  8.   

    Option Explicit
    Private Declare Function SetDIBitsToDevice Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dX As Long, ByVal dY As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As Any, ByVal wUsage As Long) As Long
    Private Type BITMAPINFOHEADER
        biSize As Long
        biWidth As Long
        biHeight As Long
        biPlanes As Integer
        biBitCount As Integer
        biCompression As Long
        biSizeImage As Long
        biXPelsPerMeter As Long
        biYPelsPerMeter As Long
        biClrUsed As Long
        biClrImportant As Long
    End Type
    Private Const BI_RGB As Long = 0&
    Private Const DIB_RGB_COLORS As Long = 0
    ' Image Size
    Private Const ImgWidth As Long = 1024
    Private Const ImgHeight As Long = 768' Image
    Private m_BI As BITMAPINFOHEADER
    Private m_LineBytes As Long
    Private m_MapData() As BytePrivate Sub Command1_Click()
       LTMMCapture.VideoDevices.Selection = 0
       LTMMCapture.PreviewSource = 1
       LTMMCapture.AudioBufferSize = 0.125
       LTMMCapture.Preview = True
    End SubPrivate Sub Command2_Click()
        Dim myData As Long
        myData = LTMMCapture.CaptureDIB 'CaptureDIB有参数吗?返回类型是什么?
                                        '从你的代码中看,如果它返回Long,则是一个指针值,而API中指针传递应使用ByVal,修改如下:
        '修改前的句子
        'Call SetDIBitsToDevice(Picture1.hdc, 0, 0, m_BI.biWidth, m_BI.biHeight, 0, 0, 0, m_BI.biHeight, myData, m_BI, DIB_RGB_COLORS)
        '修改后的句子
        Call SetDIBitsToDevice(Picture1.hdc, 0, 0, m_BI.biWidth, m_BI.biHeight, 0, 0, 0, m_BI.biHeight, ByVal myData, m_BI, DIB_RGB_COLORS)
    End SubPrivate Sub Form_Load()
        With m_BI
            .biSize = Len(m_BI)
            .biWidth = ImgWidth
            .biHeight = ImgHeight
            .biPlanes = 1
            .biBitCount = 24
            .biSizeImage = ImgWidth * ImgHeight * 3 '增加此句
            .biCompression = 0
            
            ReDim m_MapData(1 To .biSizeImage) '该数组好像在代码中没有被使用,你显示时使用的是myData
        End With
    End Sub
      

  9.   

    非常感谢你的帮助,谢谢!
    我用你发得第一段代码,就是把picture1 中的图像复制到picture2 中去,好像也是不行,点了按钮后picture2中仍然画不不出来,我用debug.print bits 查看,发现里面数据是有的,可就是图像出不来。不知道是怎么回事。我按照你发的第二个程序把我以前的程序改了下,但还是不行,希望再帮忙看看,谢谢!
    谢谢!
      

  10.   

    哦,picture2里面有图像了。谢谢你。
    有个疑问:
    GetDIBits(Picture1.hdc, Picture1.Picture.Handle, 0, 0, 0, BI, DIB_RGB_COLORS)
    我查了下,这个0应该是指向一个缓冲区的指针啊,这里为什么用0呢?
    我自己的那个程序还是显示不出来图像?请你再帮忙看看,非常感谢你,我将帖子+100 分。