使用Graphics.FromHwnd在屏幕上绘图和清除

我正在尝试创建一个程序,它获取光标下窗口的句柄,显示有关它的一些数据,并在整个窗口的顶部绘制一个填充矩形(具有非常低的alpha)。 我正在使用C#和winforms。

我已经成功了,但问题是我的draw方法是在BackgroundWorker的循环中并且它不断在窗口上制作越来越多的矩形( – >具有更高alpha的矩形)或者当将鼠标移动到另一个窗口时旧的仍然存在。

我没有设法找到一个方法来清除绘制的矩形,因为它只是在屏幕上“是”,并没有绑定到图形对象或任何东西。

我尝试过使用某些原生方法,比如

[DllImport("User32.dll")] public static extern Int64 SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] public static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase); [DllImport("user32.dll")] public static extern bool UpdateWindow(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags); 

但以上都没有正常工作。 它们中的一些确实有效,但是当消息进入队列时,重绘不会立即发生,或者非常缓慢和闪烁(闪烁等)。

所以,问题是,如何使用Graphics.FromHwnd(handleOfWindowUnderCursor)“删除”我绘制的矩形? 我实际上认为它在其他窗口上绘制并不重要,因为我在试图摆脱我自己的forms上的图纸时也遇到了同样的问题(从来没有得到那个固定!)。

或者,有关如何在不使用我现在的方法的情况下完成绘制和删除光标下窗口上的矩形的任何建议?

我注意到绘图使用

 Graphics g = Graphics.FromHwnd(form.Handle); 

在其控件下绘制表单背景。 你想要成就吗?

 // draw the rectangle Brush b = new SolidBrush(Color.FromArgb(20, 0, 0, 255)); g.FillRectangle(b, new Rectangle(5, 5, 200, 200)); // clear the rectangle g.Clear(this.BackColor); 

如果我直接在屏幕上画画,用这个:

 Graphics g = Graphics.FromHwnd(IntPtr.Zero); 

Windows刷新屏幕后,矩形立即消失。

还有第三种选择,这不是真正的直截了当。

创建一个不透明度较低的表单,将TopMost属性设置为true且不带边框,而不是绘制矩形。 然后让它对事件透明:

 protected override void WndProc(ref Message m) { const int WM_NCHITTEST = 0x0084; const int HTTRANSPARENT = (-1); if (m.Msg == WM_NCHITTEST) { m.Result = (IntPtr)HTTRANSPARENT; } else { base.WndProc(ref m); } } 

之后您必须注意的唯一事项是此表单的可见,位置和大小属性。

  bool change = false; private void timer1_Tick(object sender, EventArgs e) { try { if (change) { InvalidateRect(IntPtr.Zero, IntPtr.Zero, true); change = false; } else { PaintRectangleToScreen(); change = true; } } catch (System.Exception caught) { MessageBox.Show(caught.Message); } }