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 :

VCL et Treads [Non suivi]


Sujet :

C++Builder

  1. #1
    say
    say est déconnecté
    Membre Expert
    Avatar de say
    Profil pro
    Inscrit en
    Août 2002
    Messages
    1 176
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 1 176
    Par défaut VCL et Treads
    Bonjour,

    je patauge un peu avec les thread.
    voila le contexte :
    j'ai une fonction d'export d'un Tdataset vers Excel. ça fonctionne bien mais ça peut être très long puisque ça parcourt l'ensemble du dataset.
    j'aurais donc voulu placer cet export dans un tread à part avec une progressbar eventuellement mais ce n'est pas indispensable
    Créer le thread pose pas trop de problème, mais cela fige l'application.

    Et ce malgré l'utilisation de Synchronize.

    y'a-t-il une démarche particulière à suivre? un bon tuto sur les threads?
    J'ai cherché mais rien de très concluant.

    merci d'avance

  2. #2
    Membre confirmé Avatar de jagboys
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    166
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 166
    Par défaut Threads
    Bonjour,
    Tu peux nous poster un peux de code ?
    Focntion thread, l'appel du thread ....

  3. #3
    say
    say est déconnecté
    Membre Expert
    Avatar de say
    Profil pro
    Inscrit en
    Août 2002
    Messages
    1 176
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 1 176
    Par défaut
    vi, c possible

    l'execute du thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    _progressbar->ProgressBar->Position = 0;
      Synchronize(ExportTo);
    _progressbar est une form membre du thread instanciée ds le constructeur de celui-ci.

    la fonction d'export vers Excel :
    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
    TSaveDialog* TSD_SaveExcel = new TSaveDialog(Welcome);
    TSD_SaveExcel->InitialDir = ".\\Exports";
    TSD_SaveExcel->Filter = "Fichiers Excel (*.xls)|*.XLS";
    TSD_SaveExcel->Title = "Exporter vers...";
    ShowMessage("bouh");
    if (TSD_SaveExcel->Execute())
            {
                bool QuitExcelToEnd;
                Variant vFilename, vSaveChanges;
                Variant vMSExcel, vXLWorkbook, vXLWorkbooks, vWorksheet, vRange, vCell, vValue, vColl;
                int NumLine = 1;  // contient le numéro de la ligne où l'on commence à écrire les données sous Excel
                int NumCol = 65;  // "A" code ASCII 65 (réf. à la 1ère colonne sous Excel)
                try
                {
                   vMSExcel = Variant::GetActiveObject("Excel.Application");   // Capture d'une instance existante d'Excel
                }
                // Si Excel n'est pas déjà ouvert, une exception est levée ...
                catch(EOleSysError& e )
                {
                   vMSExcel = Variant::CreateObject("Excel.Application");      // Si Excel n'est pas lancé, on l'exécute
                }
                vMSExcel.OlePropertySet("Visible", true);                   // Si Excel était déjà lancé, on le laisse visible
                QuitExcelToEnd = false;                                     // On ne fermera pas Excel après le traitement.
     
                vXLWorkbooks = vMSExcel.OlePropertyGet("Workbooks");           // Récupération du pointeur vers la collection des Workbooks
                vXLWorkbook = vXLWorkbooks.OleFunction("Add");                 // Ajout d'un nouveau Workbook à la collection
                vWorksheet = vXLWorkbook.OlePropertyGet("Worksheets","Feuil1");   // On active le sheet par défaut "Feuil1"
     
                _source->First();                  // On se place sur le 1er enregistrement de la requête
                for (int j = 0; j < _source->FieldCount; j++)     // ... et son nb de champs pr libellés colonnes
                {
                  AnsiString Ref = "";                               // contiendra la référence à la cellule Excel, i.e. "A1"
                  Ref.cat_sprintf("%c%d", NumCol+j, NumLine);      // donne "A1" pour 65 et 1
                  vRange = StringToOleStr(Ref);                      // Ref est converti en Range (bien qu'il s'agisse toujours d'un Variant)
                  vCell = vWorksheet.OlePropertyGet("Range", vRange);// récupération du pointeur vers la cellule sélectionnée ("A1")
                  vValue = StringToOleStr(_source->Fields->Fields[j]->DisplayName);
                  vCell.OlePropertySet("Value", vValue);             // affectation de la valeur de la requête à la cellule référencée ("A1")
                }
                NumLine = 2;                    //on se place sur la ligne suivant les libellés...
                for (int t = 0; t < [color=red]_source[/color]->RecordCount; t++)       // nb d'enregistrements de la requête
                {
                   for (int i = 0; i < _source->FieldCount; i++)     // ... et son nb de champs
                   {
                      AnsiString Ref = "";                               // contiendra la référence à la cellule Excel, i.e. "A1"
                      Ref.cat_sprintf("%c%d", NumCol+i, NumLine+t);      // donne "A1" pour 65 et 1
                      vRange = StringToOleStr(Ref);                      // Ref est converti en Range (bien qu'il s'agisse toujours d'un Variant)
                      vCell = vWorksheet.OlePropertyGet("Range", vRange);// récupération du pointeur vers la cellule sélectionnée ("A1")
                      vValue = StringToOleStr(_source->Fields->Fields[i]->AsString);
                      vCell.OlePropertySet("Value", vValue);             // affectation de la valeur de la requête à la cellule référencée ("A1")
                   }
                   _source->Next();             // on passe à l'enregistrement suivant
                   [color=red]_progressbar->ProgressBar->StepBy(count);
                    count = count + 1;[/color]            }
     
                 vFilename = StringToOleStr(TSD_SaveExcel->FileName);   // le nom de fichier de la SaveDialog est converti au format OLE
                vMSExcel.OlePropertySet("DisplayAlerts", false);         // on désactive les DisplayAlerts d'Excel (pour éviter les messages d'overwriting d'Excel)
                vXLWorkbook.OleProcedure("Saveas", vFilename);           // sauvegarde du fichier sous le nom préalablement sélectionné
                vSaveChanges = true;    // true : modif save, false : not save, Unassigned : demande à l'utilisateur
                //vXLWorkbook.OleFunction("Close", vSaveChanges, vFilename);  // fermeture du classeur qui a recueilli les données
                vMSExcel.OlePropertySet("DisplayAlerts", true);          // réactivation des DisplayAlerts
                if (QuitExcelToEnd)                                      // Excel doit-il être fermé ?
                {                                                        // Si oui ...
                   vMSExcel.OleFunction("Quit");                         // on le ferme
                   vMSExcel = Unassigned;                                // ... et le pointeur de son instance est réinitialisé
                }
             }
    delete TSD_SaveExcel;
    Une fonction d'export trouvée sur Developpez.
    _source est un dataset* membre du thread, initialisé à la construction.

  4. #4
    say
    say est déconnecté
    Membre Expert
    Avatar de say
    Profil pro
    Inscrit en
    Août 2002
    Messages
    1 176
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 1 176
    Par défaut
    Bonjour..
    ça n'inspire personne. je suis surpris que personne n'ait déjà rencontré ce problème.
    j'ai bien regardé du côté du forum delphi mais rien de très concluant.

  5. #5
    say
    say est déconnecté
    Membre Expert
    Avatar de say
    Profil pro
    Inscrit en
    Août 2002
    Messages
    1 176
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 1 176
    Par défaut
    bon, je vais essayer d'en spécifier plus...
    en fait quand je mets le code de la fonction ExportTo dans Execute, le thread s'arrête sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vMSExcel = Variant::GetActiveObject("Excel.Application");
    getactive est considéré comme faisant partie de la VCL?

    franchement, je suis paumé..;

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 62
    Par défaut Re: VCL et Treads
    Citation Envoyé par say
    Créer le thread pose pas trop de problème, mais cela fige l'application.
    Et ce malgré l'utilisation de Synchronize.
    Ce n'est pas "malgré" qu'il faut utiliser mais "à cause".
    Si tu avais eu la bonne idée de consulter l'aide de Synchronize, tu aurais lu ceci :
    Description

    Synchronize causes the call specified by Method to be executed using the main VCL thread, thereby avoiding multi-thread conflicts. If you are unsure whether a method call is thread-safe, call it from within the Synchronize method to ensure that it executes in the main VCL thread.

    Execution of the thread current is suspended while Method executes in the main VCL thread.
    Le thread que tu as créé ne sert à rien, puisqu'il attend gentillment que le main thread (le thread d'affichage) réalise l'exporte.
    Et pendant ce temps, l'IHM est figée.

    Pour mettre à jour une progress bar ou tout autre objet VCL, depuis un thread secondaire, il faut utiliser le mécanisme des messages windows (PostMessage).

  7. #7
    say
    say est déconnecté
    Membre Expert
    Avatar de say
    Profil pro
    Inscrit en
    Août 2002
    Messages
    1 176
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 1 176
    Par défaut
    Citation Envoyé par Troll
    Si tu avais eu la bonne idée de consulter l'aide de Synchronize, tu aurais lu ceci :
    Tu te doutes bien que c'est ce que j'ai fait, j'ai également précisé que j'étais allé sur le forum Delphi...
    Je comprends bien que le synchronize rend la main au thread vcl.

    [la progressbar c'est pour faire joli, je regarderais du côté des messages windows, cependant, si le composant VCL fait parti du thread ça ne pose aucun problème,ce qui est mon cas et la progressbar fonctionne aussi bien dans l'exécute et qu'au travers du synchronize],

    Cependant, en retirant ces traitements VCL ,le simplement traitement d'export ne fonctionne pas comme je le voudrais. l'idée, c'est que cela tourne alors qu'on peut continuer à bosser (dans le cas d'export volumineux). Or si je place le traitement dans le synchronize (on se comprend), forcèment ça fige. Mais si je le place dans l'exécute, il ne se passe rien...mais pas le GetActiveObjet....
    je demandais donc si cela faisait partie de la VCL.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 62
    Par défaut
    Citation Envoyé par say
    Cependant, en retirant ces traitements VCL ,le simplement traitement d'export ne fonctionne pas comme je le voudrais. l'idée, c'est que cela tourne alors qu'on peut continuer à bosser (dans le cas d'export volumineux). Or si je place le traitement dans le synchronize (on se comprend), forcèment ça fige. Mais si je le place dans l'exécute, il ne se passe rien...mais pas le GetActiveObjet....
    je demandais donc si cela faisait partie de la VCL.
    OK, je n'avais pas bien compris.
    Effectivement il ya peut-être des contraintes avec l'utilisation d'objet com et les thread, mais je ne les connais pas.

Discussions similaires

  1. [VCL] Comment faire une barre d'outils skinable comme FireFox ?
    Par DarkChamallo dans le forum Composants VCL
    Réponses: 23
    Dernier message: 07/05/2008, 18h03
  2. [VCL][TListView]Montrer une ligne à l'écran
    Par ptitbob dans le forum Delphi
    Réponses: 4
    Dernier message: 23/07/2007, 16h35
  3. [VCL]toolbar verticale
    Par mandale dans le forum Composants VCL
    Réponses: 5
    Dernier message: 01/10/2004, 14h26
  4. [VCL] Scroller un contrôle par code
    Par sbeu dans le forum Composants VCL
    Réponses: 3
    Dernier message: 31/03/2004, 10h39
  5. VCL de Crystal Report pour utilisation dans C++Builder
    Par dibak dans le forum C++Builder
    Réponses: 4
    Dernier message: 16/02/2004, 17h04

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