为了在ComboBox
(或其他任何内容)上绘制文字,我会覆盖WndProc()
并抓住0x000F
消息 - WM_PAINT
。
代码如下:
Protected Overrides Sub WndProc(ByRef m As Message)
MyBase.WndProc(m)
If m.Msg = &HF Then
TextRenderer.DrawText(CreateGraphics, "The text over my control.", Font, _
ClientRectangle, ForeColor)
End If
End Sub
它工作得非常好,但是有一个问题:如果我在屏幕的一侧拖动父窗口(为了隐藏窗体的一部分),我的控件的可见部分将被无限重绘。这使得文本重新绘制!
我认为有一种方法只能绘制控件的无效(隐藏)部分。我该怎么办?
修改
以下是一张图片中的问题:http://i.stack.imgur.com/WqGfI.png(这是一个链接,因为我暂时无法发布图片。)
更新
我尝试使用BeginPaint API,但返回的PAINTSTRUCT结构中包含的RECT结构仅包含零。
If m.Msg = WM_PAINT Then
Dim ps As PAINTSTRUCT = New PAINTSTRUCT
BeginPaint(Handle, ps)
Console.WriteLine(ps.rcPaint.right)
'painting goes here
EndPaint(Handle, ps)
End If
我可以做点什么吗?我不知道如何处理,以便只绘制无效区域。
答案 0 :(得分:0)
一个好的经验法则是,永远不要使用Me.CreateGraphics。
尝试将代码更改为:
<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 Boolean
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
MyBase.WndProc(m)
If m.Msg = &HF Then
Dim dc As IntPtr = GetWindowDC(m.HWnd)
Using g As Graphics = Graphics.FromHdc(dc)
TextRenderer.DrawText(g, "The text over my control.", Font, _
ClientRectangle, ForeColor)
End Using
ReleaseDC(m.HWnd, dc)
End If
End Sub
答案 1 :(得分:0)
如果没有实际更新,您可能会尝试绘画。 PAINTSTRUCT的一部分指示是否应该实际擦除窗口。
这是我过去使用的内容。 GetUpdateRect可让您轻松查看是否实际更新过任何内容以及获取更新后的区域,而无需致电BeginPaint。请记住,BeginPaint仅在您没有将消息传递给基类时。 (我在此片段中使用NativeWindow类进行子类化。)
Dim hasUpdates As Boolean
Dim updRect As RECT
Dim r As Rectangle
hasUpdates = GetUpdateRect(_parentControl.Handle, updRect, False)
With updRect
r = New Rectangle(.Left, .Top, .Right - .Left, .Bottom - .Top)
End With
' Invalidate the control so that the whole thing will be redrawn since
' our custom painting routine could redraw the entire client area.
If hasUpdates Then _parentControl.Invalidate(r)
' Pass the message along to be handled by the default paint event.
MyBase.DefWndProc(m)
' Now draw extras over the existing control.
If hasUpdates Then Me.PaintExtras(r)
如果hasUpdates为False,那么你要做的就是退出例程。
就用于绘制的图形而言,我使用Graphics.FromHwnd(ctrl.Handle)