Сделать 2 формы способными перекрывать друг друга?
Я хотел бы иметь отдельную форму, которая показывает "вместе" с моей основной формой, чтобы она не перекрывала основную форму.
Вот пример:
Заметьте, как основная программа перекрывает логи? Я не могу понять, как это сделать в Delphi.
Спасибо!
2 ответа
Ответы на этот вопрос лежат в очень полезной теме MSDN Window Features.
Соответствующая информация:
Перекрывающееся или всплывающее окно может принадлежать другому перекрывающемуся или всплывающему окну. Принадлежность накладывает несколько ограничений на окно.
- Собственное окно всегда находится над своим владельцем в z-порядке.
- Система автоматически уничтожает собственное окно, когда его владелец уничтожается.
- Собственное окно скрыто, когда его владелец свернут.
Основной формой в вашем приложении является владелец (в терминологии Windows, а не в Delphi) других всплывающих окон. Первый пункт выше означает, что собственные окна всегда отображаются над основной формой (владелец).
Попробуйте создать приложение с 3 формами и покажите их все..Dpr будет выглядеть так:
program OwnedWindows;
uses
Forms,
Main in 'Main.pas' {MainForm},
Popup1 in 'Popup1.pas' {PopupForm1},
Popup2 in 'Popup2.pas' {PopupForm2};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TMainForm, Main);
Application.CreateForm(TPopupForm1, PopupForm1);
Application.CreateForm(TPopupForm2, PopupForm2);
PopupForm1.Show;
PopupForm2.Show;
Application.Run;
end.
Вы увидите, что основная форма всегда находится под двумя другими формами, но эти другие формы могут находиться выше или ниже друг друга. Когда вы минимизируете основную форму, все они исчезают.
Вы можете, если хотите, сделать все ваши формы на верхнем уровне неиспользуемыми окнами:
procedure TPopupForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := 0;
end;
И, как мудрый для TPopupForm2 в моем примере. Это привело бы ко всем 3 окнам, имеющим кнопки панели задач.
Еще один подход заключается в том, чтобы вернуться к тому, что было до Vista, и сделать скрытое окно приложения окном владельца верхнего уровня. Это можно сделать, убедившись, что Application.MainFormOnTaskbar имеет значение False. Пропустите весь код CreateParams, и теперь у вас будет одно окно на панели задач, и любое из ваших окон может быть выше любого другого, потому что окно владельца верхнего уровня - это скрытое окно Application.Handle. Конечно, недостатком является то, что вы потеряете свой Aero Peek.
Итак, я думаю, что вам нужно сделать, чтобы основная форма появилась на панели задач как обычно, но убедитесь, что другие формы не принадлежат (в смысле Windows) основной форме. Но они должны принадлежать, чтобы избежать их на панели задач. Таким образом, вы можете сделать скрытое окно приложения владельцем, используя метод CreateParams, например так:
procedure TOverlappedPopupForm.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := Application.Handle;
end;
Хотя в комментариях вы утверждаете иначе, когда я делаю это, я обнаруживаю, что всплывающая форма действительно скрыта, когда я минимизирую основную форму. И это снова показано, когда основная форма восстановлена. Таким образом, я думаю, что это полностью решит вашу проблему.
У меня сейчас нет открытого Delphi, но я бы
mainform.formstyle := fsStayOnTop
и показать дочернюю форму с
childform.show;
Работа?
или попробуйте использовать SetWindowPos() и установить для свойства hWndInsertAfter что-то вроде HWND_TOPMOST в главной форме