我正在开发一个应用程序,它恰好是我正在处理的安装程序的引导程序。该应用程序进行一些MSI调用,以获取将我的应用程序主窗口向导组合在一起所需的信息,这会导致在收集信息时打开进度窗口,然后在完成后立即离开。然后设置并启动向导。我的问题是,向导(从CPropertySheet派生)不想在没有我添加一些调用的情况下成为活动应用程序。
我已经解决了在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
我的问题是我还没有弄清楚如何使窗口自动激活(即,使自己成为具有焦点的窗口)。 SetFocus()在此上下文中不起作用。我需要一些东西来强制窗口到Z顺序的顶部并激活它,最好是尽可能少的调用。
我的猜测是,MSI调用开始时打开的进度窗口导致主窗口搞砸了,但我无法阻止该窗口出现。此外,隐藏它是没有意义的,因为它可以让用户知道在主窗口到达之前发生了什么。
答案 0 :(得分:9)
安德鲁并不完全正确。 Windows确实很难阻止你窃取焦点,但可以使用下面的方法。
并且代码将是这样的:
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);
您可能需要也可能不需要运行具有管理权限的程序才能使用此程序,但我已经亲自使用了此代码并完成了工作。
答案 1 :(得分:8)
答案 2 :(得分:0)
不是ShowWindow(youwindow,SW_SHOWNORMAL)有效吗? -don
答案 3 :(得分:0)
您会发现BringWindowToTop或SetForegroundWindow在将窗口实际强制到所有其他窗口(应用程序)的前面之前必须满足这些要求。如果不满足这些要求,Windows将仅在任务栏中刷新应用程序的图标。 This文章提供了解决方法,但正如1800信息所指出的那样,不建议这样做。我想你只需要接受它。
答案 4 :(得分:0)
应用“窃取”焦点是有充分理由的。我的应用程序是加载许多驱动程序 DLL 的服务器。另一个连接到服务器的应用程序有一个按钮,它向服务器发送消息以显示其中一个 DLL(由服务器拥有,而不是客户端应用程序拥有)中的详细信息,以方便使用。不幸的是,这个弹出的窗口通常隐藏在多个窗口之下。