直接在屏幕上绘图时如何清理自己
我使用 BitBlt
和 GetDC(IntPtr.Zero)
直接在屏幕上绘图。当我完成后,有什么方法可以在整个屏幕上调用“刷新”或“无效”,这样我就不会在各处留下大块的油漆(从数字角度来说)?
更新:当您像我一样直接在屏幕上绘制时,您绘制的任何内容都会保留在那里,直到其下方的窗口重新绘制自身(这样做时,会重新绘制其覆盖的屏幕部分)。
问题是 Windows 桌面的某些部分在很长一段时间内不会重新绘制自己。例如,如果我在任务栏顶部绘制,实际任务会相当快地重新绘制自己(以及“开始”按钮等),但任务栏本身会保留我绘制的内容长达几分钟。
如果我的应用程序有一个覆盖整个屏幕的窗口,我只需在该表单上调用 Invalidate()
,这将导致它重新绘制自身,从而重新绘制整个屏幕。我需要的是在整个屏幕本身上调用 Invalidate
或 Refresh
的方法。
I'm drawing directly to the screen using BitBlt
and GetDC(IntPtr.Zero)
. Is there some way to call Refresh or Invalidate on the whole screen when I'm done, so that I don't leave big chunks of paint everywhere (digitally speaking)?
Update: when you draw directly to the screen like I'm doing, whatever you draw remains there until the window underneath it repaints itself (and in so doing, repaints the portion of the screen it's covering).
The problem is that some portions of the windows desktop don't repaint themselves for long periods. For example, if I draw over top of the task bar, the actual tasks repaint themselves fairly quickly (along with the Start button etc.), but the taskbar itself retains what I've drawn for as long as a couple of minutes.
If my app had a window that covered the entire screen, I would just call Invalidate()
on that form which would cause it to repaint itself and thus the entire screen. What I need is some way of calling Invalidate
or Refresh
on the whole screen itself.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
InvalidateRect(NULL, NULL, TRUE)
应该使所有窗口无效并重绘。尽管这将是昂贵的操作。
另一种方法是记住您绘制的位置并尝试枚举该矩形中的所有窗口并仅使它们无效。
当您想要使窗口无效时,您还可以尝试在已绘制的区域上创建一个透明窗口。请注意,您想要执行 alpha 混合分层窗口,而不是 WS_TRANSPARENT 窗口。如果您使用 99% 的透明度来执行此操作,则 DWM 应该在其被破坏后重新绘制其下方的所有窗口。当然,这可能会导致目标区域出现几乎察觉不到的闪烁,因为在销毁窗口之前会对其进行 alpha 混合。
InvalidateRect(NULL, NULL, TRUE)
should invalidate and redraw all windows. Though it will be expensive operation.An alternative approach would be to remember where you've drawn and try to enumerate any windows in that rectangle and invalidate only them.
You can also try creating a transparent window over the area you've painted when you want to invalidate the windows there. Note that you want to do alpha-blended layered window, not an WS_TRANSPARENT window. If you do it with 99% transparency, the DWM should repaint all the windows below it once it's destroyed. Of course, this could lead to barely perceptible flicker over the target region due to the alphablending of the window before you destroy it.
“屏幕”由一组窗口组成,这些窗口是桌面窗口的父窗口。我想您可以简单地使桌面窗口无效,尽管您可能需要递归其子窗口(顶级应用程序窗口)并使它们也无效。 (多个显示器也可能存在问题,但这应该为您提供一个起点)
请参阅 GetDesktopWindow()。
或者,创建一个覆盖整个屏幕的表单,并使用透明绘图。完成后只需关闭表单即可。
The "screen" is made up of a set of windows that are parented to the Desktop Window. I would imagine that you could simply invalidate the desktop window, though you may need to recurse through its child windows (the top-level application windows) and invalidate them too. (There may also be issues with mutliple monitors, but this should give you a starting point)
See GetDesktopWindow().
Alternatively, create a form that covers the entire screen, and use transparent drawing. Then simply close the fom when you're done.