Question

If in Delphi 2010 or XE Application.MainFormOnTaskbar is set to true then all secondary forms are always in front of the main window. It does not matter what the Popupmode or PopupParent properties are set to. However I have secondary windows that I want to be able to show behind the the main form.

If I set MainFormOnTaskbar to false it works, but then the Windows 7 features are broken (Alt-tab, Windows bar icon, etc).

How can I keep the Windows 7 features working while still allowing secondary forms to hide behind the main form?

Was it helpful?

Solution

Basically you can't. The whole point of MainFormOnTaskBar is to have Vista compatibility. If you don't set it, compatibility is gone.., if you set it, z-order is done. The following excerpt is from D2007's readme:

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.


But see this QC report, which describes the exact same problem (and closed as AsDesigned). The report states a workaround involving overriding CreateParams of a form to set the WndParent to '0'. It also describes a few problems which this workaround causes and a possible workaround for those problems too. Beware, it wouldn't be easy/possible to find and workaround all complications. See Steve Trefethen's article to have a feeling of what could be involved.

OTHER TIPS

I would have thought that one approach would be to have a "behind-the-scenes" main form which serves only the following purposes:

  1. To select and show one of the other forms as the main form and then perpetually hide itself (Visible:=FALSE) like the good old-fashioned "flash" screens.

  2. To act as an application terminator when the form it selected as the main form is closed (just wire the appropriate OnClose events).

  3. To open other forms on behalf of the designated pseudo-main-form such that the hidden real main form is the "owner" of the other forms, not the "pseudo-main-form". It appears that this will happen anyway if all your other forms have a 'non' pop-up style and are visible via Show calls rather than ShowModal.

This small restructuring of the application's behavior may then get you the kind user interaction that you are looking for.

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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top