如何在C#中有效地绘制桌面?

时间:2010-05-25 14:50:29

标签: c# drawing gdi buffer onpaint

我想在C#中直接在桌面上绘图。从搜索一下,我最终使用Desktop HDC中的Graphics对象(null)。然后,我正常使用这个Graphics对象绘制。

问题是当重绘屏幕的任何部分时,我的形状会丢失。我尝试了一个While循环,但它实际上最终绘制的速度与应用程序一样快,这不是桌面的更新速率。

通常,我需要将我的绘图代码放在“OnPaint”事件中,但桌面上不存在这样的事情。

我该怎么做?

示例代码:https://stackoverflow.com/questions/1536141/how-to-draw-directly-on-the-windows-desktop-c

4 个答案:

答案 0 :(得分:15)

我针对类似要求发布了两个解决方案here

基本上你有两种选择。

1-获取桌面的图形对象并开始绘制。问题是如果您需要开始清除之前绘制的内容等。

Point pt = Cursor.Position; // Get the mouse cursor in screen coordinates 

using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) 
{         
  g.DrawEllipse(Pens.Black, pt.X - 10, pt.Y - 10, 20, 20); 
}

2-我在上面的链接中提供的第二个选项是创建一个透明的最顶层窗口,并在该窗口中完成所有绘图。这基本上为您可以绘制的桌面提供透明覆盖。正如我在原始答案中提到的那样,其中一个可能的缺点是,其他窗口也是最顶级的,并且是在应用程序启动后创建的,它会遮挡您最顶层的窗口。如果这是一个问题,这可以解决。

对于选项2,使表单透明就像使用透明度键一样简单,这允许鼠标点击等进入底层桌面。

BackColor = Color.LightGreen; 
TransparencyKey = Color.LightGreen; 

答案 1 :(得分:8)

当您绘制到HDC(NULL)时,您将以非托管方式绘制到屏幕。正如您所发现的,只要Windows刷新屏幕的这一部分,您的更改就会被覆盖。

根据您想要达到的目标,有几种选择:

  1. 可能会创建一个无边框 非矩形窗口。 (使用 SetWindowRgn创建一个窗口 非矩形。)您可以将其设为桌面窗口的子项。
  2. 子类化桌面窗口。这不是直截了当的,涉及到 将DLL注入 Explorer.exe进程。

答案 2 :(得分:3)

要获得桌面的OnPaint,您需要将桌面窗口子类化,并在收到WM_PAINT/WM_ERASEBKGND消息时使用绘图逻辑。

正如您链接的线程所说,您只能使用钩子(来自DLL的SetWindowsHookEx)拦截发送到外部进程窗口的消息。

如前所述,透明窗口是另一种方法,或者(取决于更新频率)复制,绘制和设置临时壁纸(如bginfo所做)。

答案 3 :(得分:1)

这很难做到。

制作自己的无边框形式会更容易,也更可靠。