Qu'est-ce que TApplication.Handle
?
- D'où vient-il ?
- Pourquoi existe-t-il ?
- Et le plus important : pourquoi tous les formulaires ont-ils cette poignée comme poignée de fenêtre parent ?
L'aide de Delphi dit :
TApplication.Handle
Permet d'accéder à la poignée de fenêtre du formulaire principal (fenêtre) de l'application l'application.
property Handle: HWND;
Description
Utilisez Handle lorsque vous appelez des fonctions de l'API Windows qui nécessitent une fenêtre parent poignée. Par exemple, une DLL qui affiche sa propre fenêtre pop-up de niveau supérieur supérieure a besoin d'une fenêtre parent pour afficher ses fenêtres dans l'application l'application. L'utilisation de la propriété Handle permet à ces fenêtres de faire partie de l'application l'application, de sorte qu'elles sont réduites, restaurées, activées et désactivées avec l'application.
Si je me concentre sur les mots " le handle de la fenêtre du formulaire principal de l'application ", et j'en déduis que cela signifie le handle de la fenêtre du formulaire principal de l'application alors je pourrai comparer :
- "l'identifiant de la fenêtre du formulaire principal de l'application".
- la poignée de fenêtre de la
MainForm
de laApplication
mais ils ne sont pas les mêmes :
Application.MainForm.Handle: 11473728
Application.Handle: 11079574
Alors, qu'est-ce que Application.Handle
?
- D'où vient-il ?
- De quelle poignée de fenêtre Windows® s'agit-il ?
- Si elle es la poignée de fenêtre Windows® de la
Application
'sMainForm
alors pourquoi ne correspondent-ils pas ? - Si c'est no la poignée de fenêtre de la
Application
'sMainForm
alors qu'est-ce que c'est ? - Plus important encore : Pourquoi est-ce l'ultime
parentpropriétaire de chaque forme ? - Et le plus important : pourquoi tout se détraque-t-il si j'essaie de faire en sorte qu'un formulaire soit
sans parentsnon propriétaire (pour qu'il puisse apparaître dans la barre des tâches), ou essayez d'utiliser quelque chose comme IProgressDialog ?
Ce que je demande vraiment c'est : Quel est le raisonnement de conception qui fait que Application.Handle exister ? Si je peux comprendre le pourquoi, le comment devrait devenir évident.
Mise à jour La compréhension à travers un jeu de vingt questions :
En parlant de la solution consistant à faire apparaître une fenêtre dans la barre des tâches en faisant en sorte que son propriétaire null
, Peter Below a déclaré en 2000 :
Cela peut causer des problèmes avec les formulaires modaux affichés à partir de formes secondaires.
Si l'utilisateur quitte l'application pendant qu'un formulaire modal est affichée, puis revient au formulaire qui l'a affichée, le formulaire modal peut être se cacher sous le formulaire. Il est possible de résoudre ce problème en s'assurant que le formulaire modal est parenté [sic ; il voulait dire possédé] au formulaire qui l'a affiché (en utilisant
params.WndParent
comme ci-dessus)Mais cela n'est pas possible avec les de l'interface
Dialogs
et exceptions qui nécessitent plus d'efforts pour pour qu'ils fonctionnent correctement (essentiellement la manipulationApplication.OnActivate
, recherche des formulaires modaux dont le parent est Application viaGetLastActivePopup
et les amener au sommet de l'ordre Z viaSetWindowPos
).
- Pourquoi un formulaire modal se retrouve-t-il coincé derrière d'autres formulaires ?
- Quel mécanisme amène normalement une forme modale à l'avant, et pourquoi n'est-il pas fonctionnel ici ?
- Windows® est responsable de l'affichage de Windows empilé. Qu'est-ce qui s'est passé pour que Windows® n'affiche pas les bonnes fenêtres ?
Il a également parlé de l'utilisation du nouveau style étendu de Windows qui force une fenêtre à apparaître dans la barre des tâches (lorsque les règles normales qui consistent à la rendre non propriétaire sont insuffisantes, peu pratiques ou indésirables), en ajoutant l'attribut 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 met en garde :
Si vous cliquez sur un bouton de la barre des tâches pour les formulaires secondaires alors qu'une autre application est active, tous les formulaires de l'application seront mis en avant. active, tous les formulaires de l'application seront mis en avant. Si vous ne voulez pas cela, il existe une option
Qui apporte tous les formulaires à l'avant alors que le propriétaire du formulaire est toujours Application.Handle
. Est Application fait ça ? Pourquoi fait-il cela ? Plutôt que de faire ça, ne devrait-il pas no faire cela ? Quel est l'inconvénient de no faire cela ; je vois l'inconvénient de en faisant (les menus système ne fonctionnent pas correctement, les vignettes des boutons de la barre des tâches sont inexactes, le shell Windows® ne peut pas minimiser Windows.
Dans un autre billet traitant de la Application
, Mike Edenfield dit que la fenêtre parent envoie aux autres fenêtres leurs messages de minimisation, d'agrandissement et de restauration. :
Cela ajoutera le bouton de la barre des tâches pour votre formulaire, mais il y a quelques autres détails mineurs à gérer. Le plus évident est que votre formulaire reçoit toujours des minimisations/maximisations qui sont envoyées au formulaire parent (le formulaire principal de l'application). (le formulaire principal de l'application). Afin d'éviter cela, vous pouvez installer un gestionnaire de message 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 est placé dans la section PARENT de celui que vous souhaitez voir se comporter indépendamment du > reste de l'application, afin d'éviter de transmettre le message de minimisation. Vous pouvez ajouter un code similaire pour SC_MAXIMIZE, SC_RESTORE, etc.
Comment se fait-il que les messages de minimisation/maximisation/restauration de mon Windows® ne parviennent 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, tous les formulaires d'une application Delphi sont "propriétaires" de Application
? Cela ne signifie-t-il pas que rendre le propriétaire nul :
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := 0; //NULL
end;
supprimera Application
et sa poignée de fenêtre d'interférer avec mon formulaire, et Windows devrait à nouveau envoyer moi mes messages de mimimisation/maximisation/restauration ?
Peut-être que si nous comparions et contrastons la façon dont une application Windows "normale" fait les choses, avec la façon dont Borland a initialement conçu les applications Delphi pour qu'elles fassent les choses - en ce qui concerne ceci Application
et sa boucle principale.
- quelle solution était la
Application
la résolution d'objets ? - Quelles modifications ont été apportées aux versions ultérieures de Delphi pour que ces mêmes problèmes n'existent plus ?
- Les modifications apportées aux versions ultérieures de Delphi n'ont-elles pas introduit d'autres problèmes, que la conception initiale de l'application s'efforçait de résoudre ?
- Comment ces applications plus récentes peuvent-elles continuer à fonctionner sans que l'application n'interfère avec elles ?
Il est évident que Borland s'est rendu compte de la faille dans leur conception initiale. Quelle était leur conception initiale, quel problème résolvait-elle, quel est le défaut, quelle est la nouvelle conception, et comment résout-elle le problème ?
0 votes
Je pense que ces deux astuces vont vous intéresser : yoy.be/item.asp?i89 yoy.be/item.asp?i87
2 votes
@Stinh Sanders : j'ai vu ces méthodes, elles ne résolvent pas les problèmes. De même, ne passez jamais, jamais, jamais GetDesktopWindow en tant que propriétaire d'une fenêtre, comme le suggèrent ces messages et d'autres messages sur le sujet. En faisant cela, Windows se figeait. C'était un tel problème que Microsoft a corrigé CreateWindow, de sorte que toute personne passant GetDesktopWindow comme propriétaire doit utiliser NULL à la place. Et si je pouvais modifier ce post sur yoy.com Je le ferais.
0 votes
A Tokyo, Application.Handle est à zéro !
0 votes
Le "propriétaire" d'un formulaire est indépendant du "parent" d'un formulaire (mais peut être le même). Le propriétaire est lié à la façon dont Delphi lie les objets basés sur des composants TC les uns aux autres, de sorte qu'ils sont automatiquement libérés lorsque le propriétaire (cf.
Create(AOwner: TComponent
) est libéré. Le "Parent" (ou "WndParent") a trait à la relation visuelle parent/enfant des contrôles visuels. Alors pourquoi chaque formulaire aApplication
en tant que propriétaire, carApplication.CreateForm(TMyForm, MyForm)
crée le formulaire en l'utilisant comme propriétaire. Et pour ce qui est du handle parent 'Application.Handle', voirTCustomForm.CreateParams
.