How do I force my app to come to the front and take focus?

21,886

Solution 1

Andrew isn't completely correct. Windows does try really hard to stop you from stealing focus, but it is possible using the folowing method.

  1. Attach to the thread of the window that currently has focus.
  2. Bring your window into focus.
  3. Detach from the thread.

And the code for that would go something like this:

DWORD dwCurrentThread = GetCurrentThreadId();
DWORD dwFGThread      = GetWindowThreadProcessId(GetForegroundWindow(), NULL);


AttachThreadInput(dwCurrentThread, dwFGThread, TRUE);

// Possible actions you may wan to bring the window into focus.
SetForegroundWindow(hwnd);
SetCapture(hwnd);
SetFocus(hwnd);
SetActiveWindow(hwnd);
EnableWindow(hwnd, TRUE);

AttachThreadInput(dwCurrentThread, dwFGThread, FALSE);

You may or may not need to have to run your program with administrative privileges for this to work, but I've used this code personally and it has go the job done.

Solution 2

You can't steal focus. Period.

See this Old New Thing article:

https://blogs.msdn.microsoft.com/oldnewthing/20090220-00/?p=19083

Share:
21,886
RobH
Author by

RobH

SOreadytohelp

Updated on July 09, 2022

Comments

  • RobH
    RobH almost 2 years

    I'm working on an application that happens to be the bootstrap for an installer that I'm also working on. The application makes a few MSI calls to get information that I need for putting together the wizard that is my application's main window, which causes a progress window to open while the info is being gathered and then go away once that's done. Then the wizard is set up and launched. My problem is that the wizard (derived from CPropertySheet) does not want to come to the front and be the active application without me adding in some calls to do so.

    I've solved the problem of bringing it to the front with the following code in my OnInitDialog() method:

    SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // force window to top
    SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // lose the topmost status that the previous line gave us
    

    My problem is that I still haven't figured out how to make the window self-activate (i.e., make itself be the one that has the focus). SetFocus() won't work in this context. I need something that will force the window to the top of the Z-order and activate it, preferably in as few calls as possible.

    My guess is that the progress window opened at the beginning by the MSI calls is causing the main window to screw up, but I have no way to prevent that window from appearing. Also, it wouldn't make sense to hide it, because it lets the user know what's going on before the main window arrives.

  • 1800 INFORMATION
    1800 INFORMATION about 15 years
    Don't do this. Raymond Chen explains why this often causes your app to hang: blogs.msdn.com/oldnewthing/archive/2008/08/01/8795860.aspx
  • 1800 INFORMATION
    1800 INFORMATION about 15 years
    Thank you, I was looking for this article as the answer to this question. Please everyone that reads this, internalise it and fix the virus meme that tries to steal foreground activation. But my app is special! Your app is user hostile. Don't do it!
  • Arnold Spence
    Arnold Spence about 15 years
    I agree and although in all likely hood this applies to the author, he (or somebody else) may have a good reason to need this functionality (closed system, private or home computer only). Make a recommendation on usage but don't hide the information.
  • snemarch
    snemarch about 15 years
    I hope that Microsoft will - some day - finally fix all focus-stealing once and for all. Programmers doing focus-stealing should be sent to Siberia. Naked.
  • RobH
    RobH about 15 years
    My reason for stealing focus is that the user just launched the application, it launches a window that does get focus, that window goes away, and the app launches another window, which doesn't get focus. That leaves the user scratching his head if I don't fix that.
  • RobH
    RobH about 15 years
    That article is of no use to me, because I'm not running a second instance of the same application. My application (or, rather, the MSI calls that my application is calling) is launching a window and then closing it, and my app then launches its main window. It's not taking focus, but it should.
  • RobH
    RobH about 15 years
    Haven't tried it, but I'm guessing that it's no more effective than BringWindowToTop(). (See my comment on Mitch Wheat's reply.)
  • nobody
    nobody about 15 years
    It sounds like it applies exactly to your situation. You have process A launching process B and you want process B to get focus. The solution, as the article explains, is that process A must give process B focus - process B can't take focus by itself.
  • RobH
    RobH about 15 years
    No, my program calls MSI functions that end up opening a progress window (which gets focus). The last MSI function call closes the window, and my app then opens its main window (which doesn't get focus). It's all happening in the same process.
  • NotMe
    NotMe almost 13 years
    For those that follow: RobH's situation is EXACTLY why you shouldn't steal focus. If I launch an app that starts some process you can bet that I'm typing an email while waiting for it to load. Now comes your focus stealing app that most likely is asking if it's okay to do something at the same time I'm hitting enter.. Just don't do it.
  • Robin Andersson
    Robin Andersson over 6 years
    This does not work in Windows 10 1703 (Creators update)
  • Glenn Maynard
    Glenn Maynard over 2 years
    I laughed pretty hard at this post when I thought about the number of times I've had applications steal focus. Yeah. Totally impossible, "period".