2

How can I ensure my C# console application is always in front? e.i. if a person clicks away from the console, how can I detect that the console has lost the focus an bring it back to front? I have this C# console application that is waiting for users to scan bar codes, if for some reason someone clicks away from the console window then the barcode data will be "lost". I took a look at this code posted on another thread;however, I can not seem to get this to work for me: bring a console window to front in c# This code thanks to @ILan keeps the console ontop of all windows, but it does not set the "focus" to keep capturing the incoming data.

   class Program
{
    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hWnd, 
                                    IntPtr hWndInsertAfter, 
                                    int X, 
                                    int Y, 
                                    int cx, 
                                    int cy, 
                                    uint uFlags);
    static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
    const uint SWP_NOSIZE = 0x0001, SWP_NOMOVE = 0x0002, SWP_SHOWWINDOW = 0x0040;

    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();

    static void Main()
    {
        IntPtr handle = GetConsoleWindow();
        SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
        Console.WriteLine($"Hello handle: {handle}");
        Console.ReadLine();
    }
}
sam goto
  • 49
  • 9
  • @CamiloTerevinto, and where is it being called... ;-) –  Oct 27 '18 at 21:56
  • 1
    Since you have the handle to the window, you could use the code in [this question](https://stackoverflow.com/questions/1528473/make-a-window-topmost-using-a-window-handle) to make it topmost. – meJustAndrew Oct 27 '18 at 21:57
  • @CamiloTerevinto, lol, i didn't see that. I just saw Console.WriteLine and then glossed over the rest of that line. Oh my, i am stupid ;-) (Better delete my stupid comments now...) –  Oct 27 '18 at 21:57
  • @elgonzo Happens to all of us :) – Camilo Terevinto Oct 27 '18 at 21:58

2 Answers2

2

The following will do the job if the application is the one that attached to the console.

For a complete answer how to get the handle in case that your application is not the one that attached to the console, see https://stackoverflow.com/a/28616832/2370138.

class Program
{
    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hWnd, 
                                    IntPtr hWndInsertAfter, 
                                    int X, 
                                    int Y, 
                                    int cx, 
                                    int cy, 
                                    uint uFlags);
    static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
    const uint SWP_NOSIZE = 0x0001, SWP_NOMOVE = 0x0002, SWP_SHOWWINDOW = 0x0040;

    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();

    static void Main()
    {
        IntPtr handle = GetConsoleWindow();
        SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
        Console.WriteLine($"Hello handle: {handle}");
        Console.ReadLine();
    }
}
Ilan
  • 624
  • 6
  • 11
  • That will make the window topmost (though you don't own the console window, so I'd be wary of doing anything not explicitly allowed to it), but not capture input, which is what the OP really wants. – Luaan Oct 28 '18 at 04:05
  • @Ilan thank you nice trick to keep the window on the front. And Luaan you are right that is the goal. in the mean time it will at least force the people to look at it..getting there – sam goto Oct 28 '18 at 19:51
0

SetForegroundWindow has been limited since then (see Remarks in https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setforegroundwindow). It will not allow you to arbitrarily put windows in the foreground anymore, exactly to prevent you from doing what you're trying to do.

If you need other applications running on the system, you're out of luck. You'll just need to tell your users they need to have the window focused when scanning a barcode.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • then could I make another console program to monitor for this one and keep bringing it to the front? would that even be possible? – sam goto Oct 28 '18 at 19:55
  • @samgoto No that's the same problem - you can only put windows in the foreground if you're already in the foreground (with a few exceptions, see the documentation). It all goes back to the basic concept - the user owns the computer, the applications don't. Keeping one application always in the foreground takes that ownership from the user. Imagine if it were possible to do this - the first malware that hit your computer would gain full control forever. You would keep being interrupted by "important" applications stealing focus. Well, no need imagine - try Windows 2k/XP :) – Luaan Oct 29 '18 at 07:26