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
看看这样改能不能达到你的要求?(我想你处理的一定是无边框窗体,所以就没处理窗体标题栏带来的坐标误差了,你可自己加上) 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
在VB里要保存图片可以直接使用StdPicture对象
如果你是用GDI在内存DC上绘图,可以使用OleCreatePictureIndirect函数将位图句柄转换成Picture对象,然后再保存。
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
从你的代码看,似乎是想在通过窗体中的拖动动作,而在屏幕上画一些矩形边框?若是这种需求,那你的代码问题就太多了,也不必这么兴师动众!我可以帮你改改。
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