Keep window on top and steal focus in WinForms

I realize that this would be COMPLETELY bad practice in normal situations, but this is just for a test app that needs to be taking input from a bar code scanner (emulating a keyboard). The problem is that I need to start up some scripts while scanning, so I need the window to regain focus directly after I click the script to run it. I've tried using Activate(), BringToFront(), Focus() as well as some Win32 calls like SetForegroundWindow(), Setcapture() and SetActiveWindow()... however the best I can get any of them to do is to make the taskbar item start blinking to tell me that it wants to have focus, but something is stopping it. BTW, I'm running this on XP SP2 and using .NET 2.0.

Is this possible?

Edit: To clarify, I am running the scripts by double-clicking on them in explorer. So I need it to steal focus back from explorer and to the test app.


Solution 1:

I struggled with a similar problem for quite a while. After much experimentation and guessing, this is how I solved it:

// Get the window to the front.
this.TopMost = true;
this.TopMost = false;

// 'Steal' the focus.
this.Activate();

Solution 2:

Visibility

Make the window a "Top-Most" window. This is the way the Task-Manager can remain on top of other windows. This is a property of a Form and you make the form top-most (floating above other windows) by setting the value to true.

You shouldn't need to override any of the "Active window" behaviour with the top-most setting.

Focus

I asked a similar question previously here on StackOverflow and the answer would solve your problem. You can make the application use a low-level input hook and get notification of the key-codes coming from the scanner. This way, your application always gets these keys even though the application does not have focus.

You may need to enhance the solution to squash the key-codes so that they are not transmitted to the "in-focus" application (e.g. notepad).

Since Windows 2000, there is no official mechanism for an application to grab focus without direct intervention of the user. Peeking at the input streams through the RawInputDevices hook is the only sensible way to go.

A number of articles may help (C# implementations)

  • RawInput article on CodeProject
  • MSDN documentation of RawInput