views:

1034

answers:

5

We have an application that uses a dual monitor setup - User A will work with Monitor 1, and user B will work with Monitor 2 simultaneously. Monitor 2 is a touch screen device.

Now, the problem is, when User A types something in his screen, if User B tries to do something, User A will end up in losing the focus from his window, which is disastrous.

What might be a good solution to preserve the focus on the window in Monitor 1, even if User B do something with Monitor 2?

+3  A: 

To me, it sounds like you might want 2 PC's... or maybe host a VM on the PC, and give the VM access to the second monitor via a USB video "card" (not quite the right term). Mmost modern VM's allow USB transfer.

Most times, multi-head displays are either used to give a single user lots of screen real-estate, or as a display-only facility (for example, showing live network/server stats over a large infrastructure setup).

Marc Gravell
So, you want to say, there is 'NO' way of preserving the focus on one window when a user works with another window? Thanks
amazedsaint
I'm saying it will be hard and not simple; you'd probably need specialist knowledge, and possible special drivers. Beyond that, I don't know.
Marc Gravell
Thanks. But hosting a VM is a heavy weight solution.
amazedsaint
+1  A: 

I can';t see a way to allow two users to access the same desktop environment simultaneously without running into focus issues. If you think about it, allowing two applications (or in this case, one app with two user "areas" will always be problematic, since the application would need to attempt to keep track of which input device worked most recently with which area of the screen.

You might be able to add functionality to filter inputs per device and send each distinct input to a separate set of controls, but I imagine that would require some driver-level work.

ZombieSheep
+1  A: 

I never worked with touch screens, but I am inclined to think they work somehow like a mouse. So if this is true, I think you may be able to use Windows hooks to capture events. If the event is from the keyboard (which I assume is single), direct it to your first window. If the event is from the mouse, check its coordinates (or maybe device ID if there is one, I don't know). If it is within your first window, direct input to it. If it is in the second screen, direct input to your second window.

If the screen is not like a mouse, I guess you'll find another way to put a hook for it.

I don't know whether this would work. It's just a conceptual idea.

Edit: Of course you need to identify which application should receive the messages on the first screen. I guess Z-order can help, unless the user opens some on-top application. It may be better to track OnFocus messages (or something similar) to keep track of which application is getting focus (excluding your other app).

(Comments explaining any deficencies with this method are very welcome!)

Hosam Aly
Yes, they work somehow like a mouse. Most drivers simulate mouse clicks.
amazedsaint
So we should do something like Capture the window messages in the application running on Monitor 2, and if it is not a mouse click happened over the window of application running on Monitor 2, send it to the application running on monitor 1
amazedsaint
But we should know which application is active on monitor 1 currently
amazedsaint
I thought you had two windows, not two applications. But this shouldn't make much difference IMHO. Check my edited answer.
Hosam Aly
+3  A: 

It is possible with some elbow grease. Paste this code in the form that you show on the touch screen:

protected override CreateParams CreateParams {
  get {
    const int WS_EX_NOACTIVATE = 0x08000000;
    CreateParams param = base.CreateParams;
    param.ExStyle |= WS_EX_NOACTIVATE;
    return param;
  }
}

That makes sure that the form won't steal the focus from the main form. Make it look like this:

  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      Thread t = new Thread(SecondMonitor);
      t.IsBackground = true;
      t.SetApartmentState(ApartmentState.STA);
      t.Start();
    }
    private void SecondMonitor() {
      Form2 f2 = new Form2();
      f2.StartPosition = FormStartPosition.Manual;
      f2.Left = 800;   // Use Screen class here...
      f2.ShowDialog();
    }
Hans Passant
A: 

Can you not fake it? Have one window that spans both monitors and acts as a container for the windows that you're working with?

Stever B