在Windows上使用.NET是否可能完全接管多个屏幕中的单个屏幕?

12
在Windows XP/Vista/7/8上运行任何版本的.NET,是否可以保留一个屏幕用于全屏应用程序,并在其中显示数据/图形/其他内容,同时保留任何其他屏幕以供 Windows UI 用户交互,例如桌面或其他应用程序?
使用场景/规则如下:
  1. PC必须能够按原样运行所有程序。
  2. .NET内容不需要任何交互(即没有按键、鼠标点击等)。
  3. 其他应用程序的UI或对话框不能穿透预定义的屏幕,该屏幕用于显示从.NET可执行文件中输出的内容。
  4. 具有.NET内容的预定义屏幕不得具有可见的鼠标光标,并且其他屏幕必须具有其光标边界,就像根本没有额外的屏幕一样(即光标必须停止在一个或多个桌面的边缘)。
  5. 即使PC被锁定(即用户已登录但工作站是从资源管理器锁定的),内容也必须可见。
我知道我可以通过某些外部USB控制器实现这一点,该控制器驱动第二个监视器或其他显示设备,然后手动构建要推送到此接口的内容/图形,但我想知道是否可以使用常规WDDM驱动程序和普通监视器实现这一点?
编辑:为了进一步澄清-我理解有多种方法可以实现类似的结果,但问题在于是否能够符合上述所有规格/规则。

你使用WPF还是Windows Forms? - alu
3
只需创建一个最大化的无边框顶层窗体,并使用自定义光标,该光标为空即可。 - Hans Passant
@alu - 可以使用任何一种或其他东西。我对所有想法都持开放态度。 - allu
1
@HansPassant - 这样做不符合规则1和4,因为其他应用程序的内容很容易在最大化的窗口下丢失,特别是(现在看不见的)光标可能会漫游到这个区域,使最终用户难以再次找到它。 - allu
哎呀,我违反了规则! - Hans Passant
1
@HansPassant 违反规则/规范 - 可能会出现缺陷或更糟糕的是,最终可能无法得到支付。 - allu
4个回答

4
我觉得你正在设计一个.NET应用程序,纯粹用于输出(例如显示图表/视频等)。该应用程序必须有一个专用的监视器,并且没有其他应用程序(甚至光标)能够进入监视器的范围。

我的直觉是,尽管您可以将应用程序强制定位到特定的监视器(XBMC具有此功能),但我怀疑您无法阻止所有其他应用程序进入监视器的显示区域。

当我读到这个问题时,脑海中的某些东西点击了一下,我想:“也许你想要类似于CPU亲和力的东西,在Windows中可以设置,并强制应用程序仅使用特定的CPU核心...也许有类似于监视器/显示区域的东西?”

果然,Windows提供了这些功能:

http://msdn.microsoft.com/en-gb/library/windows/desktop/dd375340(v=vs.85).aspx

http://msdn.microsoft.com/en-gb/library/windows/desktop/dd375338(v=vs.85).aspx

您应该可以轻松使用pinvoke调用它们。然而,这只能解决您能够强制将应用程序固定在特定监视器的问题。至于系统中的其他所有应用程序,我怀疑您是否能够轻松控制它们的显示亲和性。

粗略猜测,您需要使用另一个Win32 API调用来获取系统中所有窗口句柄的引用,并检查它们的显示亲和性,如果它们正在您专用的监视器上显示,则将它们移动到其他位置。

以下内容可能有助于获取所有窗口句柄:

如何获取具有相同类和名称的未托管窗口的所有句柄列表或枚举

http://msdn.microsoft.com/en-us/library/ms633497%28VS.85%29.aspx

我觉得我应该提一下,这可能没有什么帮助,但希望能给你一些更多的方向。

编辑:我也找到了这个...可能会有所帮助

在Windows 7中保留屏幕区域


这些方法似乎都无法防止鼠标进入“保留”屏幕,也无法在PC锁定时保持应用程序可见。 - allu
@allu - Hans已经提出了处理鼠标的解决方案。我仍然怀疑你不能强制鼠标不进入屏幕区域,但是你可以通过将其光标更改为空白来防止其在该区域显示。同样,我怀疑你不能使应用程序在PC被锁定时保持可见...如果你能做到,我很乐意听听你的想法! - Matthew Layton

4
  1. 计算机必须能够按原样运行所有程序。

  2. .NET内容上不需要交互(即没有按键、鼠标点击等)。

  3. 来自其他应用程序的任何其他UI或对话框都不能进入预定义的屏幕,该屏幕保留用于显示.NET可执行文件的输出。

实现这一点的一种方法是创建一个停靠窗口(AppBar)。它将具有与任务栏或桌面停靠栏(如Google桌面等)类似的功能。

这两篇文章可能会有所帮助:
CodeProject: 使用C#创建AppBar
CodeProject: 使用WPF和C#创建类似Google桌面的应用程序

解决问题#3的另一种方法是使用PInvoke(甚至更好的是Managed WinAPI)定期扫描计算机上打开的窗口。如果发现某个窗口正在“入侵”,则只需挂钩并将其移动。这不是最佳方法,但它仍然可以工作。

4. 预定义屏幕上的.NET内容必须没有可见鼠标光标,并且其他屏幕的光标边界必须就像根本不存在额外的屏幕一样(即光标必须停在一个或多个桌面的边缘)。

将窗体的光标属性设置为空光标。这实际上会删除鼠标光标。
防止光标进入该屏幕部分非常棘手。我最好的猜测是使用全局鼠标钩子来监听光标移动,并阻止光标移动到您的窗口所占用的区域。那显然会使将窗体的光标属性设置无效,因为光标从未在窗体上。

5. 即使PC被锁定(即用户已登录但工作站已被资源管理器锁定),内容也必须可见。

除了创建锁屏应用程序外,我不知道任何实现这一点的方法,因为标准Windows行为是关闭所有显示器,除了主显示器。

编辑
您可以使用psexec.exe -x在锁定屏幕上显示窗口。 PSEXEC是SysInternals套件的一部分,可从http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx下载。

如果您打算采用这种方式(在锁定屏幕上显示表单),您需要一种方法来确定用户会话何时被锁定,以便调整表单大小并将其移开。否则,您将不得不找到一种从您的应用程序中解锁会话的方法。
您还可以查看此问题如何在Windows 7登录屏幕上显示UI,以了解其他实现锁定屏幕应用程序的方法。

AppBar是一个很棒的想法,我会为此奖励你的赏金。 - allu

1
我正在处理的一个WPF项目采用了将所有内容添加到一个“主容器”中,该容器继承自System.Windows.Window,并在启动时根据用户偏好设置为所有可用屏幕、窗口或单个全屏幕。然后,该控件根据偏好进行设置,如下所示:
    private void SpanAllMonitors()
    {
        WindowStyle = WindowStyle.None;
        ResizeMode = ResizeMode.NoResize;
        Width = SystemParameters.VirtualScreenWidth;
        Height = SystemParameters.VirtualScreenHeight;
        Left = SystemParameters.VirtualScreenLeft;
        Top = SystemParameters.VirtualScreenTop;
    }

    private void SingleScreen()
    {
        WindowStyle = WindowStyle.None;
        ResizeMode = ResizeMode.NoResize;
        Width = SystemParameters.PrimaryScreenWidth;
        Height = SystemParameters.PrimaryScreenHeight;
        // this will take over the 'primary' monitor, additional math
        // should allow you to place it on a secondary or other monitor
        Left = 0;
        Top = 0;
    }

不错的想法,但无法防止鼠标干扰,锁定电脑时也无法保持可见等问题。 - allu

0
所选的符合设计规则的方法是……等等……虚拟化。然而,它不符合只使用.NET可执行文件(来入侵WDDM)的要求。
原始PC是虚拟化主机,有两个客户端。一个用于.NET应用程序,另一个用于最终用户,其具有适当的USB等分配。这种方法自然有很多注意事项:
  • 没有以任何方式利用WDDM,可能存在性能问题。对于普通办公应用程序,这并不是问题。
  • 除非使用Hyper-V,否则虚拟化软件始终是第三方的。
  • 无法在Hyper-V中进行嵌套虚拟化,因此客户端不能进一步虚拟化任何内容(至少不能以任何合理的速度运行,因为它将在没有超级监视器的情况下运行)。
  • 在某些情况下,需要多个软件许可证。
  • .NET可执行文件与两个客户端之间没有IPC或其他交互。

然而,解决方案本身完美地工作-只要底层主机已启动且不会崩溃,用户无论如何都无法覆盖或与附加屏幕上显示的内容进行交互。锁定最终用户PC对其他客户端没有影响,依此类推。


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