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

C++Builder Discussion :

Erreur EInvalidOperation "Le canevas ne permet pas de dessiner"


Sujet :

C++Builder

  1. #1
    bruce-willis
    Invité(e)
    Par défaut Erreur EInvalidOperation "Le canevas ne permet pas de dessiner"
    Beaucoup de problèmes m'est arrivé avec C++ Builder alors que je dois rendre mon prog Lundi pour mes examens.
    Bon! mon prob c'est que je conçois un prog qui effectue des ping sur plusieurs ordinateurs. J'affiche le résultat dans un TImage en utilisant les méthodes du TCanvas. Je mets le programme de traçage dans un Thread.Execute(), ça marche au début mais quand il n'y a que qlq ordi à tester c à d le code est à ses dernières lignes, ça provoque cette exception.

    Que signifie ce EInvalidOperation "..."? Quels sont les cas possibles qui l'affichent?

  2. #2
    Membre actif Avatar de Mattetfamilly
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 182
    Points : 201
    Points
    201
    Par défaut certes mais encore... Fais voir?
    Exécute en mode pas à pas, repère sur quelle ligne cette exception intervient et ensuites donnes nous ton code en nous indiquant où cela plante.
    Il faut voir quelles sont les précédentes opérations sur le Canvas...

    @+
    Mattetfamilly.
    on aura tout vu...
    Mais où est-ce???...
    ------------------------------------------------------
    n'oublies pas les balises [code ][/code ]
    et le Tag

  3. #3
    bruce-willis
    Invité(e)
    Par défaut
    Le problème apparaîssent dans TThread->Execute(). Bizarre! Quelquefois ça marche lorsqu'on lance le .exe directement et ça génère des exceptions dans l'EDI (run avec F9). Quelquefois, l'inverse. Pourquoi?
    Est-ce que je ne dois pas utiliser les méthodes de Canvas dans un thread car il s'agit de ping-er des centaines d'ordi à l'aide d'une boucle, c'est pourquoi j'ai utilisé un thread.

  4. #4
    bruce-willis
    Invité(e)
    Par défaut Extrait de code
    D'abord, je précise qu'il n'y a pas de problème de syntaxe, le ping des PC s'effectue en 2 parties. C'est là que c'est bizarre: les rectangles que je trace avec FillRect() se tracent en dehors de la position designée (pos.x et pos.y). En fait, je travaille avec des type double avant de les traduire en coordonnées écran avec mes fonctions toScreenx() et toScreeny() . Je crois que les contenus de *p{x,y} et *p2{x,y} et des tableaux breezmax[]{x,y} sont modifiés je ne sais pas comment.
    pinggeneral() est une fonction ping que j'ai créée et qui retourne 0 si ping KO et 1 si ping OK.

    Code C++ : 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
    void __fastcall TFourm::Execute()
    {
    try{
    axe *p;
    nagios *p2;
    int i;AnsiString ip_sour;
    int treecount,etat;
    treecount=0;
    //*********PARTIE 1***************
    MessageBox(0,"Réseau A","Scan Computers",MB_OK);
    for(i=1;i<=max;i++){
        sour=false;first=true;
        p=axelist[i];
        p2=axenagios[i];
        while (p!=NULL){
            if (first){
                etat=pinggeneral(p->ipaddress);
                if (etat!=0)
                  {sour=true;Form1->Memo1->Lines->Add(p->ipaddress);
                  Form1->TreeView1->Items->Item[treecount]->ImageIndex=1;Form1->TreeView1->Refresh();
                  Form1->Image2->Canvas->Brush->Color=clRed; Form1->Image2->Canvas->FillRect(Rect(toScreenx(p2->pos.x),toScreeny(p2->pos.y),toScreenx(p2->pos.x)+20,toScreeny(p2->pos.y)+20));
                  }
                  else {sour=false;
                   }
                first=false;
            }
            else{
                if (sour){
                etat=pinggeneral(p->ipaddress);
                if (etat!=0)
                  {sour=true;Form1->Memo1->Lines->Add(p->ipaddress);
                  Form1->TreeView1->Items->Item[treecount]->ImageIndex=1;Form1->TreeView1->Refresh();
                  Form1->Image2->Canvas->Brush->Color=clRed;
                Form1->Image2->Canvas->FillRect(Rect(toScreenx(p2->pos.x),toScreeny(p2->pos.y),toScreenx(p2->pos.x)+20,toScreeny(p2->pos.y)+20));
                  }
                }
            }
            p=p->next;p2=p2->next;
            treecount++;
          }
    }
    //***************PARTIE 2*********************
    MessageBox(0,"Réseau B","Scan Computers",MB_OK);
    treecount=0;
    for(i=1;i<=maxblr;i++){
            if (i==1){
                    etat=pinggeneral(breezmax[i].Adresse);
                    if (etat!=0) {Form1->TreeView3->Items->Item[treecount]->ImageIndex=1;
                    Form1->Image2->Canvas->Brush->Color=clRed;
                    Form1->Image2->Canvas->FillRect(Rect(toScreenx(breezpoint[i].x),toScreeny(breezpoint[i].y),toScreenx(breezpoint[i].x)+20,toScreeny(breezpoint[i].y)+20));
                    }
                    else {i=maxblr+1;//quitter la boucle
                    }
            }
            else{
                    etat=pinggeneral(breezmax[i].Adresse);
                    if (etat!=0) {Form1->TreeView3->Items->Item[treecount]->ImageIndex=1;
                    Form1->Image2->Canvas->Brush->Color=clRed;
                    Form1->Image2->Canvas->FillRect(Rect(toScreenx(breezpoint[i].x),toScreeny(breezpoint[i].y),toScreenx(breezpoint[i].x)+20,toScreeny(breezpoint[i].y)+20));
                    }
            }
    treecount++;
    }
    ShowMessage("Scan terminé !!!");
    //Form1->Image2->Refresh();
    Form1->Image2->Picture->SaveToFile("C:\image-scannetwork.bmp");
    }
    catch (...){
            ShowMessage("ERREUR DURANT LE SCAN");
    }
    }
    Dernière modification par pottiez ; 22/01/2007 à 22h17. Motif: Mise en place des balises [code][/code]. Merci de penser à les mettre la prochaine fois.

  5. #5
    bruce-willis
    Invité(e)
    Par défaut hey oh!!!!!!!!!
    Bon, en attendant que qlq1 me réponde!

    Le problème ne fait pas en fait de l'utilisation de TImage mais du Thread même.
    Car quand j'enleve Image2 et il ne reste que TreeView1, l'exception apparaisse toujours.

    Alors quelle est la solution les ami(e)s? Est-ce que je ne dois pas tracer quoique ce soit dans un thread

  6. #6
    Membre actif Avatar de Mattetfamilly
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    182
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 182
    Points : 201
    Points
    201
    Par défaut
    As tu fait un mode pas à pas comme demandé?
    Peux tu préciser sur quelle ligne cela provoque une exception?

    @+
    Mattetfamilly.
    on aura tout vu...
    Mais où est-ce???...
    ------------------------------------------------------
    n'oublies pas les balises [code ][/code ]
    et le Tag

  7. #7
    bruce-willis
    Invité(e)
    Par défaut
    Bon! Mattetfamily!!

    On ne peut pas vraiment identifié le problème par une exécution pas à pas.
    Mais l'exception a disparu quand j'ai remplacé ShowMessage() par MessageBox() l'API Windows. Je ne comprends quelle dent le prog a contre ShowMessage?

    Un autre prob est aussi à remarquer, celui du changement du contenu des tableaux que j'utilise. Encore problème de thread?

  8. #8
    bruce-willis
    Invité(e)
    Par défaut Mes respect à tous
    Excusez moi de ne pas avoir utilisé les balises

    En fait, j'ai pas bien lu jusqu'à la fin les règles, maintenant c'est fait

    OKAY A TOUS!

  9. #9
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut Merci à tous
    Je vais délester cette discussion
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  10. #10
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 389
    Points : 1 776
    Points
    1 776
    Par défaut
    Salut !

    Il faudrait se plonger dans la littérature...
    A mon avis, cette exception est lancée parce que le Canvas est solicité par deux processus simultanéement.
    Par exemple, le Canvas n'a pas terminé son opération qu'on lui demande d'en exécuter une autre... d'où le conflit possible !
    Mais ... je n'en suis pas certain ... !

    A plus !

  11. #11
    bruce-willis
    Invité(e)
    Par défaut Pour rakoto15
    Et cher ami Rakoto15, ce n'est pas à toi de délester cette discussion.

    La discussion continue !!!

  12. #12
    Membre confirmé

    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    531
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 531
    Points : 537
    Points
    537
    Par défaut
    merci henderson pour cette piste.
    Ayant actuellement ce PB suite à changement de serveur (beaucoup plus rapide) alors qu'avant sur celui qui ramait pas ce PB.

    Merci

  13. #13
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Points : 578
    Points
    578
    Par défaut
    Bonjour

    Il faudrait que tu cases les bouts de code qui touchent à Form1 dans des méthodes appelées via un Synchronize.

    Exemple:
    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
     
    void __fastcall TFourm::Execute()
    {
    ...
      if (etat!=0)
      {
        sour=true;
        Synchronize(SyncMajForm);
      }
      else {sour=false;
    ....
    }
     
    void __fastcall TFourm::SyncMajForm(void)
    {
      // => p, p2 et treecount membres de la classe TFourm
      Form1->Memo1->Lines->Add(p->ipaddress);
      Form1->TreeView1->Items->Item[treecount]->ImageIndex=1;
      Form1->TreeView1->Refresh();
      Form1->Image2->Canvas->Brush->Color=clRed;
      Form1->Image2->Canvas->FillRect(Rect(toScreenx(p2->pos.x),toScreeny(p2->pos.y),toScreenx(p2->pos.x)+20,toScreeny(p2->pos.y)+20));
    }
    A++

  14. #14
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 389
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 389
    Points : 1 776
    Points
    1 776
    Par défaut
    Salut !

    Dans ma version BCB3 Pro, TCanvas::LockCount , TCanvas::Lock() et TCanvas::Unlock() :

    Extrait de l'aide :

    Dans des applications multithread utilisant Lock pour protéger un canevas, tous les appels utilisant le canevais doivent être protégés par un appel à Lock. Tout thread ne verrouillant pas le canevas avant de l'utiliser introduire des problèmes potentiels.

    Comme Lock empêche les autres threads de s'exécuter, elle peut avoir un effet négatif sur les performances. N'appelez Lock que s'il y a un risque qu'une autre thread interfère avec l'utilisation du canevas.
    D'où mon idée initiale de vous conseiller de faire un peu de lecture !

    A plus !

  15. #15
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Points : 578
    Points
    578
    Par défaut
    Hello

    Tiens, j'avais oublié la synchro directement sur le TCanvas!
    Attention toutefois au fait que dans le cas initial, Memo1 et Treeview1 doivent être considérés comme des ressources partagées par le thread principal de la VCL et le second thread, et qu'à ce titre l'accès à Memo1 et Treeview1 doit également être protégé depuis le second thread....
    Même si le problème de l'EInvalidOperation peut être levé par le lock sur TCanvas, tous les pépins potentiels ne sont pas pour autant supprimés... (voir par exemple l'appli SortThread fournie avec Delphi/BCB)

    A+

Discussions similaires

  1. Le canevas ne permet pas de dessiner / Citrix
    Par zaclo dans le forum Langage
    Réponses: 0
    Dernier message: 22/02/2011, 17h48
  2. Message d'erreur "Le canvas ne permet pas de dessiner"
    Par Gilbert Geyer dans le forum Langage
    Réponses: 3
    Dernier message: 08/11/2007, 10h30
  3. erreur 1722 le serveur RPC n'est pas disponible
    Par StyleXP dans le forum Windows XP
    Réponses: 1
    Dernier message: 13/11/2005, 20h23
  4. [Info]Eclipse ne permet pas de changer de compilateur
    Par albertl dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 08/02/2005, 19h00

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