如何强制我的应用程序走到前面并关注焦点?

时间:2009-03-27 02:44:29

标签: c++ windows mfc propertysheet dialogbasedapp

我正在开发一个应用程序,它恰好是我正在处理的安装程序的引导程序。该应用程序进行一些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调用开始时打开的进度窗口导致主窗口搞砸了,但我无法阻止该窗口出现。此外,隐藏它是没有意义的,因为它可以让用户知道在主窗口到达之前发生了什么。

5 个答案:

答案 0 :(得分:9)

安德鲁并不完全正确。 Windows确实很难阻止你窃取焦点,但可以使用下面的方法。

  1. 附加到当前具有焦点的窗口的线程。
  2. 让您的窗口成为焦点。
  3. 脱离线程。
  4. 并且代码将是这样的:

    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)

你无法窃取焦点。周期。

请参阅此Old Old Thing文章:

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

答案 2 :(得分:0)

不是ShowWindow(youwindow,SW_SHOWNORMAL)有效吗? -don

答案 3 :(得分:0)

您会发现BringWindowToTop或SetForegroundWindow在将窗口实际强制到所有其他窗口(应用程序)的前面之前必须满足这些要求。如果不满足这些要求,Windows将仅在任务栏中刷新应用程序的图标。 This文章提供了解决方法,但正如1800信息所指出的那样,不建议这样做。我想你只需要接受它。

答案 4 :(得分:0)

应用“窃取”焦点是有充分理由的。我的应用程序是加载许多驱动程序 DLL 的服务器。另一个连接到服务器的应用程序有一个按钮,它向服务器发送消息以显示其中一个 DLL(由服务器拥有,而不是客户端应用程序拥有)中的详细信息,以方便使用。不幸的是,这个弹出的窗口通常隐藏在多个窗口之下。