Перестань быть самым верхним окном
Мое окно должно быть поверх определенного "целевого" окна, которое я не могу контролировать.
Когда целевое окно активировано, я звоню SetWindowPos
с HWND_TOPMOST
поместить мое окно поверх него, в то время как цель все еще может быть активным окном.
Когда целевое окно больше не является окном переднего плана, я хочу, чтобы мое окно по-прежнему находилось сверху целевого окна, но больше не было верхним, чтобы другие окна не закрывались им.
У меня было две идеи:
Вызов
SetWindowPos
сhWndInsertAfter
быть только что активированным окном. Это терпит неудачу, когда только что активированное окно является самым верхним, потому что мое окно не теряет статус самого верхнего. Другая проблема с этим: если только что активированное окно - рабочий стол, то мое окно помещено ниже целевого окна.Вызов
SetWindowPos
сHWND_NOTOPMOST
потерять высший статус. Однако это приводит мое окно к вершине всех не верхних окон, поэтому оно охватывает только что активированное окно. Чтобы это исправить, я должен снова поднять только что активированное окно с другимSetWindowPos
сHWND_TOP
, Это похоже на неправильный способ сделать это и может вызвать мерцание.
Возможно ли, чтобы окно просто перестало быть самым верхним и помещало его ниже текущего переднего окна?
1 ответ
Единственный автоматический метод создания окна поверх другого, вне зависимости от того, является ли целевое окно самым верхним или нет, это отношение владелец / владелец. Вы можете попробовать использовать SetParent
чтобы создать эти отношения, но обратите внимание, что Рэймонд Чен говорит, что это не рекомендуется.
Предполагая, что вы как-то отслеживаете активацию окна, я думаю, что ваш 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, ...);
}