5

我正在使用以下代码在单个显示器上绘图:

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

4 回答 4

4

这对我有用。我使用 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

于 2013-03-30T03:13:23.867 回答
3

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

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

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

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

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

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

于 2009-03-30T08:59:40.877 回答
1

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

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

我认真地尝试了近十种不同的方法,甚至我在 Google 中搜索 DirectX/Direct3D、C# Desktop Hooks 和其他方法的结果都无济于事。

我要做的就是画一个横跨整个桌面的十字准线,1px x 1px ..肯定有人必须有一些例子来说明如何在不闪烁和良好性能的情况下做到这一点:?D3D、DX、GDI 还是其他?:\

于 2009-03-31T02:06:35.217 回答
0

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

于 2009-03-30T05:15:11.697 回答