2009-12-10 24 views
1

J'ai remarqué un comportement étrange lors de l'utilisation de MessageDlg et la tentative de fermeture de mon application via la commande Barre des tâches fermer tout/groupe.Delphi 2009 - Fermer toutes les fonctions de la barre des tâches arrête le traitement si présenté avec MessageDlg?

Ma demande est la suivante:

  1. Il y a une forme principale cachée qui ne fait pas autre chose que gérer certains messages Windows et passez-les sur les fenêtres de l'enfant (le cas échéant).
  2. Chaque fenêtre enfant a son parent défini sur le bureau (afin de l'afficher dans la barre des tâches).
  3. Chaque enfant a un événement OnClose qui apparaît un MessageDlg pour inviter l'utilisateur si elles veulent sauver leur session (le cas échéant le contenu a été modifié en tout cas)

La question semble être elle fermera ses portes en permanence toutes les fenêtres qui ne sont pas modifiées, mais, quand il frappe une fenêtre qui a été, 1 de 2 choses se produisent par intermittence:

  1. Peu importe si je sélectionne « Oui/non » Fermer tout processus semble arrêter après que cette fenêtre particulière est fermée.
  2. La boîte de dialogue n'est pas affichée et mrAnnuler est le résultat. Encore une fois, la fermeture de tout le processus s'arrête après que cette fenêtre est fermée.

Une modification que j'ai faite était d'utiliser la fonction WinAPI MessageBox en remplacement de MessageDlg et cela a semblé résoudre le problème. Cependant, j'aimerais vraiment savoir pourquoi MessageDlg agit comme ça? Ma première pensée était quand la boîte de dialogue est lancée au milieu du Close Tout peut-être le système d'exploitation envoie un message WM_CLOSE au dialogue car il fait techniquement partie du groupe (ceci expliquerait le dialogue n'apparaissant pas et défaut à mrCancel car c'est l'équivalent d'appuyer sur X). Cependant, cela n'explique pas pourquoi, après avoir fermé la boîte de dialogue, le processus Fermer tout ne continue pas à fermer les autres fenêtres du groupe!

Des idées/idées à ce sujet?

Répondre

3

Windows n'envoie pas de messages WM_CLOSE à ces fenêtres, il publie WM_SYSCOMMAND avec la demande SC_CLOSE. Cela entraîne l'envoi de messages WM_CLOSE si la boîte de message Windows standard est utilisée. Si la fonction MessageDlg() est utilisée à la place, seul le premier WM_SYSCOMMAND affiché mène à WM_CLOSE, les autres ne le sont pas.C'est difficile à dire, mais peut-être cela a-t-il quelque chose à voir avec les appels DisableTaskWindows() et EnableTaskWindows() que la VCL utilise pour "simuler" les dialogues modaux. Si vous remplacez la fonction Windows par Application.MessageBox(), un wrapper qui utilise DisableTaskWindows() et EnableTaskWindows(), il ne fonctionne pas non plus (quel IMO prend en charge ce raisonnement).

+0

Où vous pouvez reproduire ce problème alors? Basculer vers le MessageBox semble fonctionner donc j'allais simplement changer de MessageDlg. – James

+0

Oui, j'ai été capable de le reproduire. Comme je l'ai écrit, je crois qu'il est ancré dans la gestion VCL des fenêtres modales, donc ne pas utiliser les fenêtres modales VCL est votre solution la plus facile. Notez que l'utilisation de la fonction Windows standard peut également présenter d'autres avantages (prise en charge transparente des nouveaux styles d'interface utilisateur, le libellé des boutons correspond au système d'exploitation par défaut, ...). – mghie

+0

La seule restriction que nous avons (c'est pourquoi nous utilisons le MessageDlg) est que nous avons besoin de boutons Oui à tous et Non à tous dans la boîte de message. Est-ce possible avec MessageBox? De ce que je lis ... ce n'est pas – James

0

Je pense que je peux expliquer pourquoi le passage de MessageDlg à MessageBox a rendu les choses différentes. MessageDlg à son tour appelle le MessageDlgPosHelp qui crée un formulaire Delphi pour ressembler à Windows MessageBox, et ce formulaire est appelé avec ShowModal. Cela verrouille toute l'application jusqu'à sa fermeture. Par contre, par défaut, MessageBox est MB_APPLMODAL, ce qui signifie que vous devez le fermer avant de pouvoir utiliser la fenêtre à laquelle il est attaché. Si vous n'avez rien spécifié dans le paramètre uFlags, il s'agit du paramètre par défaut. Cela vous empêche uniquement de revenir à la fenêtre spécifiée dans le paramètre hwnd, de sorte que les autres fenêtres de votre application restent accessibles.

+0

Bonne estimation, mais pas vrai. Peu importe que l'appel 'MessageBox()' soit fenêtre-modale, tâche-modale ou même modal-système - cela fonctionne dans tous les cas. – mghie