12

使用在 Windows XP/Vista/7/8 上运行的 .NET(任何版本) - 是否可以为全屏应用程序保留一个屏幕并在其上显示数据/图形/任何内容,同时为 Windows UI 用户保留任何其他屏幕可用交互,例如桌面或其他应用程序?

这里的使用场景/规则如下:

  1. PC 必须能够按原样运行所有程序。

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

  3. 其他应用程序的任何其他 UI 或对话框都不能穿透为显示 .NET 可执行文件的输出而保留的一个预定义屏幕。

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

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

我知道我可以使用一些驱动辅助显示器或其他显示设备的外部 USB 控制器来实现这一点,然后手动构建要推送到此界面的内容/图形,但我问我可以使用普通的 WDDM 驱动程序来做到这一点/普通显示器?

编辑:进一步澄清 - 我知道有多种方法可以达到类似的结果,但这里的问题是可以符合上述所有规范/规则。

4

4 回答 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

您应该能够轻松地调用这些。但是,这只会解决您只能强制您的应用程序使用特定监视器的问题。至于系统中的所有其他应用程序,我怀疑您能否轻松控制它们的显示亲和力。

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

这可能有助于获取所有窗口句柄:

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

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

只是想我会把它扔在那里,它可能没有帮助,但希望这会给你更多的方向。

编辑:我也发现了这个......可能有一些用处

在 Windows 7 中保留屏幕区域

于 2013-02-19T10:53:59.557 回答
4
  1. PC 必须能够按原样运行所有程序。

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

  3. 其他应用程序的任何其他 UI 或对话框都不能穿透为显示 .NET 可执行文件的输出而保留的一个预定义屏幕。

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

这两篇文章可能会有所帮助:
CodeProject: AppBar using C#
CodeProject: Creating an application like Google Desktop in WPF and C#

解决 #3 的另一种方法是使用 PInvoke(甚至更好的Managed WinAPI)定期扫描您的计算机以查找打开的窗口。如果发现一扇窗户“侵入”,您只需钩住它并将其移开。不是最好的方法,但它仍然有效。

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

将表单的光标属性设置为空光标。这有效地删除了鼠标光标。
阻止光标访问屏幕的那部分是非常棘手的。我最好的选择是使用Global Mouse Hooks来监听光标移动并阻止光标移动到您的窗口占据的区域。这显然会使设置表单的光标属性无用,因为光标永远不会在表单上。

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

除了创建锁屏应用程序之外,我不知道有什么方法可以实现这一点,因为标准的 Windows 行为是关闭除主监视器之外的所有监视器。

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

如果您打算采用这种方式(在锁定屏幕顶部显示表单),您将需要一种方法来确定用户会话何时被锁定,以便调整表单大小并将其移开。否则,您将不得不找到一种从您的应用程序中解锁会话的方法。

您可能还想看看这个问题如何在 Windows 7 的登录屏幕上显示 UI,以了解其他实现锁屏应用程序的方法。

于 2013-02-19T11:56:46.203 回答
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;
    }
于 2013-02-25T16:52:08.233 回答
0

选择符合所有设计规则的方法是……等待它……虚拟化。但是,它不符合仅使用 .NET 可执行文件(入侵 WDDM)的要求。

原始 PC 是具有两个来宾的虚拟化主机。一种用于 .NET 应用程序,另一种用于分配了适当 USB 等的最终用户。这种方法自然有很多警告:

  • 没有以任何方式利用 WDDM,并且可能存在性能问题。然而,对于临时办公应用来说,这根本不是问题。
  • 除非使用 Hyper-V,否则虚拟化软件始终是第 3 方。
  • Hyper-V 中的 Hyper-V 是不可能的,因此来宾无法进一步虚拟化任何东西(至少没有任何合理的速度,因为它将在没有管理程序的情况下运行)。
  • 在某些情况下,任何软件都需要多个许可证。
  • .NET 可执行文件和两个来宾之间的其他应用程序之间没有 IPC 或其他交互。

但是,解决方案本身可以完美运行 - 只要底层主机通电并且不会自行崩溃,用户就无法覆盖或与附加屏幕上显示的内容进行交互。锁定最终用户 PC 对其他访客等没有影响。

于 2013-02-26T07:18:07.047 回答