简体   繁体   中英

How can I bring a window to the foreground in Vista using C++?

I have a piece of code that brings the window under the cursor to the foreground using the SetForegroundWindow API for WinXP. I have been testing it for Vista but the API seems to no longer do the job correctly.

AllowSetForeground did not help, my process is a background process.

What can I use to accomplish this?

Try the following code and see if it works for you:

SetWindowPos(WndHandle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
SetWindowPos(WndHandle,HWND_NOTOPMOST,0,0,0,0,SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);

Just a warning: there was a public API to do that (SetForegroundWindow), now it does not bring the window in the foreground anymore.

Now the window just flashes.

But this was for a reason. Applications doing that "steal" the focus from the current window (often without a good reason) and can lead to all kind of problems.

So before trying to circumvent the protections put by the OS against this kind of behavior, make sure you will not annoy your users. Ask yourself: "do I really-really have to jump in my user's face, even if my application is in the background?"

If using MFC, this worked for me in Windows 7 x64:

    RECT rc;
    m_pMainWnd->GetWindowRect(&rc);

    int nBoxWidth = rc.left-rc.right;
    int nBoxHeight = rc.bottom-rc.top;
    int nBoxTop = rc.top;
    int nBoxLeft = rc.left;

    SetWindowPos(m_pMainWnd->GetSafeHwnd(), HWND_TOPMOST,
                    nBoxLeft, nBoxTop, nBoxWidth, nBoxHeight,
                    SWP_NOMOVE || SWP_NOSIZE);
    SetWindowPos(m_pMainWnd->GetSafeHwnd(), HWND_NOTOPMOST,
                    nBoxLeft, nBoxTop, nBoxWidth, nBoxHeight,
                    SWP_SHOWWINDOW || SWP_NOMOVE || SWP_NOSIZE);

If SetForegroundWindow() fails, have you tried setting the window WS_EX_TOPMOST and then immediately non top most right after calling SetForegroundWindow() ?

It might have something to do with people rightfully complaining about applications poping all over the place when you least expect it.

Setting the current thread asleep did it for me, together with setting it to non-topmost before:

OS.SetWindowPos(handle, OS.HWND_NOTOPMOST, 0, 0, 0, 0, OS.SWP_NOMOVE | OS.SWP_NOSIZE);
try {
    Thread.sleep(100);
} catch (InterruptedException e) {
    LOG.error("sleeping thread was interrupted", e);
}
OS.SetWindowPos(handle, OS.HWND_TOPMOST, 0, 0, 0, 0, OS.SWP_NOMOVE | OS.SWP_NOSIZE);
VOID SwitchToThisWindow(HWND hWnd, BOOL fAltTab);

适用于XP到Windows 7 http://msdn.microsoft.com/en-us/library/ms633553.aspx

use windows powertoys tweakui program to change the state of permission for focus.

select "general" then "focus" and then de-check the box allowing other programs to take focus.

This works when everyones suggestions seem not to work, (they actually all do).

microsoft in thier infinate wisdom decided that the response from calls to setforegrondwindow etc etc will now be null.

they didn't bother to say tjat you can still get back to original by tweakui!!!!

enjoy.....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM