windows 如何强制我的应用程序出现在最前面并获得焦点?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/688337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I force my app to come to the front and take focus?
提问by RobH
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.
我正在开发一个应用程序,它恰好是我也在开发的安装程序的引导程序。该应用程序进行了几次 MSI 调用,以获取我将作为我的应用程序主窗口的向导组合在一起所需的信息,这会导致在收集信息时打开一个进度窗口,然后在完成后消失。然后设置并启动向导。我的问题是向导(源自 CPropertySheet)不想在没有我添加一些调用的情况下走到前面并成为活动应用程序。
I've solved the problem of bringing it to the front with the following code in my OnInitDialog() method:
我在 OnInitDialog() 方法中使用以下代码解决了将其置于最前面的问题:
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.
我的问题是我还没有弄清楚如何使窗口自激活(即,使自己成为具有焦点的窗口)。SetFocus() 在这种情况下不起作用。我需要一些东西来强制窗口到 Z 顺序的顶部并激活它,最好是在尽可能少的调用中。
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.
我的猜测是 MSI 调用开始时打开的进度窗口导致主窗口搞砸了,但我无法阻止该窗口出现。此外,隐藏它也没有意义,因为它让用户在主窗口到达之前就知道发生了什么。
回答by Caleb Bartholomew
Andrew isn't completely correct. Windows does try really hard to stop you from stealing focus, but it is possible using the folowing method.
安德鲁并不完全正确。Windows 确实非常努力地阻止您窃取焦点,但使用以下方法是可能的。
- Attach to the thread of the window that currently has focus.
- Bring your window into focus.
- 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.
您可能需要也可能不需要以管理权限运行您的程序才能使其工作,但我已经亲自使用了此代码并且它已经完成了工作。
回答by nobody
You can't steal focus. Period.
你不能偷走焦点。时期。
See this Old New Thing article:
请参阅这篇旧的新事物文章:
https://blogs.msdn.microsoft.com/oldnewthing/20090220-00/?p=19083
https://blogs.msdn.microsoft.com/oldnewthing/20090220-00/?p=19083
回答by Don Dickinson
doesn't ShowWindow(youwindow,SW_SHOWNORMAL) work? -don
ShowWindow(youwindow,SW_SHOWNORMAL) 不起作用吗?-大学教师
回答by Arnold Spence
You will find that BringWindowToTop or SetForegroundWindow have requirements that must be met before the window will actually be forced to the front over all other windows (applications). If these aren't met, Windows will only flash the application's icon in the taskbar. Thisarticle presents a way around that but as 1800 INFORMATION points out, it is not recommended. I guess you'll just have to accept it.
您会发现,BringWindowToTop 或 SetForegroundWindow 必须满足这些要求,才能实际将窗口强制置于所有其他窗口(应用程序)的前面。如果不满足这些要求,Windows 只会在任务栏中闪烁应用程序的图标。该文章呈现一根绕的方式,但在1800个信息点出来,所以不推荐。我想你只能接受它。