我正在开发一个应用程序,它恰好是我正在开发的安装程序的引导程序.该应用程序进行一些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调用开始时打开的进度窗口导致主窗口搞砸了,但我无法阻止该窗口出现.此外,隐藏它是没有意义的,因为它让用户知道在主窗口到达之前发生了什么.
安德鲁不完全正确.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);
您可能需要也可能不需要运行具有管理权限的程序才能使用此程序,但我已经亲自使用了此代码并且已完成工作.
你无法窃取焦点.期.
看到这篇Old New Thing文章:
https://blogs.msdn.microsoft.com/oldnewthing/20090220-00/?p=19083