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

C# 在多个监视器上绘制所有窗口,c#,gdi+,desktop,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, cursorLoc

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

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);
}
从本质上讲,这在理论上应该利用任何一个监视器。但是,它只利用了主对象。所以,为了解决这个问题,我得到了所有显示器的直流电,并试图这样做

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刷新桌面来消除闪烁吗?我只画了两条线,它疯狂地闪烁着。

在第一部分我无能为力。我假设您正在绘制绘制绘制事件中的线条。使用双缓冲来消除闪烁。

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

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

那就开始在上面画画吧。(我喜欢它,因为它很容易为线条和图像添加效果)。保证不闪烁

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

这样你就不必求助于GDI来完成你的工作


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

不幸的是,由于以下原因,两个答案都没有任何帮助:

我仅限于Windows窗体,因为这是为WF构建的基本框架。 我尝试过透明键/窗体技巧,但仍然闪烁太多

我认真地尝试了几乎十种不同的方法,甚至我在谷歌上搜索DirectX/Direct3D、C#Desktop Hooks和其他方法都没有用


我所要做的就是画一个横跨整个桌面的十字线,1px x 1px。。当然,有些人必须有一些例子,说明如何做到这一点而不闪烁和良好的性能:?D3D、DX、GDI或其他\

这对我很有效。我使用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);
更多信息请点击此处:

您的代码没有按原样编译--您的图形对象名为“graphics”,但后来您将其用作“g”。graphics.FromHwnd(hdc)为我抛出OutOfMemoryException--对于从“\\\.DISPLAY1”创建的hdc,以及由EnumDisplayDevices返回的字符串创建的所有非零DC。。。