我用savedc保存了初始内存设备环境,经过在内存中作图后,我想用restoredc恢复到初始状态,却不行,出来的始终是作图后的设备环境,好像VC栏中这个问题讨论较多,VB还没有,VB真的是玩玩简单的啊!

解决方案 »

  1.   

    不能。
    在VB里要保存图片可以直接使用StdPicture对象
    如果你是用GDI在内存DC上绘图,可以使用OleCreatePictureIndirect函数将位图句柄转换成Picture对象,然后再保存。
      

  2.   

    Option ExplicitPrivate Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As LongPrivate Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As LongPrivate Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, lpInitData As Long) As LongPrivate Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As LongPrivate Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As LongPrivate Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As LongPrivate 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 LongPrivate Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As LongPrivate Declare Function SaveDC Lib "gdi32" (ByVal hdc As Long) As LongPrivate Declare Function RestoreDC Lib "gdi32" (ByVal hdc As Long, ByVal nSavedDC As Long) As LongPrivate Type RECT
            Left As Long
            Top As Long
            Right As Long
            Bottom As Long
    End Type
    Dim myrect As RECT
    Dim vrect As RECT
    Dim mdc As Long
    Dim monidc As Long
    Dim bmphandle As Long
    Dim dx As Long
    Dim dy As Long
    Dim bdown As Boolean
    Dim hid As Long
    Private Sub Form_Load()
        dx = Screen.Width / Screen.TwipsPerPixelX
        dy = Screen.Height / Screen.TwipsPerPixelY
        
        monidc = CreateDC("display", 0, 0, 0)
        mdc = CreateCompatibleDC(monidc)    bmphandle = CreateCompatibleBitmap(Me.hdc, dx, dy)
        SelectObject mdc, bmphandleEnd SubPrivate Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
        If Button = vbLeftButton Then
            GetWindowRect Me.hwnd, myrect
            BitBlt mdc, 0, 0, dx, dy, monidc, 0, 0, vbSrcCopy
            hid = SaveDC(mdc)
            drawmutirect mdc, myrect
            BitBlt monidc, 0, 0, dx, dy, mdc, 0, 0, vbSrcCopy        bdown = True
        End If
    End SubPrivate Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        
    If bdown = True Then
        RestoreDC mdc, hid
        With vrect
        .Left = myrect.Left
        .Top = myrect.Top
        .Right = (X + Me.Left) / Screen.TwipsPerPixelX
        .Bottom = (Y + Me.Top) / Screen.TwipsPerPixelY
        End With
        drawmutirect mdc, vrect    BitBlt monidc, 0, 0, dx, dy, mdc, 0, 0, vbSrcCopyEnd If
    End SubPrivate Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
        'Me.Move Me.Left, Me.Top, X, Y
        'Me.Cls
        bdown = False
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        If bmphandle <> 0 Then bmphandle = 0
        DeleteObject mdc
    End SubPrivate Sub drawmutirect(destdc As Long, myrect As RECT)
        DrawFocusRect destdc, myrect
        With myrect
        .Left = .Left + 1
        .Top = .Top + 1
        .Right = .Right - 1
        .Bottom = .Bottom - 1
        End With
        DrawFocusRect destdc, myrect
        With myrect
        .Left = .Left - 2
        .Top = .Top - 2
        .Right = .Right + 2
        .Bottom = .Bottom + 2
        End With
        DrawFocusRect destdc, myrect
    End Sub
      

  3.   

    查查MSDN对这两个API的说明吧,RESTOREDC可不会恢复画面内容的。
      

  4.   

    明白楼主的意思了,savedc和restoredc的作用不是你想象中的保存和加载位图,想保存/加载位图数据的话用GetBitmapBits/SetBitmapBits或者GetDIBits/SetDIBits吧,推荐用后者,具体的,建议看看MSDN
      

  5.   

    写了这么多API,不如用VC算了……
      

  6.   

    savedc和restoredc只是保存DC状态信息,而位图内容则是由DC中选入的bmphandle决定。
    从你的代码看,似乎是想在通过窗体中的拖动动作,而在屏幕上画一些矩形边框?若是这种需求,那你的代码问题就太多了,也不必这么兴师动众!我可以帮你改改。
      

  7.   

    看看这样改能不能达到你的要求?(我想你处理的一定是无边框窗体,所以就没处理窗体标题栏带来的坐标误差了,你可自己加上)
    Option Explicit
    Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End Type
    Private monidc As Long, bdown As Boolean, dx As Long, dy As Long
    Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
    Private Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As Long
    Private Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
        If Button = vbLeftButton Then
            bdown = True
            dx = x
            dy = y
            monidc = GetDC(0)
            drawmutirect monidc, dx, dy
        End If
    End Sub
    Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
        If bdown = True Then
            drawmutirect monidc, dx, dy
            dx = x
            dy = y
            drawmutirect monidc, dx, dy
        End If
    End Sub
    Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
        If bdown = True Then
            drawmutirect monidc, dx, dy
            ReleaseDC 0, monidc
            bdown = False
        End If
    End Sub
    Private Sub drawmutirect(destdc As Long, x As Long, y As Long)
        Dim rc As RECT
        With rc
            .Left = Left \ Screen.TwipsPerPixelX
            .Top = Top \ Screen.TwipsPerPixelY
            .Right = (x + Left) \ Screen.TwipsPerPixelX
            .Bottom = (y + Top) \ Screen.TwipsPerPixelY
        End With
        DrawFocusRect destdc, rc
        With rc
            .Left = .Left + 1
            .Top = .Top + 1
            .Right = .Right - 1
            .Bottom = .Bottom - 1
        End With
        DrawFocusRect destdc, rc
        With rc
            .Left = .Left - 2
            .Top = .Top - 2
            .Right = .Right + 2
            .Bottom = .Bottom + 2
        End With
        DrawFocusRect destdc, rc
    End Sub