IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Stopper la suite des instructions d'une procédure et attendre la réception d'un message


Sujet :

Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 157
    Points : 67
    Points
    67
    Par défaut Stopper la suite des instructions d'une procédure et attendre la réception d'un message
    Bonjour

    Je voudrais au niveau de ma procédure arrêter l'exécution de la succession des instructions en attendant la réception d'un message qui est envoyé par un DLL externe. Je vous donne un prototype de ce que je faire ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
     procedure TForm1.test;
     begin
       procedure A; // Cette procédure appelle des fonctions d'une DLL. La fin de l’exécution de ces fonctions est indiquée par l'envoi d'un message WM_launch
       // Arrêt et attente de la réception du message
      procedure B; 
     end;
     
     procedure TForm1.DefaultHandler(var Message);
    begin
      if TMessage(Message).Msg = WM_Launch then
      begin
        // Envoyer un signal indiquant la reprise de la procédure test
      end;
    end;
    J'ai vu qu'avec le TEvent on pouvait gérer la réception des événements et, d'après la doc, ça me paraît assez simple à mettre en place. Par contre, je suis pas sûr que ça soit la solution pour provoquer l’arrêt et l'attente de ma procédure test.

    Pensez vous que ça soit la bonne solution ou est-ce que vous proposez une autre solution ?

    Merci

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Avez vous songé aux threads ?
    Toutefois, avant d'en donner plus, les nouvelles versions de Delphi proposant différents types de thread il me/nous faudrait connaitre la version utilisée
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 689
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 689
    Points : 13 118
    Points
    13 118
    Par défaut
    Le problème est que TEvent est bloquant, l'application ne pourra jamais traiter le message censé le libérer.

    Pourquoi ne pas simplement exécuter "B" à la réception du message ?

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 157
    Points : 67
    Points
    67
    Par défaut
    Merci pour vos réponses.

    @SergioMaster, la version c'est un de mes problème, j'utilise une ancienne version Delphi2005 mais de tout façon les thread se gère bien avec cette version. Par contre dans mon problème comme je suis dans le thread principal, il faudrait que je l’arrête comme même pour attendre le signal de la réception de mon message.

    @Andnotor, j'ai donné juste un schéma de mon programme pour par trop embrouillé les lecteurs. mais ma procédure test est une procédure qui gère un manage un message qui a été émit par une autre DLL. Je dois donc donner une réponse à cette DLL "Msg.Result". et bien sur cette réponse dépend de la réception du message WM_launch. Dans le cas que je présente après l'exécution de la procédure A le programme passe directement à la procédure B et termine le process avant l'arrivée d mon message.

    J'avais pensé à faire des envoie d'un message dirigé plusieurs fois dans une boucle avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
      Repeat
        value := SendMessage(fhandle,WM_msgTest,0,0)
      until value = -1;
    "value" serait modifiée à la réception du message WM_launch mais je trouve ça très laid comme programmation. Vous en pensez quoi?

    Merci

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 689
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 689
    Points : 13 118
    Points
    13 118
    Par défaut
    SendMessage est aussi bloquant ! Est-ce qu'il est émis par un thread secondaire ?

    Je comprends bien ce que tu aimerais faire mais pas ta façon de procéder.
    Es-tu l'auteur de cette bibliothèque ?
    Est-elle thread-ées ?

    Si oui tu en es l'auteur et non la DLL ne lance aucun thread secondaire, "A" devrait être une fonction retournant le résultat.
    Si oui tu en es l'auteur et oui la DLL lance un thread secondaire depuis "A", un TEvent devrait être reset-é dans "A" et set-té à la fin du thread secondaire, "A" attendant que cet Event soit signalé avant de retourner.

    Si tu n'est pas l'auteur de cette DLL et doit obligatoirement attendre sur ce message, je lancerais "B" à la réception de ce message (comme déjà dit).
    Si tu dois obligatoirement mettre en pause cette procédure, pas de miracle, il faut un thread secondaire. Soit pour y déporter la procédure "Test" ou à l'inverse comme récepteur du message (ce qui implique une fenêtre et une boucle de messages dans ce thread). Avec bien sûr un TEvent pour synchroniser tout cela.

  6. #6
    Membre expérimenté
    Avatar de retwas
    Homme Profil pro
    Développeur Java/Delphi
    Inscrit en
    Mars 2010
    Messages
    698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Java/Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 698
    Points : 1 608
    Points
    1 608
    Billets dans le blog
    4
    Par défaut
    Tu peux essayer avec les TTask de l'unité System.Threading.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    FutureString := TTask.Future<string>(function : string
                                         begin
                                            Sleep(3000);
                                            Result := 'Mon message';
                                         end);
     
    Memo1.Lines.Add(FutureString.Value);
    L'appel à Value va bloquer l'application tant que la valeur n'est pas calculé.

  7. #7
    Membre expérimenté
    Avatar de Bloon
    Homme Profil pro
    Consultant Freelance
    Inscrit en
    Avril 2002
    Messages
    467
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant Freelance
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2002
    Messages : 467
    Points : 1 339
    Points
    1 339
    Par défaut
    Bonjour,

    Et du côté de Application.ProcessMessages ? un truc du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    repeat
      Application.ProcessMessages;
    until (top reçu);
    Bloon
    A lire : Les règles du club
    Delphi : La FAQ - Articles

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 453
    Points : 24 864
    Points
    24 864
    Par défaut
    Comme l'indique Andnotor, un Thread secondaire, un WaitMessage et un PeekMessage sur WM_LAUNCH,
    Dommage que ta DLL ne fonctionne pas plutôt avec un CallBack

    Et via ce Thread secondaire, tu peux notifier la Main Thread pour afficher une patience, une barre de progression, un pauvre TAnimate
    Il faut donner l'impression que cela fonctionne et réagit, rien n'est pire pour un utilisateur qu'une application bloque
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    de façon générale "arrêter une procédure" dans le thread principal n'est pas une bonne idée, cela conduit à une application figée que Windows pourrait proposer de tuer.

    soit le code est "bloquant" et il suffit de le placer dans un Thread secondaire.

    soit le code est "non-bloquant" est il suffit de mettre la suite du code dans l’événement déclenché à la fin du premier traitement.

    dans les deux cas, il faut que l'interface utilisateur tienne compte du traitement en cours

    une méthode simple étant de faire appel à une boite de dialogue modale cf
    https://www.developpez.net/forums/d1...-tache-longue/
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

Discussions similaires

  1. [Firebird] Désactiver des Triggers dans une procédure
    Par Cazaux-Moutou-Philippe dans le forum Bases de données
    Réponses: 5
    Dernier message: 28/10/2007, 09h07
  2. Réponses: 2
    Dernier message: 27/06/2006, 15h21
  3. Réponses: 2
    Dernier message: 28/05/2006, 23h31
  4. [format des données avec une procédure stockée]
    Par viny dans le forum PostgreSQL
    Réponses: 7
    Dernier message: 10/03/2005, 13h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo