使用Win32 API更新许多Windows的Z顺序

Gre*_*les 7 windows winapi z-order

场景是我有一个顶级窗口的窗口句柄列表,我想转移它们,所以它们按我选择的z顺序排列.我开始通过迭代列表(我希望最后的窗口最后一个),调用SetForegroundWindow每个.这似乎在某些时候有效,但并非总是如此,当我在每次通话之间稍微暂停时,有所改善.

有一个更好的方法吗?


编辑:

它看起来像BeginDeferWindowPos/ DeferWindowPos/ EndDeferWindowPosroute是要走的路.但是,我似乎无法让它一次使用多个窗口.当我将窗口列表限制为单个窗口时,它可以正常工作.当列表有多个窗口时,它似乎只能获得其中一个窗口.这是我正在做的伪代码:

HWND[] windows;
HWND lastWindowHandle = 0;
HDWP positionStructure = BeginDeferWindowPos(windows.length);

for (int i = 0; i < windows.length; i++)
{
    positionStructure = DeferWindowPos(positionStructure, windows[i], 
        lastWindowHandle, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}

EndDeferWindowPos(positionStructure);
Run Code Online (Sandbox Code Playgroud)

我确定这是一个小/明显我在这里失踪的东西,但我只是没有看到它.

And*_*ers 11

有一组特殊的api用于设置多个窗口的窗口位置:BeginDeferWindowPos + DeferWindowPos + EndDeferWindowPos(循环中的SetWindowPos当然也可以工作,但它可能有更多的闪烁)


In *_*ico 5

您可以使用SetWindowPos订购顶级窗口.

// Hypothetical function to get an array of handles to top-level windows
// sorted with the window that's supposed to be topmost at the end of array.
HWND* windows = GetTopLevelWindowsInOrder();
int numWindows = GetTopLevelWindowCount();

for(int i = 0; i < numWindows; ++i)
{
    ::SetWindowPos(windows[i], HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
Run Code Online (Sandbox Code Playgroud)

  • `SetForegoundWindow`不只是改变Z顺序.它"激活"了窗口,这会对焦点等事情产生影响,这需要消息在系统中飞行,这可能是时机似乎至关重要的原因.使用`SetWindowPos`作为In Silico建议,至少对于前n-1个窗口.根据您要实现的目标,您可能希望在最终窗口中执行`SetWindowPos`. (2认同)