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

Langage Delphi Discussion :

Message loop dans un thread


Sujet :

Langage Delphi

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 831
    Points : 13 579
    Points
    13 579
    Par défaut Message loop dans un thread
    Salut à tous !

    J'aimerais mettre en place une synchronisation sur les modifications du presse-papiers entre différents threads.
    La création de la fenêtre et l'ajout du listener ne semblent pas poser de problème, mais je ne reçois rien...

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    constructor TClipboardSync.Create(aSync: TEvent);
    begin
      inherited Create;
     
      Sync := aSync;
      Sync.ResetEvent;
    end;
     
    procedure TClipboardSync.Execute;
    var
      Msg      :TMsg;
      Wnd      :hWnd;
      NextWnd  :hWnd;
      WndClass :TWndClass;
     
    begin
      try
        //Création de la fenêtre
        ZeroMemory(@WndClass, SizeOf(WndClass));
        WndClass.lpfnWndProc   := @DefWindowProc;
        WndClass.hInstance     := hInstance;
        WndClass.lpszClassName := 'TIClipboardSync';
     
        if Windows.RegisterClass(WndClass) <> 0 then
        try
          Wnd := CreateWindow(WndClass.lpszClassName, nil, WS_POPUP, 0, 0, 0, 0, 0, 0, HInstance, nil);
     
          if Wnd <> 0 then
          try
            //Mise en place du Listener en fonction de l'OS
            if GetWindowsVersion < wvVista
            then NextWnd := SetClipboardViewer(Wnd)
            else if not AddClipboardFormatListener(Wnd) then Exit;
     
            //Message loop
            while not Terminated do
            begin
              if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
                with Msg do
                  case Message of
                    // XP
                    WM_CHANGECBCHAIN:   begin
                                          if WParam = NextWnd
                                          then NextWnd := LParam
                                          else if NextWnd <> 0
                                               then SendMessage(NextWnd, Message, WParam, LParam);
                                        end;
     
                    WM_DRAWCLIPBOARD:   begin
                                          if NextWnd <> 0 then
                                            SendMessage(NextWnd, Message, WParam, LParam);
     
                                          Terminate;
                                        end;
     
                    // Vista+
                    WM_CLIPBOARDUPDATE: Terminate;
     
                    //Autres...
                    else                begin
                                          TranslateMessage(Msg);
                                          DispatchMessage(Msg);
                                        end;
                  end;
     
              Sleep(10);
            end;
     
          finally
            if GetWindowsVersion < wvVista then
              ChangeClipboardChain(Wnd, NextWnd);
     
            DestroyWindow(Wnd);
          end;
     
        finally
          Windows.UnregisterClass(WndClass.lpszClassName, HInstance);
        end;
     
      finally
        Sync.SetEvent;
      end;
    end;
    Si vous aviez une piste !
    Merci.

  2. #2
    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 : 55
    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 457
    Points
    28 457
    Par défaut
    je ne comprend pas bien ce que tu cherches à faire...ne serait-il pas plus simple de capter ces messages dans le thread principal et de déclencher un Event pour l'ensemble de tes threads concernés ?

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 710
    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 710
    Points : 25 593
    Points
    25 593
    Par défaut
    as-tu essayé d'utilisé ta fameuse classe comme receveur des messages ?
    0 devrait choper toutes les fenêtres crées par le thread, c'est vrai que cela devrait fonctionner

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if PeekMessage(Msg, Wnd, 0, 0, PM_REMOVE) then
    Sinon, tu utilises "DefWindowProc", essaye d'affecter ta propre fonction et de gérer la reception des messages directement dans la lpfnWndProc

    Après, un autre approche est peut-être possible, dans les threads au lieu de mettre directement dans le Clipboard, tu ajoutes à la donnée à une ThreadList
    Dans un Thread ou un Timer dans le Main, tu parcours la ThreadList et tu manipule le Clipboard à cet unique endroit !

    Sinon, utilise une Section Critique lors de l'utilisation du Clipboard si tu veux le protéger en écriture \ lecture

  4. #4
    Membre chevronné Avatar de chaplin
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 215
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 215
    Points : 1 819
    Points
    1 819
    Par défaut
    A priori, WM_DRAWCLIPBOARD est envoyé dans la fenêtre enregistré avec la fonction SetClipboardViewer. Cette fenêtre possède la méthode qui traite le message DRAWCLIPBOARD et donc répond aux événements du presse-papier.

    Edit: Shailetroll est plus rapide que l'éclair c'est équivalent à sa question :
    as-tu essayé d'utilisé ta fameuse classe comme receveur des messages ?

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 831
    Points : 13 579
    Points
    13 579
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    je ne comprend pas bien ce que tu cherches à faire
    Pour l'instant, c'est un essai de récupération de texte à travers le presse-papiers en simulant les touches claviers.
    Le thread principal balance les touches quelque soit l'application au premier plan et se met en attente jusqu'à ce que le Clipboard soit rempli. Donc plus de gestion possible. Bien sûr, je pourrait découper tout ça, mais pas envie pour l'instant.

    @ShaiLeTroll,
    @chaplin,


    J'ai un peu tout essayé, y compris SetWindowLong(Wnd, GWL_WNDPROC, Longint(MakeObjectInstance(WndProc))); (même si c'est pas thread-safe )

    Bon, mes derniers tests en ajoutant un message perso (WM_USER) montre que la boucle fonctionne ! J'ai donc quant même un problème avec l'ajout du listener (sous XP, Seven pas encore testé)...

    Edit:
    Ça fonctionne sous Seven. Plus qu'à voir pourquoi SetClipboardViewer ne passe pas !

Discussions similaires

  1. Réponses: 5
    Dernier message: 08/04/2013, 23h39
  2. Boucle message dans un thread
    Par jhonnyBravo dans le forum Threads & Processus
    Réponses: 3
    Dernier message: 27/07/2007, 12h22
  3. message loop et threads
    Par d'Oursse dans le forum Windows
    Réponses: 9
    Dernier message: 23/06/2007, 17h06
  4. Gestion des message windows dans les threads
    Par billyboy dans le forum Windows
    Réponses: 5
    Dernier message: 06/10/2003, 18h25

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