停止成为最重要的 window
Stop being topmost window
我的 window 应该在我无法控制的特定 "target" window 之上。
当目标 window 被激活时,我用 HWND_TOPMOST
调用 SetWindowPos
将我的 window 放在它上面,同时目标仍然是活动的 window.
当目标window不再是前景window时,我希望我的window仍然在目标window之上,但不再是最顶层, 所以其他 windows 不在其中。
我有两个想法:
用hWndInsertAfter
调用SetWindowPos
成为刚刚激活的window。当刚刚激活的 window 是最顶层时,这会失败,因为我的 window 不会失去最顶层的状态。另一个问题:如果刚刚激活的 window 是桌面,那么我的 window 放在目标 window.
下面
用HWND_NOTOPMOST
调用SetWindowPos
失去最顶层状态。但是,这会将我的 window 带到所有非最顶层 windows 的顶部,因此它覆盖了刚刚激活的 window。要解决此问题,我必须将刚刚激活的 window 与另一个 SetWindowPos
和 HWND_TOP
一起放在最上面。感觉这个方法不对,可能会导致闪烁。
是否可以让 window 不再位于最顶部并将其置于当前前景 window 下方?
无论目标 window 是否在最顶层,使一个 window 永久位于另一个之上的唯一自动方法是 owner/owned 关系。您可以 尝试 使用 SetParent
来创建此关系,但请注意 Raymond Chen does say it's not recommended.
假设您正在以某种方式跟踪 window 激活,我认为您的 SetWindowPos
想法(第一个)是实现它的方法,并进行以下修改:
- 当目标 window 处于活动状态时,将您的 window 设置为
HWND_TOPMOST
- 当目标失去激活时,在 目标 window 的直接前任之后插入你的 window 在 z 顺序中(即实际上仍然在目标顶部 window,但不是最顶部)
像这样的伪代码:
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, ...);
}
我的 window 应该在我无法控制的特定 "target" window 之上。
当目标 window 被激活时,我用 HWND_TOPMOST
调用 SetWindowPos
将我的 window 放在它上面,同时目标仍然是活动的 window.
当目标window不再是前景window时,我希望我的window仍然在目标window之上,但不再是最顶层, 所以其他 windows 不在其中。
我有两个想法:
用
hWndInsertAfter
调用SetWindowPos
成为刚刚激活的window。当刚刚激活的 window 是最顶层时,这会失败,因为我的 window 不会失去最顶层的状态。另一个问题:如果刚刚激活的 window 是桌面,那么我的 window 放在目标 window. 下面
用
HWND_NOTOPMOST
调用SetWindowPos
失去最顶层状态。但是,这会将我的 window 带到所有非最顶层 windows 的顶部,因此它覆盖了刚刚激活的 window。要解决此问题,我必须将刚刚激活的 window 与另一个SetWindowPos
和HWND_TOP
一起放在最上面。感觉这个方法不对,可能会导致闪烁。
是否可以让 window 不再位于最顶部并将其置于当前前景 window 下方?
无论目标 window 是否在最顶层,使一个 window 永久位于另一个之上的唯一自动方法是 owner/owned 关系。您可以 尝试 使用 SetParent
来创建此关系,但请注意 Raymond Chen does say it's not recommended.
假设您正在以某种方式跟踪 window 激活,我认为您的 SetWindowPos
想法(第一个)是实现它的方法,并进行以下修改:
- 当目标 window 处于活动状态时,将您的 window 设置为
HWND_TOPMOST
- 当目标失去激活时,在 目标 window 的直接前任之后插入你的 window 在 z 顺序中(即实际上仍然在目标顶部 window,但不是最顶部)
像这样的伪代码:
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, ...);
}