Windows est en cours d'arrêt


Comment le processus de WM_ENDSESSION etc
Contributeur: HALLVARD VASSBOTN
{
Dans un précédent envoyé par la poste avec le sujet '[Delphi] Serios bug lors de la fermeture de
windows???' [email protected](Par Bakkendorff) écrit:
>Quand vous avez un delphi application en cours d'exécution, et vous êtes à l'arrêt de windows,
>(ne fermez pas votre première application), AUCUN de vos destructeurs sont appelés!!!!
Au début, je pensais que le problème était du programmeur code, mais ensuite j'ai réalisé que c'est vraiment un bug ou au moins une très paresseux 'fonction'.
Le problème semble être que lorsque vous fermez Windows, il va d'abord envoyer un message WM_QueryEndSession à toutes les fenêtres de niveau supérieur. C'est manipulés et traités correctement par la TForm objet de la VCL.
Ensuite, en supposant que toutes les applications ont indiqué que c'était ok pour fermer, Windows envoie WM_EndSession des messages à toutes les fenêtres. Ce message n'est pas géré par la VCL. L'application est tout simplement ramené avec un bang.
Pas de fenêtres sont fermées, pas de destructeur appelé et personne ne les procédures de sortie appelé.
La solution est de gérer la WM_EndSession message vous-même. Il y a plusieurs façons de gérer les messages en Delphi, mais la seule façon fiable de gestion de la WM_ENDSESSION est d'utiliser le HookWindow de la méthode d'Application.
Dans le gestionnaire de messages, vérifier pour voir si le message est une WM_ENDSESSION. Si oui, nous devrions fermer l'application. Nous pourrions avoir appelé la méthode de fermeture de la fenêtre principale, mais la documentation de l'API Windows états que le système peut à tout moment après le retour de la WM_ENDSESSION, et posté un message WM_QUIT pourrait ne jamais arriver à l'application.
La solution est de simplement appeler Arrêt à la place. Ce qui appelle de tous ses procédures de sortie, y compris ceux dans les Contrôles de base de données et les unités. Ces permettra de libérer de l'application et les objets à l'écran et de prendre le BDE vers le bas correctement.
voici Un exemple simple:
}
unité de Tst2u
interface

& nbsp & nbsp SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
& nbsp & nbsp Formes, des Dialogues, des Grilles, des DBGrids, DB, DBTables
type
& nbsp & nbsp TForm1 = class(TForm)
& ! & ! & ! & nbsp DataSource1: TDataSource
& ! & ! & ! & nbsp Table1: TTable
& ! & ! & ! & nbsp DBGrid1: TDBGrid
& ! & ! & ! & nbsp procedure FormCreate(Sender: TObject)
& nbsp & nbsp privé
& ! & ! & ! & nbsp { Private declarations }
& ! & ! & ! & nbsp fonction HookProc(var Message: TMessage): boolean
& nbsp & nbsp public

& ! & ! & ! & nbsp { déclarations Publiques }
& nbsp & nbsp fin
var
& nbsp & nbsp Form1: TForm1
application
{$R *.DFM}
const
& nbsp & nbsp FlagFileName = 'C:\Flag.Fil'
procédure CreateFlagFile
var
& nbsp & nbsp F: Système.Texte
begin
& nbsp & nbsp Système.Assign(F, FlagFileName)
& nbsp & nbsp Système.Rewrite(F)
& nbsp & nbsp Writeln(F, 'C'est un mannequin fichier flag')
& nbsp & nbsp Système.Fermer(F)
fin
procédure KillFlagFile
var
& nbsp & nbsp F: Fichier
begin
& nbsp & nbsp Système.Assign(F, FlagFileName)
& nbsp & nbsp Système.Effacer(F)
fin
procédure MyExitProc loin
begin
& nbsp & nbsp KillFlagFile
fin
procedure TForm1.FormCreate(Sender: TObject)
begin
& nbsp & nbsp Application.HookMainWindow(HookProc)
fin
fonction de TForm1.HookProc(var Message: TMessage): boolean
begin
& nbsp & nbsp Result := false
& nbsp & nbsp si le Message.Msg = WM_EndSession puis
& nbsp & nbsp commencer
& ! & ! & ! & nbsp si WordBool(Message.wParam)
& ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & nbsp { Windows va fermer - pour le nettoyage!! }
& ! & ! & ! & ! & ! & nbsp { Ce qui doit exécuter tous les ExitProcs, fermer les fenêtres et d'appeler les destructeurs... }
& ! & ! & ! & ! & ! & ! & nbsp Stopper { Cela fonctionne! }
& ! & ! & ! & ! & ! & nbsp { Cela devrait fermer les choses correctement,
& ! & ! & ! & ! & ! & ! & ! & nbsp mais avons-nous assez de temps pour gérer tous les messages postés avant Windows
& ! & ! & ! & ! & ! & ! & ! & nbsp est déjà en panne?? Il en résultera une PostQuitMessage qui peut
& ! & ! & ! & ! & ! & ! & ! & nbsp jamais arriver!}
{ Fermer } { Cela ne fonctionne pas toujours - éviter }
& ! & ! & ! & nbsp fin
& nbsp & nbsp fin
fin
initialisation
& nbsp & nbsp CreateFlagFile
& nbsp & nbsp AddExitProc(MyExitProc)
à la fin.
Cette unité, qui démontre que les procédures de sortie sont appelés lors de la fermeture de l'application normalement et lors de la fermeture de Windows et à l'aide HookMainWindow. Sans le HookMainWindow appel, la sortie proc ne sera pas appelé. Ceci est particulièrement important pour la DB applications. Sans l'Interrompre, LCK fichiers ne seront pas supprimés, tampons peut pas être vidées, les changements posté et ainsi de suite.









Windows est en cours d'arret


Windows est en cours d'arret : Plusieurs milliers de conseils pour vous faciliter la vie.


Comment le processus de WM_ENDSESSION etc
Contributeur: HALLVARD VASSBOTN
{
Dans un precedent envoye par la poste avec le sujet '[Delphi] Serios bug lors de la fermeture de
windows???' [email protected](Par Bakkendorff) ecrit:
>Quand vous avez un delphi application en cours d'execution, et vous etes a l'arret de windows,
>(ne fermez pas votre premiere application), AUCUN de vos destructeurs sont appeles!!!!
Au debut, je pensais que le probleme etait du programmeur code, mais ensuite j'ai realise que c'est vraiment un bug ou au moins une tres paresseux 'fonction'.
Le probleme semble etre que lorsque vous fermez Windows, il va d'abord envoyer un message WM_QueryEndSession a toutes les fenetres de niveau superieur. C'est manipules et traites correctement par la TForm objet de la VCL.
Ensuite, en supposant que toutes les applications ont indique que c'etait ok pour fermer, Windows envoie WM_EndSession des messages a toutes les fenetres. Ce message n'est pas gere par la VCL. L'application est tout simplement ramene avec un bang.
Pas de fenetres sont fermees, pas de destructeur appele et personne ne les procedures de sortie appele.
La solution est de gerer la WM_EndSession message vous-meme. Il y a plusieurs façons de gerer les messages en Delphi, mais la seule façon fiable de gestion de la WM_ENDSESSION est d'utiliser le HookWindow de la methode d'Application.
Dans le gestionnaire de messages, verifier pour voir si le message est une WM_ENDSESSION. Si oui, nous devrions fermer l'application. Nous pourrions avoir appele la methode de fermeture de la fenetre principale, mais la documentation de l'API Windows etats que le systeme peut a tout moment apres le retour de la WM_ENDSESSION, et poste un message WM_QUIT pourrait ne jamais arriver a l'application.
La solution est de simplement appeler Arret a la place. Ce qui appelle de tous ses procedures de sortie, y compris ceux dans les Controles de base de donnees et les unites. Ces permettra de liberer de l'application et les objets a l'ecran et de prendre le BDE vers le bas correctement.
voici Un exemple simple:
}
unite de Tst2u
interface

& nbsp & nbsp SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
& nbsp & nbsp Formes, des Dialogues, des Grilles, des DBGrids, DB, DBTables
type
& nbsp & nbsp TForm1 = class(TForm)
& ! & ! & ! & nbsp DataSource1: TDataSource
& ! & ! & ! & nbsp Table1: TTable
& ! & ! & ! & nbsp DBGrid1: TDBGrid
& ! & ! & ! & nbsp procedure FormCreate(Sender: TObject)
& nbsp & nbsp prive
& ! & ! & ! & nbsp { Private declarations }
& ! & ! & ! & nbsp fonction HookProc(var Message: TMessage): boolean
& nbsp & nbsp public

& ! & ! & ! & nbsp { declarations Publiques }
& nbsp & nbsp fin
var
& nbsp & nbsp Form1: TForm1
application
{$R *.DFM}
const
& nbsp & nbsp FlagFileName = 'C:\Flag.Fil'
procedure CreateFlagFile
var
& nbsp & nbsp F: Systeme.Texte
begin
& nbsp & nbsp Systeme.Assign(F, FlagFileName)
& nbsp & nbsp Systeme.Rewrite(F)
& nbsp & nbsp Writeln(F, 'C'est un mannequin fichier flag')
& nbsp & nbsp Systeme.Fermer(F)
fin
procedure KillFlagFile
var
& nbsp & nbsp F: Fichier
begin
& nbsp & nbsp Systeme.Assign(F, FlagFileName)
& nbsp & nbsp Systeme.Effacer(F)
fin
procedure MyExitProc loin
begin
& nbsp & nbsp KillFlagFile
fin
procedure TForm1.FormCreate(Sender: TObject)
begin
& nbsp & nbsp Application.HookMainWindow(HookProc)
fin
fonction de TForm1.HookProc(var Message: TMessage): boolean
begin
& nbsp & nbsp Result := false
& nbsp & nbsp si le Message.Msg = WM_EndSession puis
& nbsp & nbsp commencer
& ! & ! & ! & nbsp si WordBool(Message.wParam)
& ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & nbsp { Windows va fermer - pour le nettoyage!! }
& ! & ! & ! & ! & ! & nbsp { Ce qui doit executer tous les ExitProcs, fermer les fenetres et d'appeler les destructeurs... }
& ! & ! & ! & ! & ! & ! & nbsp Stopper { Cela fonctionne! }
& ! & ! & ! & ! & ! & nbsp { Cela devrait fermer les choses correctement,
& ! & ! & ! & ! & ! & ! & ! & nbsp mais avons-nous assez de temps pour gerer tous les messages postes avant Windows
& ! & ! & ! & ! & ! & ! & ! & nbsp est deja en panne?? Il en resultera une PostQuitMessage qui peut
& ! & ! & ! & ! & ! & ! & ! & nbsp jamais arriver!}
{ Fermer } { Cela ne fonctionne pas toujours - eviter }
& ! & ! & ! & nbsp fin
& nbsp & nbsp fin
fin
initialisation
& nbsp & nbsp CreateFlagFile
& nbsp & nbsp AddExitProc(MyExitProc)
a la fin.
Cette unite, qui demontre que les procedures de sortie sont appeles lors de la fermeture de l'application normalement et lors de la fermeture de Windows et a l'aide HookMainWindow. Sans le HookMainWindow appel, la sortie proc ne sera pas appele. Ceci est particulierement important pour la DB applications. Sans l'Interrompre, LCK fichiers ne seront pas supprimes, tampons peut pas etre videes, les changements poste et ainsi de suite.


Windows est en cours d'arrêt

Windows est en cours d'arrêt : Plusieurs milliers de conseils pour vous faciliter la vie.
Recommander aux amis
  • gplus
  • pinterest

Messages récents

Commentaire

Laisser un commentaire

évaluation