Is it possible to take over just one screen of multiple screens completely with .NET on Windows?
Asked Answered
V

4

12

With .NET (any version) running on Windows XP/Vista/7/8 - is it possible to reserve one screen for a full-screen application and display data/graphics/whatever on it whilst keeping any other screens available for Windows UI user interaction such as the desktop or other apps?

The usage scenario / rules here are the following:

  1. The PC must be able to run all programs as-is.

  2. No interactivity is required on the .NET contents (i.e. no keypresses, mouse clicks etc).

  3. No other UIs or dialogs from other applications can penetrate the one predefined screen reserved for showing the output from the .NET executable.

  4. The predefined screen with the .NET contents must not have a visible mouse cursor AND the other screens must have their cursor boundaries as if there was no extra screen at all (i.e. the cursor must stop at the edges of the one or multiple desktops).

  5. The content must be visible even if the PC is locked (i.e. user is logged in but the workstation is locked from Explorer).

I know I could achieve this with some external USB controller that drives a secondary monitor or other display device and then manually build the contents/graphics to be pushed to this interface but I'm asking can I do this with the normal WDDM drivers w/ normal monitors?

Edit: To further clarify - I understand there are multiple approaches to achieve a somewhat similar result but the question here is can one comply with all of the specifications/rules above.

Vaporetto answered 13/2, 2013 at 18:45 Comment(6)
Do you use WPF or Windows Forms?Gullet
Just create a maximized borderless topmost form with a custom Cursor that's empty.Bronson
@Gullet - could use either or something else. I'm open to all ideas here.Vaporetto
@HansPassant - that would not abide to rules 1 and 4 as content from other applications could easily be lost under the maximized window and especially the (now invisible) cursor can (and will) wander off to this area making it hard for the end user to find again.Vaporetto
Eeek, I broke the rules!Bronson
@HansPassant break the rules/specs - get back a defect or even worse, don't get paid at the end of the day.Vaporetto
V
0

The approach selected that conforms to somewhat all of the design rules was... wait for it.. virtualization. It however does not conform to the requirement of using just .NET executables (to hack into WDDM).

The original PC is the virtualisation host with two guests. One for the .NET application and one for the end user which has the proper USBs etc assigned to it. This approach naturally has lots of caveats:

  • WDDM is not leveraged in any way and there are possible performance issues. For casual office application this however is not a problem at all.
  • Unless using Hyper-V, virtualisation software is always 3rd party.
  • Hyper-V within Hyper-V isn't possible so the guest cannot virtualise anything further (at least not with any reasonable speed since it would be running without a hypervisor).
  • In some cases, multiple licenses for any software is required.
  • No IPC or other interaction between the .NET executable and other apps between the two guests.

However, the solution itself works perfectly - in no way can the user override or interact with what's being shown on the additional screen as long as the underlying host is powered and does not crash itself. Locking the end-user PC has no effect on the other guest and so on.

Vaporetto answered 26/2, 2013 at 7:18 Comment(0)
S
4

It sounds to me like you are designing a .NET application that will be used purely for output (i.e to display a graph/chart, video etc). The application must have a dedicated monitor, and no other application (or even the cursor should be able to enter the bounds of the monitor).

My gut feeling is that whilst you can force your application to a particular monitor (XBMC has this functionality), I doubt you can prevent all of your other applications from entering the monitor's display region.

When I read the question, something in my head clicked and I thought "maybe you want something similar to cpu affinity, which you can set in windows, and force your application to only use particular cpu cores...maybe there is something similar for monitors/display regions?"

Sure enough, Windows provides these functions:

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

You should be able to pinvoke these without much trouble. However that will only solve you being able to force your application only a particular monitor. As for every other application in the system, I doubt you will be able to control their display affinity easily.

At a rough guess, you would need to use another Win32 API call to get references to all window handles in the system, and check their display affinity, and if they are displaying in your dedicated monitor, move them elsewhere.

this might help with getting all window handles:

How to get list or enumerate all handles of unmanaged windows with same class and name

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

Just thought I would throw this in there, it may not be helpful, but hopefully that should give you some more direction.

EDIT: I found this too...might be of some use

Reserve screen area in Windows 7

Shala answered 19/2, 2013 at 10:53 Comment(2)
None of these approaches seem to prevent mouse incursion into the reserved screen or keep the application visible even when the PC is locked.Vaporetto
@Vaporetto - Hans has already suggested a solution for dealing with the mouse. Again, I doubt you can force the mouse not to enter the screen region, but you can prevent it from displaying in that region by changing it's cursor to an empty one. Equally, I doubt you can make the application stay visible when the PC is locked...if you can, I'd be happy to hear how!Shala
W
4
  1. The PC must be able to run all programs as-is.

  2. No interactivity is required on the .NET contents (i.e. no keypresses, mouse clicks etc).

  3. No other UIs or dialogs from other applications can penetrate the one predefined screen reserved for showing the output from the .NET executable.

One way of achieving this could be to create a docking window (AppBar). That would have similar functionality as the Taskbar or Desktop Docks like Google Desktop etc.

These two articles could be of help:
CodeProject: AppBar using C#
CodeProject: Creating an application like Google Desktop in WPF and C#

Another way to address #3 is to use PInvoke (or even better, Managed WinAPI) to scan your computer for open windows at regular intervals. If a window is found to be 'trespassing', you just hook to it and move it away. Not the best approach but it works anyway.

4 . The predefined screen with the .NET contents must not have a visible mouse cursor AND the other screens must have their cursor boundaries as if there was no extra screen at all (i.e. the cursor must stop at the edges of the one or multiple desktops).

Set the cursor property of the form to an empty cursor. This effectively removes the mouse cursor.
Stopping the cursor from accessing that part of the screen is quite tricky. My best bet is to use Global Mouse Hooks to listen to cursor movement and stop the cursor from moving into areas occupied by your window. That would obviously render setting the cursor property of the form useless since the cursor is never on the form anyway.

5 . The content must be visible even if the PC is locked (i.e. user is logged in but the workstation is locked from Explorer)

I do not know of any way to achieve this short of creating a lock screen application because standard Windows behaviour is to turn off all monitors except the primary one.

Edit
You can display a window on the lock screen using psexec.exe -x. PSEXEC is part of the SysInternals suite, available for download from http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx.

If you intend to go this way (displaying your form on top of the lock screen), you'll need a way to determine when a user session is being locked so you resize your form and move it out of the way. Otherwise you'll have to find a way of unlocking the session from your app.

You may also want to have a look at this question How to display UI on logon screen in Windows 7 for other ways of implementing lock screen apps.

Wangle answered 19/2, 2013 at 11:56 Comment(1)
The AppBar is a great idea and I'll award you the bounty for it.Vaporetto
J
1

A WPF project I'm working on has gone the route of adding everything inside a "master container" inheriting from System.Windows.Window that is set up on launch based on user preference to be either all available screens, a window, or a single full screen. That control then just sets itself up based on the preference as follows:

    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;
    }
Johen answered 25/2, 2013 at 16:52 Comment(1)
otherwise nice idea, but doesn't prevent mouse incursion, does not stay visible when PC is locked and so forth.Vaporetto
V
0

The approach selected that conforms to somewhat all of the design rules was... wait for it.. virtualization. It however does not conform to the requirement of using just .NET executables (to hack into WDDM).

The original PC is the virtualisation host with two guests. One for the .NET application and one for the end user which has the proper USBs etc assigned to it. This approach naturally has lots of caveats:

  • WDDM is not leveraged in any way and there are possible performance issues. For casual office application this however is not a problem at all.
  • Unless using Hyper-V, virtualisation software is always 3rd party.
  • Hyper-V within Hyper-V isn't possible so the guest cannot virtualise anything further (at least not with any reasonable speed since it would be running without a hypervisor).
  • In some cases, multiple licenses for any software is required.
  • No IPC or other interaction between the .NET executable and other apps between the two guests.

However, the solution itself works perfectly - in no way can the user override or interact with what's being shown on the additional screen as long as the underlying host is powered and does not crash itself. Locking the end-user PC has no effect on the other guest and so on.

Vaporetto answered 26/2, 2013 at 7:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.