问题
我试图在子类别ListBox的表面上画一个边框,我得到了很好的结果:
但如果我滚动控件,就会发生这种情况:
问题
在 C#或 VB.Net 中,我如何才能在控件边缘上正确绘制边框,如图片1?
(澄清:不是每个项目的边框)
CODE
这就是我在做的事情:
public class mylistbox : inherits listbox
Public Sub New()
MyBase.DrawMode = Windows.Forms.DrawMode.OwnerDrawVariable
End Sub
Private Sub DrawBorder(ByVal g As Graphics)
ControlPaint.DrawBorder(g, Me.ClientRectangle,
BorderColor, ButtonBorderStyle)
End Sub
Private Sub MyBase_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) _
Handles MyBase.DrawItem
Me.ColorizeItems(e)
End Sub
Private Sub ColorizeItems(ByVal e As DrawItemEventArgs)
' non important code here...
Me.DrawBorder(Graphics.FromHwnd(Me.Handle))
End Sub
end class
答案 0 :(得分:1)
借鉴 WM_NCPAINT(133):
//
<DllImport("User32.dll")>_
Public Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Dim HDC As IntPtr
If m.Msg = 133 Then
HDC = GetWindowDC(m.HWnd)
If HDC <> IntPtr.Zero Then
MyBase.WndProc(m) //call it to draw what it needs
Using g As Graphics = Graphics.FromHdc(HDC)
g.DrawRectangle(Pens.Blue, 0, 0, Me.Width - 1, Me.Height - 1)
End Using
ReleaseDC(m.HWnd, HDC)
Return
End If
End If
MyBase.WndProc(m)
End Sub
修改强>
在 WM_NCPAINT 中挖掘更多内容,你也可以这样做:
//
<DllImport("User32.dll")> _
Private Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<StructLayout(LayoutKind.Sequential)> _
Private Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
<DllImport("gdi32.dll")> _
Private Shared Function CreateRectRgnIndirect(ByRef lpRect As RECT) As IntPtr
End Function
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Dim HDC As IntPtr
Dim rgn As IntPtr
Dim rt As RECT
Dim pnt As Point
If m.Msg = 133 Then
HDC = GetWindowDC(m.HWnd)
pnt = Me.PointToScreen(New Point(0, 0))
rt.Left = pnt.X
rt.Top = pnt.Y
rt.Right = rt.Left + Me.Width - 4
rt.Bottom = rt.Top + Me.Height - 4
rgn = CreateRectRgnIndirect(rt)
If HDC <> IntPtr.Zero Then
Using g As Graphics = Graphics.FromHdc(HDC)
g.DrawRectangle(Pens.Red, 0, 0, Me.Width - 1, Me.Height - 1)
End Using
m.WParam = rgn
ReleaseDC(m.HWnd, HDC)
End If
End If
MyBase.WndProc(m)
End Sub
我们正在尝试创建一个 rect ,它不包含边框但包含垂直滚动条。从此 rect 创建区域并将其传递给 wParam 。