Question

Qu'est-ce que TApplication.Handle?

  • D'où vient-il?
  • Pourquoi il existe?
  • Et surtout: pourquoi toutes les formes ont comme leur poignée de fenêtre parent
  • ?

L'aide Delphi dit:

  

TApplication.Handle

     

Permet d'accéder à la poignée de fenêtre   de la forme principale (fenêtre) de la   application.

property Handle: HWND;
     

Description

     

Utiliser la poignée lors de l'appel API Windows   les fonctions qui nécessitent une fenêtre parent   manipuler. Par exemple, une DLL   affiche son propre pop-up de haut niveau   fenêtres a besoin d'une fenêtre parent   afficher ses fenêtres dans la   application. Utilisation de la propriété Handle   rend ces fenêtres de la partie   l'application, de sorte qu'ils sont   réduite au minimum, restauré, activé et   désactivée avec l'application.

Si je me concentre sur les mots « la poignée de la fenêtre de la forme principale de l'application », et je prends cela pour dire la poignée de la fenêtre de la forme principale de l'application , alors je peux comparer:

  • « la poignée de fenêtre de la forme principale de l'application », avec
  • la poignée de fenêtre du MainForm du Application

mais ils ne sont pas les mêmes:

Application.MainForm.Handle: 11473728
Application.Handle: 11079574

Alors, quelle est Application.Handle?

  • D'où vient-il?
  • Qu'est-ce que la poignée de fenêtre Windows® est-il?
  • S'il est la poignée de fenêtre Windows® de Application du MainForm, alors pourquoi ne pas correspondre?
  • S'il est pas la poignée de fenêtre du Application du MainForm, alors qu'est-ce?
  • Plus important encore: Pourquoi est-il le nec plus ultra parent propriétaire de toutes les formes
  • Et le plus important: Pourquoi tout va détraquer si j'essayer d'avoir une forme de unparented unowned (donc je peut apparaître sur la barre des tâches), ou essayez d'utiliser quelque chose comme IProgressDialog ?

Vraiment ce que je demande est: Quelle est la logique de conception qui fait Application.Handle existe? Si je peux comprendre le pourquoi, le comment devrait être évidente.


Mise à jour Comprendre à travers un jeu de vingt questions:

En parlant de la solution de faire apparaître une fenêtre sur la barre des tâches en faisant son propriétaire null, Peter ci-dessous en 2000 dit :

  

Cela peut causer des problèmes avec des formes modales prospectées de   formes secondaires.

     

Si l'utilisateur passe à une application de l'alors qu'un modal   la forme est, et puis de nouveau à la forme qui l'a montré, le formulaire modal peut   cacher sous la forme. Il est possible de faire face à ce en veillant à ce   la forme modale est apparenté [sic; il appartient signifiait] à la forme qui a montré (à l'aide   params.WndParent comme ci-dessus)

     

Mais cela est impossible avec la norme   les boîtes de dialogue de l'unité de Dialogs et exceptions , qui ont besoin de plus d'efforts pour   les amener à travailler à droite (manipulation essentiellement Application.OnActivate,   la recherche de formes modales apparentées à l'application via GetLastActivePopup   et les amener vers le haut de l'ordre Z via SetWindowPos).

  • Pourquoi une forme modale finissent coincé derrière d'autres formes?
  • Quel mécanisme apporte normalement une forme modale à l'avant, et pourquoi est-il ne fonctionne pas ici?
  • Windows® est chargé de montrer les fenêtres empilées. Qu'est-ce qui a mal tourné que Windows ne montre pas les fenêtres droit?

Il a également parlé de l'utilisation des nouvelles fenêtres de style étendu qui force une fenêtre à apparaître sur la barre des tâches (lorsque les règles normales de la rendre non propriété est insuffisante, peu pratique, ou indésirable), en ajoutant til WS_EX_APPWINDOW style étendu:

procedure TForm2.CreateParams(var Params: TCreateParams); 
begin 
   inherited CreateParams( params ); 

   Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; 
end; 

Mais il avertit:

  

Si vous cliquez sur un bouton de forme secondaire barre des tâches pendant une autre application est   actif cela apportera encore toutes les formes d'applications à l'avant. Si vous   ne veulent pas qu'il y ait l'option

Qui apporte toutes les formes à l'avant quand le propriétaire de la forme est encore Application.Handle. Application fait cela? Pourquoi ça fait ça? Plutôt que de faire cela, devrait-il pas pas faire cela? Quel est l'inconvénient de pas le faire; je vois l'inconvénient de faire il (le menu du système ne fonctionne pas propertly, les vignettes bouton barre des tâches sont inexactes, shell Windows ne peut pas réduire les fenêtres.


Dans un autre poste traitant de la Application, Mike Edenfield dit que la fenêtre parent envoie autre fenêtre de leur minimiser, maximiser et restaurer les messages :

  

Cela va ajouter le bouton de la barre des tâches de votre forme, mais il y a quelques autres petits détails à   manipuler. Bien évidemment, votre formulaire reçoit toujours minimiser / maximiser qui sont envoyés au parent   forme (la forme principale de l'application). Pour éviter cela, vous pouvez installer un message   gestionnaire pour WM_SYSCOMMAND en ajoutant une ligne telle que:

procedure WMSysCommand(var Msg: TMessage); WM_SYSCOMMAND; 

procedure TParentForm.WMSysCommand(var Msg: TMessage); 
begin 
   if Msg.wParam = SC_MINIMIZE then 
   begin 
      // Send child windows message, don't 
      // send to windows with a taskbar button. 
   end; 
end; 
     

Notez que ce gestionnaire va dans le reste de l'application PARENT sous forme de celui que vous voulez à se comporter de manière indépendante>, de manière à éviter de transmettre le message minimiser. Vous pouvez ajouter similaires> code pour SC_MAXIMIZE, SC_RESTORE, etc.

Comment est-ce que minimiser / maximiser / restaurer des messages pour mes fenêtres Windows® ne vont pas à ma fenêtre? Est-ce parce que les messages destinés à une fenêtre sont envoyés, par Windows® au propriétaire de la fenêtre? Et dans ce cas, toutes les formes dans une application Delphi sont la « propriété » Application? Est-ce que ne signifie pas que faire le nul propriétaire:

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
   inherited;
   Params.WndParent := 0; //NULL
end;

supprime Application et de poignée de fenêtre d'interférer avec ma forme, et Windows doit envoyer une nouvelle fois me mon mimimize / maximiser / restaurer des messages?


Peut-être que si nous comparé et maintenant une application Windows « normal » fait des choses, la façon dont Borland Delphi conçu initialement applications pour faire des choses - par rapport à cet objet Application et il est boucle principale.

  • quelle solution est la résolution de l'objet Application?
  • Quel changement a été fait avec les versions ultérieures de Delphi pour que ces mêmes problèmes n'existent pas?
  • at-il changé dans les versions ultérieures de Delphi n'introduire d'autres problèmes, que la conception de l'application inital a essayé si difficile à résoudre?
  • Comment ces nouvelles applications fonctionnent toujours sans application interférer avec eux?

Il est évident que Borland a réalisé la faille dans leur conception initiale. Quel était leur conception initiale, ce problème était-il de résoudre, ce qui est le défaut, ce qui a été la re-conception, et comment fonctionne-t-elle résoudre le problème?

Était-ce utile?

La solution

La raison de la fenêtre d'application a un peu d'une histoire sordide. Lors du développement de Delphi 1, nous savions que nous voulions utiliser « SDI » (fenêtres éparpillées dans le bureau) modèle pour l'IDE ui. Nous savions aussi que Windows aspiré (et fait encore) à ce modèle. Cependant, nous avons également remarqué que Visual Basic à l'époque utilisé ce modèle et il semble bien fonctionner. Un examen plus poussé, nous avons constaté que VB utilisé une fenêtre spéciale de stationnement « caché » qui a été utilisé comme « propriétaire » (Windows brouille la notion de parent et propriétaire parfois, mais la distinction est similaire à VCL) pour toutes les autres fenêtres visibles .

Voici comment nous avons résolu le « problème » où les fenêtres contenant le menu principal est rarement porté si le traitement Alt-F pour le menu Fichier ne fonctionnerait tout simplement pas. En utilisant cette fenêtre de stationnement central d'intermédiaire, nous pourrions plus facilement garder trace de et acheminer les messages vers les fenêtres appropriées.

Cet arrangement a également résolu un autre problème où normalement plusieurs fenêtres de haut niveau étaient totalement indépendants. En faisant l'application gère le « propriétaire » de toutes ces fenêtres, ils se comportent tous de concert. Par exemple, vous avez peut-être remarqué que lorsque vous sélectionnez any des fenêtres de l'application, tous les fenêtres d'application se déplacent à l'avant et conservent leur ordre z par rapport à l'autre. Cela permettrait également de rendre l'application de minimiser et de restauration en tant que groupement fonctionnel.

C'est une conséquence de l'utilisation de ce modèle. Nous peut ont fait manuellement tout ce travail pour garder les choses directement, mais la philosophie de conception était de ne pas réinventer Windows, mais pour tirer parti de là où nous le pouvions. Voilà aussi pourquoi un TButton ou TEdit est vraiment Windows "utilisateur" bouton et la fenêtre EDIT classe et de style, respectivement.

de Windows a évolué, ce modèle « SDI » a commencé à tomber en disgrâce. En fait Windows lui-même a commencé à devenir « hostile » à ce style d'application. À partir de Windows Vista et en continuant à 7, le shell utilisateur ne semble pas fonctionner correctement avec une application à l'aide d'une fenêtre de stationnement. Donc, nous avons décidé de mélanger les choses dans VCL pour éliminer la fenêtre de stationnement et déplacer sa fonction dans la forme principale. Cela présente plusieurs « poulet et des œufs » problèmes où nous devons avoir la fenêtre de stationnement disponible assez tôt dans l'initialisation de l'application afin que les autres fenêtres peuvent « attacher », mais la principale forme elle-même ne peut pas être construit assez tôt. TApplication doit sauter à travers quelques cerceaux pour obtenir ce travail, et il y a eu quelques cas de pointe subtiles qui ont causé problème, mais la plupart des problèmes ont été élaborés. Cependant, pour toutes les applications que vous aller de l'avant, il restera en utilisant le modèle de fenêtre de stationnement plus.

Autres conseils

Toutes les applications VCL ont une fenêtre de haut niveau « caché » appelé application. Ceci est créé automatiquement au démarrage de l'application. Entre autres choses, il est le principal gestionnaire de messages Windows pour VCL - d'où Application.ProcessMessages

.

Avoir la fenêtre de haut niveau des applications cachées provoque des choses étranges, sensiblement le menu système incomplet qui affiche dans la barre des tâches et des fenêtres de l'ongle du pouce incorrectes dans Vista. Les versions ultérieures de Delphi corriger cela.

Cependant, toutes les fenêtres doivent avoir en tant que parent, Windows tend juste à travailler mieux si elle est. Cependant, toute forme créée avec Application.CreateForm aura comme parent, et il sera également la propriété de l'objet Application. Comme ils appartiennent, ils seront libérés une fois l'application est libéré. Cela arrive dans les coulisses Forms.DoneApplication

De la recherche à la source Forms.pas (Delphi 2009), il semble qu'ils créent une fenêtre « maître » dans win32 applications pour autoriser les appels graphiques à

  • TApplication.Minimize
  • TApplication.Restore
  • etc

Il semble que les messages transmis au Application.Handle sont transmises selon le cas au MainForm, si elle existe. Cela permettrait à l'application de répondre à minimiser, etc si la fenêtre principale n'a pas été créée. En modifiant la source de projet, vous pouvez créer une application delphi sans une fenêtre principale.

Dans ce cas, les méthodes de TApplication continueront à fonctionner, même si vous ne l'avez pas créé une fenêtre principale. Je ne sais pas si je suis saisir toutes les fins, mais je n'ai pas le temps de passer par tout le code TApplication.

Par vos questions:

  • Où vient-il? Il est la poignée d'une fenêtre créée dans TApplication.Create

  • Qu'est-ce que la poignée de fenêtres est-il? une fausse fenêtre que chaque application IUG delphi exige dans le cadre de l'abstraction TApplication

  • Est-ce la poignée de fenêtres de la forme principale du appliation Non

  • Si ce ne est pas la poignée de mainform de l'application alors quel est-il? Voir ci-dessus

  • Plus important encore: pourquoi est-il le parent ultime de toutes les formes en supposant que vous avez raison que son parent ultime, je suppose qu'il en est ainsi parce qu'il le rend facile à trouver? toutes formes dans votre application (les enfants de l'énumération de cette forme « maître »).

  • et le plus important: pourquoi tout va détraquer si j'essayer d'avoir une forme être unparented Je pense que parce que la forme « maître » caché devient messages système que devrait transmettre à ses enfants et / ou mainform, mais ne peut pas trouver la forme unparented.

Quoi qu'il en soit, c'est mon avis sur la question. Vous pouvez probablement en apprendre davantage en regardant la déclaration TApplication et code forms.pas. L'essentiel de ce que je vois est-il est une abstraction commode.

Cordialement,

Don

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