windows - 不再是最顶层的窗口

标签 windows winapi window topmost

我的窗口应该位于我无法控制的特定“目标”窗口之上。

当目标窗口被激活时,我调用 SetWindowPosHWND_TOPMOST 将我的窗口放在它上面,同时目标仍然是事件窗口。

当目标窗口不再是前景窗口时,我希望我的窗口仍然在目标窗口的顶部,但不再是最顶层,这样其他窗口就不会被它覆盖。

我有两个想法:

  • hWndInsertAfter调用SetWindowPos作为刚刚激活的窗口。当刚刚激活的窗口位于最顶层时,这会失败,因为我的窗口不会失去最顶层的状态。另一个问题是:如果刚刚激活的窗口是桌面,那么我的窗口就会放在目标窗口的下方。

  • 使用HWND_NOTOPMOST 调用SetWindowPos 以失去最顶层状态。但是,这会将我的窗口带到所有非最顶层窗口的顶部,因此它覆盖了刚刚激活的窗口。要解决此问题,我必须使用另一个带有 HWND_TOPSetWindowPos 再次将刚刚激活的窗口置于顶部。这感觉像是错误的做法,可能会导致闪烁。

是否可以让一个窗口不再位于最顶层并将其置于当前前景窗口下方?

最佳答案

无论目标窗口是否在最顶层,使一个窗口永久位于另一个窗口之上的唯一自动方法是所有者/拥有关系。您可以尝试使用SetParent 来创建此关系,但请注意Raymond Chen does say it's not recommended .

假设您正在以某种方式跟踪窗口激活,我认为您的 SetWindowPos 想法(第一个)是实现它的方法,并进行以下修改:

  • 当目标窗口处于事件状态时,将您的窗口设置为 HWND_TOPMOST
  • 当目标失去激活时,将您的窗口插入到 目标 窗口在 z 顺序中的直接前任窗口之后(即有效地仍在目标窗口的顶部,但不是最顶部)

像这样的伪代码:

if (foregroundwindow == targetwindow)
   SetWindowPos(my_window, HWND_TOPMOST, ...);
else
{
    HWND hwndPred = GetWindow(targetwindow, GW_HWNDPREV);
    if (!hwndPred)
    {
        // no predecessor so my_window will still be on top, just not top-most any more
        if (GetWindowLong(targetwindow, GWL_EXSTYLE) & WS_EX_TOPMOST)
            hwndPred = HWND_NOTOPMOST;
    }
    SetWindowPos(my_window, hwndPred, ...);
}

关于windows - 不再是最顶层的窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31360705/

相关文章:

c++ - ShowWindow 替代方案

c++ - 检测到子进程因操作系统内存不足而被终止

java - Windows - 在哪里找到 .bashrc 文件以增加堆大小

c++ - Windows 上的 Boost asio 套接字无法异步连接

c# - 像 Winspector Spy 一样拖放

ios - 如何创建穿过一层进入另一层的窗口

android - 如何使用墙纸获取 DrawingCache()

python - 在 Windows 上复制文件时为 "IOError [Errno 13] Permisson denied"

c++ - 提高 Windows 应用程序的性能

c++ - native API 窗口设计器