Question

J'ai essayé d'obtenir des formulaires modaux dans mon application apparaissent sur la barre des tâches -. En profitant de la nouvelle barre des tâches utiles dans Windows 7

Il y a de nombreux problèmes avec la VCL qui doivent être défaits avant une forme peut exister sur la barre des tâches.

Mais la dernière question est que minimiser la forme que le VCL a désigné le principal forme fait disparaître toutes les fenêtres de l'application.

Il y a dix ans, Peter Below (TeamB) a documenté ces problèmes , et les tentatives de travailler autour d'eux. Mais il y a des problèmes qui ne peuvent être résolus. Les questions sont si profondes au sein de la VCL lui-même, qu'il est effectivement impossible de faire des applications Delphi se comportent correctement.

Tout découle du fait que le bouton que vous voyez sur la barre d'outils ne représente pas la fenêtre de l'application; elle représente la fenêtre TApplications, qui est caché et jamais vu. Et puis il y a le MainForm de l'application, qui est ensuite imprégnée avec des capacités spéciales où si il est minimisés alors il demande à l'application de se cacher.

Il me semble que si je peux faire

Application.MainForm := nil;

alors tous ces bugs disparaîtrait. L'application peut avoir sa fenêtre cachée, et en attendant, je vais passer outre tous les autre forme dans l'application, y compris ma forme principale, avec :

procedure TForm2.CreateParams(var params: TCreateParams ); 
begin 
   inherited CreateParams(params); 
   params.ExStyle := params.ExStyle or WS_EX_APPWINDOW; 
end; 

Mais dans Delphi la propriété Application.MainForm est en lecture seule.

Comment puis-je pas avoir un MainForm à Delphes?

Voir aussi

Était-ce utile?

La solution

Vous ne pouvez pas lancer un projet GUI sans MainForm attribué. La boucle principale du message quittera immédiatement sans. Cependant, cela ne signifie pas que le MainForm doit exécuter votre interface utilisateur. Vous pouvez utiliser un vide caché TForm comme attribué MainForm, puis l'avoir instancier votre MainForm réel comme TForm secondaire. Par exemple:

HiddenMainFormApp.dpr:

project HiddenMainFormApp;

uses
  ..., Forms, HiddenMainForm;

begin
  Application.Initialize;
  Application.CreateForm(THiddenMainForm, MainForm);
  Application.ShowMainForm := False;
  Application.Run;
end.

HiddenMainForm.cpp:

uses
  ..., RealMainForm;

procedure THiddenMainForm.FormCreate(Sender: TObject);
begin
  RealMainForm := TRealMainForm.Create(Self);
  RealMainForm.Show;
end;

RealMainForm.cpp:

procedure TRealMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  Application.Terminate;
end;

Vous pouvez également:

HiddenMainFormApp.dpr:

project HiddenMainFormApp;

uses
  ..., Forms, HiddenMainForm, RealMainForm;

begin
  Application.Initialize;
  Application.CreateForm(THiddenMainForm, MainForm);
  Application.ShowMainForm := False;

  RealMainForm := TRealMainForm.Create(Application);
  RealMainForm.Show;
  RealMainForm.Update;

  Application.Run;
end.

RealMainForm.cpp:

procedure TRealMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  Application.Terminate;
end;

Autres conseils

Vous ne pouvez pas, en particulier dans Delphi 5.

Votre citation concernant la fenêtre TApplication étant celui vu sur la barre des tâches n'a pas été le cas pour plusieurs versions Delphi maintenant (je crois D2007 a changé).

Parce que vous utilisez Delphi 5, vous utilisez une copie obsolète de Delphi; les versions actuelles ont presque aucune des choses que vous écrivez plus. Je vous suggère de mettre à niveau vers une version ultérieure de Delphi (D5 est extrêmement ancienne); Delphi 2007 si vous avez besoin pour éviter Unicode, Delphi XE si vous pouvez utiliser (ou ne me dérange pas d'avoir) le support Unicode dans la VCL et RTL.

Les choses que vous décrivez ne sont pas bogues , BTW. Ils étaient des décisions de conception intentionnelles effectuées au moment Delphi 1 était conçu, et par Delphi 7 a bien fonctionné avec les versions de Windows qui étaient disponibles. Les changements dans les versions ultérieures de Windows (XP / Vista / Windows 7 et les versions équivalentes Server) fait des changements dans l'architecture nécessaire, et ils ont été faits comme Delphi a progressé en même temps que Windows. Parce que vous avez choisi de ne pas progresser avec votre version de Delphi pour le garder plus récente ne fait pas les choses que vous écrivez deviennent comme par magie bugs. : -)

Avoir Application.MainForm attribué ne semble pas être un problème pour montrer une autre forme de modeless la barre des tâches, tout en minimisant le MainForm.

Project1.dpr:

program Project1;

uses
  Forms,
  Windows,
  Unit1 in 'Unit1.pas' {MainForm},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

var
  MainForm: TMainForm;

begin
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  ShowWindow(Application.Handle, SW_HIDE);
  Application.Run;
end.

Unit1.pas:

unit Unit1;

interface

uses
  Windows, Messages, Classes, Controls, Forms, StdCtrls, Unit2;

type
  TMainForm = class(TForm)
    ShowForm2Button: TButton;
    ShowForm2ModalButton: TButton;
    procedure ShowForm2ButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ShowForm2ModalButtonClick(Sender: TObject);
  private
    FForm2: TForm2;
    procedure ApplicationActivate(Sender: TObject);
    procedure Form2Close(Sender: TObject; var Action: TCloseAction);
    procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

implementation

{$R *.dfm}

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Visible := True; //Required only for MainForm, can be set designtime
  Application.OnActivate := ApplicationActivate;
end;

procedure TMainForm.ApplicationActivate(Sender: TObject);
{ Necessary in case of any modal windows dialog or modal Form active }
var
  TopWindow: HWND;
  I: Integer;
begin
  TopWindow := 0;
  for I := 0 to Screen.FormCount - 1 do
  begin
    Screen.Forms[I].BringToFront;
    if fsModal in Screen.Forms[I].FormState then
      TopWindow := Screen.Forms[I].Handle;
  end;
  Application.RestoreTopMosts;
  if TopWindow = 0 then
    Application.BringToFront
  else
    SetForegroundWindow(TopWindow);
end;

procedure TMainForm.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
  begin
    ExStyle := ExStyle or WS_EX_APPWINDOW;
    WndParent := GetDesktopWindow;
  end;
end;

procedure TMainForm.WMSysCommand(var Msg: TWMSysCommand);
begin
  if Msg.CmdType = SC_MINIMIZE then
    ShowWindow(Handle, SW_MINIMIZE)
  else
    inherited;
end;

{ Testing code from here }

procedure TMainForm.ShowForm2ButtonClick(Sender: TObject);
begin
  if FForm2 = nil then
  begin
    FForm2 := TForm2.Create(Application); //Or: AOwner = nil, or Self
    FForm2.OnClose := Form2Close;
  end;
  ShowWindow(FForm2.Handle, SW_RESTORE);
  FForm2.BringToFront;
end;

procedure TMainForm.Form2Close(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  FForm2 := nil;
end;

procedure TMainForm.ShowForm2ModalButtonClick(Sender: TObject);
begin
  with TForm2.Create(nil) do
    try
      ShowModal;
    finally
      Free;
    end;
end;

end.

Unit2.pas:

unit Unit2;

interface

uses
  Windows, Messages, Classes, Controls, Forms;

type
  TForm2 = class(TForm)
  private
    procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

implementation

{$R *.dfm}

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
  begin
    ExStyle := ExStyle or WS_EX_APPWINDOW;
    WndParent := GetDesktopWindow;
  end;
end;

procedure TForm2.WMSysCommand(var Msg: TWMSysCommand);
begin
  if Msg.CmdType = SC_MINIMIZE then
    ShowWindow(Handle, SW_MINIMIZE)
  else
    inherited;
end;

end.

(Testé avec D5 et D7 sur XP et Win7.)

(Et oui, vous pouvez marquer ceci comme étant pas une réponse, parce que ce n'est pas. Il y a encore MainForm Mais je ne me plais à penser cela répond à la question derrière la question ...)

Je ne peux pas parler pour Delphi 5, mais en Delphi 7, vous pouvez certainement courir sans mainform si vous êtes prêt à obtenir votre sale mains. Je couvert beaucoup de détails dans une autre réponse .

Depuis Delphi 5 n'a pas la propriété MainFormOnTaskBar, vous devez faire ce qui suit dans votre DPR:

// Hide application's taskbar entry
WasVisible := IsWindowVisible(Application.Handle);
if WasVisible then
  ShowWindow(Application.Handle, SW_HIDE);
SetWindowLong(Application.Handle, GWL_EXSTYLE,
  GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
if WasVisible then
  ShowWindow(Application.Handle, SW_SHOW);
// Hide the hidden app window window from the Task Manager's
// "Applications" tab.  Don't change Application.Title since
// it might get read elsewhere.
SetWindowText(Application.Handle, '');

Ce cachera la fenêtre d'application, et aussi longtemps que vous redéfinissez votre formulaire de CreateParams pour définir Params.WndParent := 0 chacun d'entre eux auront une entrée barre des tâches de leur propre. Application.MainForm n'est pas affecté, donc les choses comme le minimiser override ne sont pas un problème, mais vous ne devez faire attention à tout code qui suppose MainForm est valide.

Vous pouvez mettre vos formulaires modaux dans une dll, ils agissent à peu près sur eux-mêmes. (Si vous n'utilisez pas l'instance d'application de la dll tout en créant (Application.CreateForm) alors Application.Mainform est nul dans le dll).

Bien sûr, cela pourrait ne pas être possible en fonction de ce que les formulaires pourraient avoir besoin de faire.

En fait, la plupart de ce que vous plaignez est sur le point, en fait, la conception de Windows plutôt que la VCL. Voir fonctionnalités Windows pour tous les détails .

Le nœud de la question est la propriété du propriétaire, et je veux dire le propriétaire de fenêtres plutôt que le propriétaire de VCL.

  

Une fenêtre propriété est masquée lorsque   son propriétaire est réduite au minimum.

Si vous souhaitez être en mesure de minimiser la principale forme sans autres fenêtres étant caché, vous devez obtenir sur la façon dont fonctionnent les fenêtres appartenant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top