我写了一个旋转图片的程序,用PlgBlt.
但运行后我发现目标图片框里没有任何东西,PlgBlt的返回值为0.
我百思不得其解,望高手指点迷津,不胜感激.

解决方案 »

  1.   

    以下是文件form1.frm的内容:VERSION 5.00
    Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "MSCOMCTL.OCX"
    Begin VB.Form Form1 
       BorderStyle     =   1  'Fixed Single
       Caption         =   "Form1"
       ClientHeight    =   5055
       ClientLeft      =   2190
       ClientTop       =   2565
       ClientWidth     =   6420
       LinkTopic       =   "Form1"
       MaxButton       =   0   'False
       MinButton       =   0   'False
       ScaleHeight     =   337
       ScaleMode       =   3  'Pixel
       ScaleWidth      =   428
       Begin MSComctlLib.Slider Degree 
          Height          =   420
          Left            =   15
          TabIndex        =   2
          Top             =   105
          Width           =   4215
          _ExtentX        =   7435
          _ExtentY        =   741
          _Version        =   393216
          LargeChange     =   30
          Max             =   360
          TickStyle       =   3
       End
       Begin VB.PictureBox PicDest 
          AutoRedraw      =   -1  'True
          Height          =   2145
          Left            =   2100
          ScaleHeight     =   139
          ScaleMode       =   3  'Pixel
          ScaleWidth      =   126
          TabIndex        =   1
          Top             =   1005
          Width           =   1950
       End
       Begin VB.PictureBox PicSrc 
          AutoRedraw      =   -1  'True
          Height          =   1620
          Left            =   225
          Picture         =   "Form1.frx":0000
          ScaleHeight     =   104
          ScaleMode       =   3  'Pixel
          ScaleWidth      =   75
          TabIndex        =   0
          Top             =   840
          Width           =   1185
       End
       Begin VB.Label Label1 
          AutoSize        =   -1  'True
          Caption         =   "旋转360度"
          BeginProperty Font 
             Name            =   "宋体"
             Size            =   15.75
             Charset         =   134
             Weight          =   400
             Underline       =   0   'False
             Italic          =   0   'False
             Strikethrough   =   0   'False
          EndProperty
          Height          =   315
          Left            =   4545
          TabIndex        =   3
          Top             =   150
          Width           =   1440
       End
    End
    Attribute VB_Name = "Form1"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = True
    Attribute VB_Exposed = False
    Option Explicit
    Private Declare Function PlgBlt Lib "gdi32" (ByVal hdcDest As Long, lpPoint As POINTAPI, ByVal hdcSrc As Long, ByVal nXSrc As Long, ByVal nYSrc As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hbmMask As Long, ByVal xMask As Long, ByVal yMask As Long) As Long
    Private Type POINTAPI
            x As Long
            y As Long
    End Type
    Const Pi# = 3.14159265358979Private Sub Degree_Scroll()
        Label1 = "旋转" & Degree.Value & "度"
        Dim P(1 To 4) As POINTAPI, Rad#
        Rad = Degree.Value * Pi / 180
        
        'P(1).x = 0
        'P(1).y = 0
        P(2).x = Cos(Rad) * PicSrc.ScaleWidth
        P(2).y = -Sin(Rad) * PicSrc.ScaleWidth
        P(3).x = Sin(Rad) * PicSrc.ScaleHeight
        P(3).y = Cos(Rad) * PicSrc.ScaleHeight
        P(4).x = P(2).x + P(3).x
        P(4).y = P(2).y + P(3).y
        
        Dim L%, T%, R%, B%, I%, Off As POINTAPI
        If Degree.Value < 90 Then
            L = 1: T = 2: R = 4: B = 3
        ElseIf Degree.Value < 180 Then
            L = 2: T = 4: R = 3: B = 1
        ElseIf Degree.Value < 270 Then
            L = 4: T = 3: R = 1: B = 2
        Else
            L = 3: T = 1: R = 2: B = 4
        End If
        
        Off.x = -P(L).x
        Off.y = -P(T).y
        
        For I = 1 To 4
            P(I).x = P(I).x + Off.x
            P(I).y = P(I).y + Off.y
        Next
        
        PicDest.Width = P(R).x + 4
        PicDest.Height = P(B).y + 4
        
        PicDest.Cls
        PlgBlt PicDest.hDC, P(1), PicSrc.hDC, 0, 0, PicSrc.ScaleWidth, PicSrc.ScaleHeight, 0, 0, 0
        PicDest.Refresh
    End Sub
      

  2.   

    我怀疑是hbmMask, xMask, yMask的问题.
      

  3.   

    PlgBlt 这个函数只有NT系列才有,,Win9X好像不支持
      

  4.   

    Win9X好像不支持?
    他没有说找不到DLL入口..........
    难道是个占位函数?
      

  5.   

    PlgBlt:
    【VB声明】
      Private Declare Function PlgBlt Lib "gdi32" Alias "PlgBlt" (ByVal hdcDest As Long, lpPoint As POINTAPI, ByVal hdcSrc As Long, ByVal nXSrc As Long, ByVal nYSrc As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hbmMask As Long, ByVal xMask As Long, ByVal yMask As Long) As Long【说明】
      复制一幅位图,同时将其转换成一个平行四边形。利用它可对位图进行旋转处理 【返回值】
      Long,非零表示成功,零表示失败。会设置GetLastError 【备注】
      如果对源图象应用了旋转或剪切处理,这个函数的执行就会失败。可用GetDeviceCaps判断这个函数是否得到了一个特定设备场景的支持【参数表】
      hdcDest --------  Long,图象使用的目标设备场景  lpPoint --------  POINTAPI,POINTAPI结构数组中使用的第一个条目。第一个点对应于一个平行四边形左上角位置;第二个点代表右下角位置;第三个点代表左下角位置;第四个点是在前三个点的基础上导出的  hdcSrc ---------  Long,图象的源设备场景  nXSrc,nYSrc ----  Long,源图象左上角的x,y坐标,采用逻辑坐标系统表示  nWidth,nHeight -  Long,源图象大小,用逻辑坐标表示  hbmMask --------  Long,一个可选的句柄,指向一个单色掩模。如设定了这个参数,那么只有与掩模值1对应的二进制位才会传输到目的地  xMask,yMask ----  Long,掩模位图欲使用区域左上角的x,y坐标
      适用平台
      Windows NT
      

  6.   

    那个问题是没治了,我再问一个:
    PictureBox.Picture和PictureBox.Image有什么区别?
    As Picture和StdPicture和IPictureDisp有什么区别?
      

  7.   

    //StdPicture和IPictureDisp有什么区别实际上是一样的//PictureBox.Picture和PictureBox.ImageProperty Image As IPictureDisp
        只读
        VB.PictureBox 的成员
        返回一个 Microsoft Windows 提供的句柄到一个持久性位图。
        (其实就是当前显示的图形,和picturebox大小相同)Property Picture As IPictureDisp
        VB.PictureBox 的成员
        返回/设置控件中显示的图形。
        (和picturebox的大小没有关系,它的大小取决于图片文件)
      

  8.   

    明白了。
    还是前面的问题。
    我把WIN XP
      

  9.   

    还没写完就发出去了,怎么回事。
    我把WIN XP的GDI32.DLL复制过来,并在声明中加上了路径,这回VB说找不到文件!
    File not found: F:\GDI32.DLL
    我可以肯定路径没有错误.
    有谁知道怎么回事?
      

  10.   

    重命名后,将文件放入系统文件夹试试不过,估计没用不是dll文件的问题,是win98操作系统不支持PlgBlt!
    如果想在win98下实现图形的旋转,可以不用PlgBlt,根据解析几何进行换算即可,当然速度要慢一些
      

  11.   

    参考:
    http://vbnew.www21.cnidc.cn/wz/qcwz1/list.asp?id=1102
      

  12.   

    我试过,确实没有用.
    根据解析几何进行换算,这个我到会.
    我用getpixel,setpixel做过,太慢.
    用dib,我正在做,又碰到问题了:
    GetDIBits Picture1.hdc, Picture1.Image.Handle, 0, Picture1.ScaleHeight, MapData(0), BM, 0
    mapdata是位图数据(足够大),bm是bitmapinfo.
    返回值为0.请问是什么原因?千万不要说win98不支持...
    另外,我想只得到bm(根据bm确定redim mapdata(多大?) ),该怎么做?
      

  13.   

    许多函数都是在Win9x的时候已经设计好了,不知什么原因没有将功能放上(?)。这些函数都是空的,返回值总是零。
      

  14.   

    终于找到了,getbitmapbits,setbitmapbits还是可以使用的。
    但是他没有bitmapinfo结构,他的bits是只包含数据区,还是包含整个位图的字节?
      

  15.   

    //但是他没有bitmapinfo结构,他的bits是只包含数据区,还是包含整个位图的字节?只包含数据
      

  16.   

    终于做出来了,但是还有两个问题:
    1、旋转时有麻点。(这是我的算法不好,要改就得全改)
    2、下划线的两行,本来是应该从0开始,但改成0就会下标超界。谁能告诉我其中的原因。VERSION 5.00
    Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "MSCOMCTL.OCX"
    Begin VB.Form Form1 
       Caption         =   "Form1"
       ClientHeight    =   5325
       ClientLeft      =   1755
       ClientTop       =   2055
       ClientWidth     =   6330
       LinkTopic       =   "Form1"
       ScaleHeight     =   355
       ScaleMode       =   3  'Pixel
       ScaleWidth      =   422
       Begin MSComctlLib.Slider Degree 
          Height          =   630
          Left            =   105
          TabIndex        =   2
          Top             =   180
          Width           =   4560
          _ExtentX        =   8043
          _ExtentY        =   1111
          _Version        =   393216
          LargeChange     =   10
          Max             =   360
          TickStyle       =   3
       End
       Begin VB.PictureBox PicDest 
          AutoRedraw      =   -1  'True
          Height          =   3450
          Left            =   2400
          ScaleHeight     =   226
          ScaleMode       =   3  'Pixel
          ScaleWidth      =   140
          TabIndex        =   1
          Top             =   855
          Width           =   2160
       End
       Begin VB.PictureBox PicSrc 
          AutoRedraw      =   -1  'True
          Height          =   3450
          Left            =   210
          Picture         =   "Form1.frx":0000
          ScaleHeight     =   226
          ScaleMode       =   3  'Pixel
          ScaleWidth      =   140
          TabIndex        =   0
          Top             =   855
          Width           =   2160
       End
    End
    Attribute VB_Name = "Form1"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = True
    Attribute VB_Exposed = False
    Option Explicit
    Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
    Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
    Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
    Private 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 DeleteDC Lib "gdi32" (ByVal hDC 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 Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Private Type BITMAP '14 bytes
            bmType As Long
            bmWidth As Long
            bmHeight As Long
            bmWidthBytes As Long
            bmPlanes As Integer
            bmBitsPixel As Integer
            bmBits As Long
    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 RGBQUAD
            rgbBlue As Byte
            rgbGreen As Byte
            rgbRed As Byte
            rgbReserved As Byte
    End Type
    Private Type BITMAPINFO
            bmiHeader As BITMAPINFOHEADER
            bmiColors(255) As RGBQUAD
    End Type
    Private Type POINTAPI
            x As Long
            y As Long
    End Type
    Const BI_RGB = 0&
    Const DIB_RGB_COLORS = 0 '  color table in RGBs
    Const Pi# = 3.14159265358979Private Sub Degree_Scroll()
        Dim Image As StdPicture
        Set Image = PicSrc.Image
        
        Dim BM As BITMAP
        GetObject Image.Handle, Len(BM), BM    Dim BI As BITMAPINFO
        With BI.bmiHeader
        .biSize = Len(BI.bmiHeader)
        .biWidth = BM.bmWidth
        .biHeight = BM.bmHeight
        .biPlanes = BM.bmPlanes
        .biBitCount = BM.bmBitsPixel
        .biCompression = BI_RGB
        
        Dim LineBytes As Long
        LineBytes = ((.biWidth * .biBitCount + 31&) And &HFFFFFFE0) \ 8
        .biSizeImage = LineBytes * .biHeight
        
        ReDim MapData(0 To LineBytes - 1, 0 To .biHeight - 1) As Byte
        
        
        GetDIBits PicSrc.hDC, Image.Handle, 0, .biHeight, MapData(0, 0), BI, DIB_RGB_COLORS
           
           
           
           
        
        Dim Rad#, SinRad#, CosRad#
        Rad = Degree.Value * Pi / 180
        SinRad = Sin(Rad)
        CosRad = Cos(Rad)
        
        Dim P(1 To 4) As POINTAPI
        'P(1).x = 0
        'P(1).y = 0
        P(2).x = CosRad * PicSrc.ScaleWidth
        P(2).y = -SinRad * PicSrc.ScaleWidth
        P(3).x = SinRad * PicSrc.ScaleHeight
        P(3).y = CosRad * PicSrc.ScaleHeight
        P(4).x = P(2).x + P(3).x
        P(4).y = P(2).y + P(3).y
        
        Dim L%, T%, R%, B%, I%, Off As POINTAPI
        If Degree.Value < 90 Then
            L = 1: T = 2: R = 4: B = 3
        ElseIf Degree.Value < 180 Then
            L = 2: T = 4: R = 3: B = 1
        ElseIf Degree.Value < 270 Then
            L = 4: T = 3: R = 1: B = 2
        Else
            L = 3: T = 1: R = 2: B = 4
        End If
        
        Off.x = -P(L).x
        Off.y = -P(T).y
        
        For I = 1 To 4
            P(I).x = P(I).x + Off.x
            P(I).y = P(I).y + Off.y
        Next
        
        PicDest.Width = P(R).x + 4
        PicDest.Height = P(B).y + 4
        End With
        
        Dim NewBI As BITMAPINFO
        With NewBI.bmiHeader
        NewBI = BI
        .biWidth = P(R).x
        .biHeight = P(B).y
        Dim NewLineBytes As Long
        NewLineBytes = ((.biWidth * .biBitCount + 31&) And &HFFFFFFE0) \ 8
        ReDim NewMap(0 To NewLineBytes - 1, 0 To .biHeight - 1) As Byte
        End With
        
        
        With BI.bmiHeader
        If .biBitCount < 8 Then Exit Sub
        Dim M As Long, N As Long    For N = 1 To .biHeight - 1
      '--------------------------------
        For M = 1 To .biWidth - 1
      '--------------------------------    CopyMemory NewMap((.biBitCount \ 8) * CLng(Off.x + M * CosRad + N * SinRad), CLng(Off.y - M * SinRad + N * CosRad)), MapData((.biBitCount \ 8) * M, N), .biBitCount \ 8
        
        Next
        
        Next
        End With
        
        With NewBI.bmiHeader
        SetDIBitsToDevice PicDest.hDC, 0, 0, .biWidth, .biHeight, 0, 0, 0, .biHeight, NewMap(0, 0), NewBI, DIB_RGB_COLORS
        End With
        PicDest.Refresh
    End Sub