获取具有多个监视器的整个屏幕的设备上下文

4
我需要用C#在所有内容上画一条线(用鼠标)。我可以通过使用P/Invoke获取桌面窗口的Graphics对象:
DesktopGraphics = Graphics.FromHdc(GetDC(IntPtr.Zero));
然而,使用此图形对象绘制的任何内容都只显示在左侧监视器上,右侧监视器上没有任何内容。它不会失败或出现任何问题,只是不显示。
创建Graphics对象后,它显示可见剪辑区域为1680 x 1050,这是我的左侧监视器的分辨率。我只能假设它仅获取了左侧监视器的设备上下文。有没有办法获取所有(或任意数量)监视器的设备上下文?
编辑3/7/2009: 关于我使用的修复程序的其他信息。我使用colithium提供的修复程序来编写以下代码,以创建每个监视器的图形对象,并存储偏移量,以便我可以将全局鼠标点转换为图形表面上的有效点。
private void InitializeGraphics()
{
    // Create graphics for each display using compatibility mode
    CompatibilitySurfaces = Screen.AllScreens.Select(s => new CompatibilitySurface()
        {
            SurfaceGraphics = Graphics.FromHdc(CreateDC(null, s.DeviceName, null, IntPtr.Zero)),
            Offset = new Size(s.Bounds.Location)
        }).ToArray();
}

private class CompatibilitySurface : IDisposable
{
    public Graphics SurfaceGraphics = null;
    public Size Offset = default(Size);

    public PointF[] OffsetPoints(PointF[] Points)
    {
        return Points.Select(p => PointF.Subtract(p, Offset)).ToArray();
    }

    public void Dispose()
    {
        if (SurfaceGraphics != null)
            SurfaceGraphics.Dispose();
    }
}

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

好的,现在这真的非常奇怪。您的代码可以用于FillRectangle()方法,但不能用于SurfaceGraphics对象的DrawString和其他方法。无论我使用哪个SurfaceGraphics,DrawString始终会在主显示器上绘制,但FillRectangle的行为是正确的。 :| - Cipi
2个回答

3

这里是另一个遇到同样问题的人的链接。它通过调用以下函数解决:

CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL)

这将向所有监视器返回一个DC。


0

以下 URL 可获取 EnumDisplayMonitor,或可解决您的问题

MSDN

如需检索有关所有显示器的信息,请使用以下代码:

EnumDisplayMonitors(NULL, NULL, MyInfoEnumProc, 0); 还有一个 URL 给出在 MSJ


你也是正确的。我使用了EnumDisplayMonitors来获取设备名称,然后将其传递给CreateDC。谢谢! - Dylan Vester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接