Un paint qui tient tête... peut être un multithread...

Résolu
parlaciel Messages postés 33 Date d'inscription mardi 25 mars 2008 Statut Membre Dernière intervention 22 décembre 2009 - 31 juil. 2008 à 14:13
parlaciel Messages postés 33 Date d'inscription mardi 25 mars 2008 Statut Membre Dernière intervention 22 décembre 2009 - 1 août 2008 à 14:41
Bonjour à vous!
j'ai posté sur un autre topic il y a de ça peu de temps... mais je ne suis pas sûre d'avoir été lu. Je me permet de reposter car j'ai beau chercher je ne trouve pas de solution et c'est sérieusement bloquant dans l'appli que je suis en train de faire.

Donc désolée si ce post n'a pas lieu d être.

je m'explique: je travaille sur une form qui doit se rafraichir à chaque événement survenant sur un softphone que je scanne via une classe différente. le problème vient bien de là puisque l'erreur cross-thread.. apparait lorsque j'appelle mon paint via la fonction qui scanne.

en d' autres termes  thread1 appelle ma form , thread2 communique avec mon softphone, methode ReceiveMessages() scanne le téléphone, et c'est par cette dernière que je lance mon paint().

j'ai tenté le délégate mais soit je m'y prend comme un pied soit ce n'est pas ce qui est approprié à ce que je veux en faire.

Merci d'avoir accordé de l' attention à mon problème et plus grand merci encore si vous avez un début de solution parsque je suis vraiement perdue!

8 réponses

leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 17
1 août 2008 à 12:19
private delegate void ChangePaintHandler()

private bool m_DisplayButtons = true;

public void ChangePaint()
{
if (this.InvokeRequired)
{
this.Invoke(new ChangePaintHandler(ChangePaint));
}
else
{
m_DisplayButtons = false;
}
}

protected override OnPaint(PaintEventArgs e)
{
//Cest ici que tu dois placer ton code du paint
}
maitredede Messages postés 153 Date d'inscription vendredi 9 août 2002 Statut Membre Dernière intervention 18 septembre 2009
1 août 2008 à 13:01
Bon, dans ton thread qui gère la récup d'infos, tu appelle des fonctions chargées de faire la mise à jour de la form.
Exemple (C#) :

Dans ton thread tu as un SetWindowTitle("Téléphone")

La focntion appelée
public void SetWindowTitle(string newTitre)
{
  frm.Text = newTitre;
}

Ici frm est ta fenêtre.

Ensuite, tu crée un délégate qui a la même signature que ta fonction :
public delegate void TextDelegate(string value);

Après, tu modifie ta fonction comme suit :

public void SetWindowTitle(string newTitre)

{
if(frm.InvokeRequired)
{
Delegate d = new TextDelegate(SetWindowTitle);
frm.Invoke(d, newTitre);
}
else
{

  frm.Text = newTitre;
}

}

Et voilà, tu n'as plus de problème de cross-thread
maitredede Messages postés 153 Date d'inscription vendredi 9 août 2002 Statut Membre Dernière intervention 18 septembre 2009
31 juil. 2008 à 14:32
Salut,

J'ai une piste à te proposer, mais il me manque un exemple de code pour l'appliquer à ton problème...

Si j'ai bien compris, t'a un thread 2 qui récupère des infos et doit mettre à jour ta Form, mais t'a des exceptions de cross thread ?

@+

Dédé
leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 17
31 juil. 2008 à 15:34
tu n'as pas à appeler ton paint! Tu dois soit appeler invalidate, soit refresh (selon que tu veux invalider uniquement une zone ou tout le control), ca va lancer le onpaint tout seul...ensuite il y a un tuto sur le site expliquant les opération cross thread et la manière de résoudre le problème...

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
parlaciel Messages postés 33 Date d'inscription mardi 25 mars 2008 Statut Membre Dernière intervention 22 décembre 2009 1
31 juil. 2008 à 15:58
@ maitredede : oui c' est tout à fait ça, c est ce que je souhaite faire sachant que ma form est un bandeau téléphonique qui doit afficher des boutons ou les faire disparaitre en fonction de l'événement survenu sur le téléphone...et faire remonter différentes infos.

@leprov : je suis débutante en programmation et malheureusement ce que tu dis ne me parle pas des masses... pourrais-tu être plus explicite stp? sinon pour les tuto concernant le cross thread j'ai bien tenté les delegates mais ça me fait toujours l'erreur :'(

merci à vous d'avoir répondu !!
leprov Messages postés 1160 Date d'inscription vendredi 23 juillet 2004 Statut Membre Dernière intervention 21 octobre 2010 17
1 août 2008 à 09:58
donc : Tout d'abord, ton paint ne dois pas être un paint personnalisé fait dans une méthode que tu appelles quand tu veux changer l'affichage. Un test simple, fait ca, puis passe une fenetre par dessus la tienne, tout ce que tu as fait dans ta méthode a part a disparu. Bref, tout code de dessin doit etre dans la méthode onpaint (tu dois override la méthode onpaint de base de ton formulaire).

Donc, tu n'appeles jamais ton paint, mais une méthode perso qui va juste changer une variable qui changera le comportement de ton paint (tu devras donc tester la valeur de cette variable toi meme, et faire le paint en fonction)

Pour les cross thread, Le tuto est clair et simple, il devrait se suffire alui meme
parlaciel Messages postés 33 Date d'inscription mardi 25 mars 2008 Statut Membre Dernière intervention 22 décembre 2009 1
1 août 2008 à 11:12
je vais tenter ce que tu proposes, mon paint() n' est pas le Paint() de la form mais ma fonction  perso... mea culpa.

pour le cross thread , j'ai bien  suivi le tuto mais je ne vois pas comment appeler mon delegate.

en gros ça donne ça:

class FrmBandeau :
public void paint()
{
        ...
}

class ConnexoinReseau()

public delegate void paintFrame();

        public void ReceiveMessages()
        {
            while (isRunning)
            {
                if (tServerProtocol.State != ChannelState.Opened)
                {
                    System.Threading.Thread.Sleep(500);
                    continue;
                }

                IMessage response = tServerProtocol.Receive();

                if (response != null)
                {
                    modele.checkReturnMessage(response);
                }

               FrmBandeau   maFrame = modele.getFrame();
                paintFrame monPaint = new paintFrame(maFrame.paint);
                monPaint();            
            }
        }

c'est sur je dois pas appeler correctement mon delegate pourrais tu m' aider sur la syntaxe stp?
     
             
parlaciel Messages postés 33 Date d'inscription mardi 25 mars 2008 Statut Membre Dernière intervention 22 décembre 2009 1
1 août 2008 à 14:41
un grand merci à vous vous sauvez mon projet!!!!!!!!!

Bisous!!
Rejoignez-nous