使用 WM_PAINT 绘制无效矩形
为了在 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
它工作得很好,但是有一个问题:如果我将父窗口拖动到屏幕的一侧(为了隐藏窗口窗体的一部分),我的控件的可见部分将被无限重绘。这使得文本自身重新绘制!
我想有一种方法可以只绘制控件的无效(隐藏)部分。我该怎么办?
编辑
这是一张图片中的问题:https://i.sstatic.net /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
我可以用它做点什么吗?我不知道如何继续,以便只绘制无效区域。
In order to draw a text over a ComboBox
(or whatever else), I override WndProc()
and catch 0x000F
message -- which is WM_PAINT
.
Code is like the following:
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
It works very well, but there is a problem: if I drag parent window on a side of the screen (in order to hide a part of the window form), the visible part of my control is infinitely redrawn. This makes the text redrawn over itself!
I suppose there is a way to draw only invalidated (hidden) part of the control. How can I do?
EDIT
Here is the problem in one picture: https://i.sstatic.net/WqGfI.png (it's a link since I can't post image for now.)
UPDATE
I tried using BeginPaint API, but the RECT structure included in the returned PAINTSTRUCT structure contains only zeros.
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
Can I do something with that? I don't know how to proceed, in order to paint only invalidated area.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一个好的经验法则是,永远不要使用 Me.CreateGraphics。
尝试将您的代码更改为:
A good rule of thumb is, never use Me.CreateGraphics.
Try changing your code to this:
您可能会在没有实际更新的情况下尝试绘画。 PAINTSTRUCT 的一部分指示窗口是否应该实际被擦除。
这是我过去使用过的。 GetUpdateRect 可让您轻松查看是否任何内容实际上都已更新,并且无需调用 开始绘制。请记住,BeginPaint 仅在您不将消息传递给基类时才执行。 (我在这段代码中使用 NativeWindow 类进行子类化。)
因此,如果 hasUpdates 为 False,您要做的就是退出例程。
就用于绘制的图形而言,我已经成功使用 Graphics.FromHwnd(ctrl.Handle)
You might be attempting to paint when there has been no actual update. Part of the PAINTSTRUCT indicates whether the window should actually be erased.
Here's what I've used in the past. GetUpdateRect allows you to easily see if anything has actually been updated as well as get the updated region without having to call BeginPaint. Remember, BeginPaint is only when you're not passing the message down to your base class. (I'm subclassing using the NativeWindow class in this snippet.)
So what you would do is exit the routine if hasUpdates is False.
As far as the graphics to use to draw, I've had success using
Graphics.FromHwnd(ctrl.Handle)