在多个监视器上绘制所有窗口

时间:2009-03-30 03:07:54

标签: c# gdi+ desktop

我使用以下代码在单个监视器上绘制:

Point cursorLocation;
NativeMethods.GetCursorPos(out cursorLocation);
Screen screen = Screen.FromPoint(cursorLocation);

Point h1 = new Point(screen.Bounds.Left, cursorLocation.Y);
Point h2 = new Point(screen.Bounds.Right, cursorLocation.Y);
Point v1 = new Point(cursorLocation.X, screen.Bounds.Top);
Point v2 = new Point(cursorLocation.X, screen.Bounds.Bottom);

using (Graphics graphics = Graphics.FromHwnd(NativeMethods.GetDesktopWindow())) {
    NativeMethods.SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);
    graphics.DrawLine(Pens.Red, h1, h2);
    graphics.DrawLine(Pens.Red, v1, v2);
}

本地,这个 理论上在任一监视器上绘制。但是,它只取决于初级。所以,为了解决这个问题,我得到了所有显示器的DC并尝试这样做。

IntPtr hdc = NativeMethods.CreateDC("DISPLAY", IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
Graphics graphics = Graphics.FromHdc(hdc);
graphics.DrawLine(Pens.Red, h1, h2);
graphics.DrawLine(Pens.Red, v1, v2);
graphics.Dispose();
NativeMethods.ReleaseDC(IntPtr.Zero, hdc);

去图,这根本不会画到屏幕上。我已经尝试过CreateDC的各种重载,以及搜索SO和其他资源,我很难过。


一旦解决了这个问题,任何人都知道如何通过使用SHCHangeNotify刷新桌面来摆脱闪烁?我只画两条线,它像疯了一样闪烁..)

4 个答案:

答案 0 :(得分:3)

这不是你问题的答案,但如果你没有问题,我会建议尝试使用WPF来解决这个问题。我玩过其他类型的桌面交互,比如透明度,与GDI替代方案相比,WPF闪电般快。

放置wpf应用程序并调整其​​大小以适合您需要绘制的所有区域。然后将其设置为透明,并确保其点击(我认为这是默认的100%透明度)。这样,只要你在这个大型WPF画布/表格上没有任何东西,所有鼠标事件都会点击进入桌面。

然后开始画上它。 (我喜欢它,因为它很容易为线条和图像添加效果)。保证没有闪烁。

或者,您可以在普通的Windows窗体上使用相同的方案。

这样你就不必转向GDI去做你的工作了。

我认为,当你现在接近它时,你能够做到这一点的唯一方法就是挂钩桌面WM_PAINT上的窗口消息,并在那里做你的工作。

答案 1 :(得分:1)

遗憾的是,由于以下原因,任何答案都没有任何帮助:

我仅限于Windows Forms,因为这是为WF构建的基础框架。 我尝试过TransparencyKey / Form技巧,但仍然闪烁太多。

我认真尝试了近十种不同的方法,甚至我在谷歌搜索DirectX / Direct3D,C#Desktop Hooks等搜索结果都让我无济于事。

我要做的就是绘制一个横跨整个桌面的十字准线,1px x 1px ..当然有人必须有一些如何做到这一点的例子,没有闪烁和良好的性能:? D3D,DX,GDI还是其他? :\

答案 2 :(得分:1)

这对我有用。我使用EnumDisplayDevices来获取名称。

[DllImport("gdi32.dll")]
public static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData);

var hdc = CreateDC(@"\\.\DISPLAY1", "", "", IntPtr.Zero);
Graphics g = Graphics.FromHdc(hdc);
var pt = Cursor.Position;
g.DrawEllipse(Pens.BlueViolet, pt.X - 100, pt.Y - 100, 200, 200);

更多信息: http://msdn.microsoft.com/en-us/library/windows/desktop/dd145179(v=vs.85).aspx

答案 3 :(得分:-1)

第一部分无法帮助。我假设您在Paint事件中绘制线条。使用双缓冲来消除闪烁。