Как разрешить Delphi вторичные формы за основной формой

Если в Delphi 2010 или XE Application.MainFormOnTaskbar установлено значение true, то все вторичные формы всегда находятся перед главным окном. Неважно, какие свойства Popupmode или PopupParent установлены. Однако у меня есть вторичные окна, которые я хочу показать за основной формой.

Если я установил MainFormOnTaskbar в false, он будет работать, но функции Windows 7 будут повреждены (Alt-tab, значок панели Windows и т. Д.).

Как сохранить работоспособность функций Windows 7, при этом позволяя вторичным формам скрываться за основной формой?

2 ответа

Решение

По сути, вы не можете. Весь смысл MainFormOnTaskBar это иметь совместимость с Vista. Если вы не установите его, совместимость исчезнет, ​​если вы установите его, z-порядок будет выполнен. Следующая выдержка из readme D2007:

The property controls how Window's TaskBar buttons are handled by VCL. This property can be applied to older applications, but it affects the Z-order of your MainForm, so you should ensure that you have no dependencies on the old behavior.


Но посмотрите этот отчет о контроле качества, который описывает точно такую ​​же проблему (и закрыт как AsDesigned). В отчете говорится об обходном пути, связанном с переопределением CreateParams формы для установки WndParent до "0". Также описаны некоторые проблемы, которые вызывает этот обходной путь, и возможный обход этих проблем. Осторожно, было бы непросто / невозможно найти и обойти все осложнения. Посмотрите статью Стива Трефетена, чтобы понять, что может быть в этом замешано.

Я бы подумал, что одним из подходов будет иметь "закулисную" основную форму, которая служит только следующим целям:

  1. Чтобы выбрать и показать одну из других форм в качестве основной, а затем постоянно скрывать себя (Visible:=FALSE), как старые добрые "флеш" экраны.

  2. Чтобы действовать как терминатор приложения, когда форма, выбранная в качестве основной формы, закрыта (просто подключите соответствующие события OnClose).

  3. Открывать другие формы от имени назначенной псевдо-главной формы так, чтобы скрытая реальная главная форма была "владельцем" других форм, а не "псевдо-главной формой". Похоже, что это произойдет в любом случае, если все ваши другие формы имеют всплывающий стиль "не" и будут видимы через вызовы Show, а не ShowModal.

Эта небольшая перестройка поведения приложения может затем дать вам доброе взаимодействие с пользователем, которое вы ищете.

unit FlashForm;
interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;

type
  TFlash = class(TForm)
    lblTitle: TLabel;
    lblCopyright: TLabel;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  public
    procedure CloseApp;
  end;

var
  Flash: TFlash;

implementation

{$R *.dfm}

uses Main;

procedure TFlash.CloseApp;  // Call this from the Main.Form1.OnClose or CanClose (OnFormCloseQuery) event handlers
begin
   close
end;

procedure TFlash.FormCreate(Sender: TObject);  // You can get rid of the standard border icons if you want to
begin
   lblCopyright.Caption := 'Copyright (c) 2016  AT Software Engineering Ltd';
   Refresh;
   Show;
   BringToFront;
end;


procedure TFlash.Timer1Timer(Sender: TObject);
begin
   Application.MainFormOnTaskBar := FALSE;  // This keeps the taskbar icon alive
   if assigned(Main.MainForm) then
   begin
       visible := FALSE;
       Main.MainForm.Show;
       Timer1.Enabled := FALSE;
   end else Timer1.Interval := 10;  // The initial time is longer than this (flash showing time)
end;

end.

// Finally, make this the FIRST form created by the application in the project file.

Я нашел способ решить эту проблему.

на *.dpr

изменение Application.MainFormOnTaskbar := true;к Application.MainFormOnTaskbar := false;

это позволит вам создать дочернюю форму позади основной формы.

Другие вопросы по тегам