Mon appli bloque la fermeture de Windows [Résolu]

vieuxpere 199 Messages postés samedi 3 janvier 2004Date d'inscription 17 décembre 2014 Dernière intervention - 3 mai 2009 à 22:29 - Dernière réponse : vieuxpere 199 Messages postés samedi 3 janvier 2004Date d'inscription 17 décembre 2014 Dernière intervention
- 7 mai 2009 à 15:31
Bonjour,

Mon application, qui se lance au démarrage de Windows, reste en arriere plan en permanence.

Jusqu'à maintenant mon application bloquée la fermeture de Windows quans l'utilisateur demandé l'arret.
Depuis le code ci-dessous, mon appli se ferme mais l'arret de windows s'interrompt, il faut donc le refaire arreter Windows pour que ca s'arrete enfin.

Je doit donc fermer en deux fois !

Si quelqu'un sait m'améliorer le code ci-dessous je lui en serait bien reconnaissant.

Cordialement,

// Detecte la fermeture de Windows (demandée par l'utilisateur)
procedure TForm4.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
Message.Result := 1;
end;

// Execute des operations pendant la fermeture de Windows
procedure TForm4.WM_ENDSESSION(var Message: TWMQueryEndSession);
Begin
Application.Terminate; // On ferme l'application
End;
Afficher la suite 

Votre réponse

19 réponses

Meilleure réponse
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 5 mai 2009 à 21:46
3
Merci
Ben un flag de façon générale c'est un indicateur en fait.
Par exemple, tu déclares en variable globale :

var
MyFlag: Integer=0;

Quand cette valeur est à 0, tout va bien.
Quand elle est à 1, il faut arrêter toutes les opérations en cours pour fermer l'application.
Au moment de la réception du WM_QUERYENDSESSION tu vas définir ce flag à 1, et toutes tes opérations stopperont, et Windows pourra fermer ton application et s'éteindre normalement.

Dans tes boucles de travail tu fais :

for I := 0 to ... do
begin
...
if MyFlag = 1 then Break;
end;

while ... do
begin
...
if MyFlag = 1 then Break;
end;

C'est une façon efficace de stopper toute opération rapidement.

Cordialement, Bacterius !

Merci Bacterius 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 74 internautes ce mois-ci

Commenter la réponse de Bacterius
ni69 1529 Messages postés samedi 12 juin 2004Date d'inscription 5 juillet 2010 Dernière intervention - 3 mai 2009 à 23:02
0
Merci
Bonsoir,
Tu as oublié l'instruction inherited
Voilà le code corrigé (remarque: il est inutile d'utiliser les deux messages Windows WMQueryEndSession et WMEndSession, un seul suffit pour réaliser ce que tu recherches) :

procedure WMQueryEndSession(var Msg: TWMQueryEndSession); message WM_QUERYENDSESSION;

procedure TForm4.WMQueryEndSession;
begin
   inherited;
   Application.Terminate;
   Msg.Result := 1;
end;

@+
Nico { www.ni69.info }
Commenter la réponse de ni69
vieuxpere 199 Messages postés samedi 3 janvier 2004Date d'inscription 17 décembre 2014 Dernière intervention - 4 mai 2009 à 14:38
0
Merci
Merci de ta réponse, je vais tester mais j'ai quand même une question comment "Msg.Result := 1;"va s'executer si avant je fais un application.terminate ?
Commenter la réponse de vieuxpere
vieuxpere 199 Messages postés samedi 3 janvier 2004Date d'inscription 17 décembre 2014 Dernière intervention - 4 mai 2009 à 14:40
0
Merci
A j'oubliez aussi, est-ce que ce code doit-être mis sur toutes les fenetres potentiellement ouvertes au moment de la fermeture de Windows ou juste sur la fenetre principale ?
Commenter la réponse de vieuxpere
vieuxpere 199 Messages postés samedi 3 janvier 2004Date d'inscription 17 décembre 2014 Dernière intervention - 4 mai 2009 à 14:48
0
Merci
NON helas, aprés avoir testé :






procedure TForm4.WMQueryEndSession;
begin
   inherited;
   Application.Terminate;
   Msg.Result := 1;
end;



Ca ne fonctionne pas, ça me ferme certes mon application mais windows ne se ferme pas, je dois le faire donc en deux fois.
Commenter la réponse de vieuxpere
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 4 mai 2009 à 17:59
0
Merci
Non !
Windows terminera ton application lui-même comme un grand. Enleve le Application.Terminate et ça devrait rouler.

Cordialement, Bacterius !
Commenter la réponse de Bacterius
ni69 1529 Messages postés samedi 12 juin 2004Date d'inscription 5 juillet 2010 Dernière intervention - 4 mai 2009 à 20:41
0
Merci
@vieuxpere:
Désolé, une petite inversion de lignes... J'ai pas trop réfléchi à vrai dire il était tard ! Il faut bien sûr lire :
   inherited;
   Msg.Result := 1;
   Application.Terminate;
Mais en pratique, il est vrai que
   Msg.Result := 1;
est facultatif, vu qu'il est géré par l'appel à inherited;
Cette procédure mise sur la form principale est amplement suffisante. Cela marche très bien pour moi je viens de tester, donc regarde peut-être au niveau des autres applications qui tournent en même temps (cf taskmgr). Peut-être que le problème ne vient pas de la tienne!

@Bacterius:
Tout dépend de si l'application est dans une phase bloquante ou non (procédure longue en cours, boucle qui n'est pas encore finie...)
Dans ce genre de cas, l'utilisation d'un flag associé à la boucle en cours peut être utile (on modifie le flag dans la procédure liée au WMQES, et cela est répercuté dans la boucle...)

@+
Nico { www.ni69.info }
Commenter la réponse de ni69
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 4 mai 2009 à 20:59
0
Merci
En général il faut tout faire pour respecter les choix de l'utilisateur.
Si l'utilisateur veut fermer, tu ne dois pas être en boucle de travail.
M'enfin des fois evidemment il faut attendre quelques minutes par exemple pendant une sauvegarde de base de données de dernière minute, mais dans ce cas-là la moindre des choses est d'afficher une messagebox avec marqué "patientez svp" en gros. Ou bien sur Vista, appeller ShutdownReasonBlockCreate.
Mais effectivement ça peut être utile d'utiliser un flag pour savoir de quoi on parle ...

Cordialement, Bacterius !
Commenter la réponse de Bacterius
ni69 1529 Messages postés samedi 12 juin 2004Date d'inscription 5 juillet 2010 Dernière intervention - 4 mai 2009 à 21:14
0
Merci
"Si l'utilisateur veut fermer, tu ne dois pas être en boucle de travail."
Je ne suis pas d'accord avec cela. Par exemple, si tu es en train de parcourir tous les fichiers du disque pour une recherche particulière qui dure longtemps, et qu'en plein milieu, l'utilisateur décide inopinément de quitter windows, il faut stopper la boucle. Là est l'utilité d'un flag. Mais c'est loin d'être le seul cas...

@+
Nico { www.ni69.info }
Commenter la réponse de ni69
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 4 mai 2009 à 21:34
0
Merci
Je n'ai pas dit le contraire, je dis qu'il faut éviter les longs traitements qui empêchent Windows de fermer. Mais je me suis mal exprimé je le reconnais. En fait on va mettre à True une variable booléenne globale quand on veut stopper la boucle, et la boucle, à chaque itération teste la variable et se casse si c'est à True (en gros, après on peut utiliser une variable de type Integer pour spécifier plusieurs types de réactions, etc ...) ?

Cordialement, Bacterius !
Commenter la réponse de Bacterius
vieuxpere 199 Messages postés samedi 3 janvier 2004Date d'inscription 17 décembre 2014 Dernière intervention - 5 mai 2009 à 11:37
0
Merci
Bonjour, je suis désolé ça ne fonctionne pas !
A la demande de fermeture Windows, mon application se ferme, mais windows s'interrompt de fermer, je dois donc continuer à le faire en deux fois.

Voici mon code complet :

  public
    { Déclarations publiques }



    // Déclaration de la procédure qui va permettre de detecter la fermeture de Windows
    procedure WMQueryEndSession(var Msg: TWMQueryEndSession); message WM_QUERYENDSESSION;



  end;



var
  Form17: TForm17;



implementation



uses Unit9, Unit11, Unit3, Unit1, Unit4, Unit5, Unit2;



{$R *.dfm}



// Detecte la fermeture de Windows  (demandée par l'utilisateur)
procedure TForm17.WMQueryEndSession (var Msg: TWMQueryEndSession);
  begin
  Inherited;
  Msg.Result:= 1;
  Application.Terminate; // On ferme l'application
  end;


Merci par avance pour votre aide, car là je séche !
Commenter la réponse de vieuxpere
ni69 1529 Messages postés samedi 12 juin 2004Date d'inscription 5 juillet 2010 Dernière intervention - 5 mai 2009 à 13:10
0
Merci
Exécutes-tu ton application à partir de l'EDI, ou bien en dehors du débugger?

@+
Nico { www.ni69.info }
Commenter la réponse de ni69
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 5 mai 2009 à 18:15
0
Merci
Bon sang ! Enleve ce Application.Terminate ! Il n'a rien à faire là ! On s'occupera de fermer ton app, ne t'inquiète pas (en revanche, si tu as une boucle, utilise les flags).
Et euh je vois Form17. Il ne faut mettre ce code que dans (et DANS) ta fiche principale, et non pas dans une autre fiche.

Cordialement, Bacterius !
Commenter la réponse de Bacterius
ni69 1529 Messages postés samedi 12 juin 2004Date d'inscription 5 juillet 2010 Dernière intervention - 5 mai 2009 à 18:28
0
Merci
Oh, et juste au passage, pense quand même à renommer tes forms et unités, parce que ça va finir par te faire mal à la tête tout ça...

Form17

@+
Nico { www.ni69.info }
Commenter la réponse de ni69
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 5 mai 2009 à 18:33
0
Merci
17 fiches dans une application. Woah ... mon record c'était 12 fiches :p

Cordialement, Bacterius !
Commenter la réponse de Bacterius
vieuxpere 199 Messages postés samedi 3 janvier 2004Date d'inscription 17 décembre 2014 Dernière intervention - 5 mai 2009 à 21:23
0
Merci
Lol, mon appli à 19 forms. No comment...

Sinon pardonnez ma question mais c'est quoi un Flags et comment je peux l'utiliser ?

En tous cas merci à tous.
Commenter la réponse de vieuxpere
ni69 1529 Messages postés samedi 12 juin 2004Date d'inscription 5 juillet 2010 Dernière intervention - 5 mai 2009 à 21:54
0
Merci
Bonsoir,
Je me permets un petit complément à ce que tu viens d'écrire :
Mieux vaut parfois utiliser exit plutôt que break dans les boucles, pour sortir directement de la procédure (si une boucle n'est pas finie et qu'on passe à la suite, il y a risque de plantage). Mais cela dépend bien évidemment du contexte ! On peut trouver des cas contraires où c'est exit qui génère un bug (mais c'est quand même plus rare).

Quoiqu'il en soit ces flags ne doivent être employés qu'en cas de réelle nécessité, sinon il finit par y en avoir de partout et ça alourdit le code en diminuant sa lisibilité.
A savoir aussi que généralement les flags sont des booléens, car on n'a dans la plupart des cas pas besoin d'une information dépassant la taille du bit.

@+
Nico { www.ni69.info }
Commenter la réponse de ni69
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 5 mai 2009 à 22:11
0
Merci
En effet on aurait pu utiliser un Boolean. Mais parfois on a besoin de savoir exactement ce que veut l'utilisateur (par exemple 0 pour tout va bien, 1 pour l'utilisateur a choisi de fermer l'application, 2 pour le système va s'éteindre). Mais c'est également rare ...

Cordialement, Bacterius !
Commenter la réponse de Bacterius
vieuxpere 199 Messages postés samedi 3 janvier 2004Date d'inscription 17 décembre 2014 Dernière intervention - 7 mai 2009 à 15:31
0
Merci
Ok j'ai compris merci bcp
Commenter la réponse de vieuxpere

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.