[RESOLVED] SetROP2 : Erase Old Resizing Line then Draw new Resizing Line
I draw a dot line on Picturebox so that I can drag the line to move the margins. But very seldom the start (first) line still remains on the screen (look like two lines UpDown). What is going on?
I erase and draw a resizing line on Picture1.MouseMove:
Code:
Private CachedMouseDown As Boolean
Private cachedMouseDownX As Single
Private cachedMouseDownY As Single
Private cachedMouseMoveX As Single
Private cachedMouseMoveY As Single
Private Sub picture1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
If Button = vbLeftButton Then
cachedMouseDownX = x
cachedMouseDownY = y
CachedMouseDown = True
If CachedMouseDown Then
cachedMouseMoveY = cachedMouseDownY
End If
End If
End Sub
Private Sub picture1_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
If y >= TopMarginInPixels - 2 And y <= TopMarginInPixels + 2 Then
picture1.MousePointer = vbSizeNS
Else
picture1.MousePointer = vbDefault
End If
If picture1.MousePointer = vbSizeNS And CachedMouseDown then
If Not cachedMouseMoveY = y Then
DrawResizeLine picture1.hDc, 0, cachedMouseMoveY, picWidth , cachedMouseMoveY '--->Erase old Dot Line
DrawResizeLine picture1.hDc, 0, y, picWidth, y '--->Draw New Dot Line
cachedMouseMoveY = y
End If
End If
End Sub
Private Sub picture1_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
If Button = vbLeftButton Then
CachedMouseDown = False
picture1.Refresh
End If
End Sub
Public Sub DrawResizeLine(ByVal lhDc As Long, ByVal x1 As Long, ByVal y1 As Long, ByVal x2 As Long, ByVal y2 As Long)
Dim OldDrawMode As Long
OldDrawMode = GetROP2(lhDc)
SetROP2 lhDc, R2_NOTXORPEN
DrawLineEx lhDc, x1, y1, x2, y2, 0, 1, 2, True
SetROP2 lhDc, OldDrawMode
ReleaseDC 0, lhDc
End Sub
Public Sub DrawLineEx(ByVal hDc As Long, ByVal x1 As Long, ByVal y1 As Long, ByVal x2 As Long, ByVal y2 As Long, Optional ByVal crColor As Long = 0, Optional ByVal nWidth As Long = 1, Optional ByVal fnPenStyle As Long = PS_SOLID, Optional ByVal bNewPen As Boolean = True)
Dim lhPen As Long
Dim lhPenOld As Long
Dim tP As POINTAPI
Dim tLB As LOGBRUSH
If bNewPen Then
tLB.lbColor = crColor
lhPen = ExtCreatePen(PS_GEOMETRIC Or PS_ENDCAP_SQUARE Or fnPenStyle, nWidth, tLB, 0, ByVal 0&) 'PS_ENDCAP_FLAT
lhPenOld = SelectObject(hDc, lhPen)
End If
BeginPath hDc
MoveToEx hDc, x1, y1, tP
LineTo hDc, x2, y2
EndPath hDc
StrokePath hDc
If bNewPen Then
SelectObject hDc, lhPenOld
DeleteObject lhPen
End If
End Sub
Re: SetROP2 : Erase Old Resizing Line then Draw new Resizing Line
I found the problem:
The reason is the logic of "If y >= TopMarginInPixels - 2 And y <= TopMarginInPixels + 2 Then". While mouse on the resizing area then mouse down,the Y axis of mouse_Down is possible not be equal with the start line (Y=TopMarginInPixels), so the start line won't be erased by 2nd draw.
Re: [RESOLVED] SetROP2 : Erase Old Resizing Line then Draw new Resizing Line
Why do you call `ReleaseDC 0, lhDc` in `DrawResizeLine` when `lhDc` comes from `picture1.hDc`?
I would definately release locally acquired resources only i.e. will use `ReleaseDC` only if used `GetDC` somewhere in the beginning of the same routine.
Re: [RESOLVED] SetROP2 : Erase Old Resizing Line then Draw new Resizing Line
Originally Posted by wqweto
Why do you call `ReleaseDC 0, lhDc` in `DrawResizeLine` when `lhDc` comes from `picture1.hDc`?
I would definately release locally acquired resources only i.e. will use `ReleaseDC` only if used `GetDC` somewhere in the beginning of the same routine.
cheers,
</wqw>
Thank you point out the bug.
I forgot to remove it, I previously call GetDC(0) to use desktop foreground mix mode in DrawResizeLine function.
The real project draw Margin lines on a MemoryDC then call PictureBox.Refresh to bitblt on Picturebox.
Re: [RESOLVED] SetROP2 : Erase Old Resizing Line then Draw new Resizing Line
I was recently reported a bug with a splitter control of mine that used GetDC(0) to XOR the splitter on desktop device context when using remote desktop under Windows 8.1. Turns out there is a DPI virtualization implemented in newer OSes where an application hwnd contents can be down-scaled under certain conditions. RDP connection tries to use current client machine DPI to seamlessly integrated but if resuming a session with different DPI funny things happen. Anyway, using API call `LogicalToPhysicalPointForPerMonitorDPI` fixed the problem of mapping a local DC coordinates to screen coordinates for use woth GetDC(0)