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调用开始时打开的进度窗口导致主窗口出错,但是我没有办法阻止这个窗口的出现。此外,隐藏它也没有意义,因为它让用户知道主窗口到达之前发生了什么。
4 个解决方案
#1
8
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.
您可能需要也可能不需要运行具有管理权限的程序才能运行它,但是我个人使用了这段代码,它已经完成了工作。
#2
7
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
#3
0
doesn't ShowWindow(youwindow,SW_SHOWNORMAL) work? -don
不显示窗口(youwindow SW_SHOWNORMAL)工作?——请
#4
0
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. This article 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信息所指出的,不建议这样做。我想你只好接受了。
#1
8
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.
您可能需要也可能不需要运行具有管理权限的程序才能运行它,但是我个人使用了这段代码,它已经完成了工作。
#2
7
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
#3
0
doesn't ShowWindow(youwindow,SW_SHOWNORMAL) work? -don
不显示窗口(youwindow SW_SHOWNORMAL)工作?——请
#4
0
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. This article 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信息所指出的,不建议这样做。我想你只好接受了。