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 :

Mesurer une temporisation a l'aide de QueryPerformance [Langage/Algorithme]


Sujet :

C++Builder

  1. #1
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut Mesurer une temporisation a l'aide de QueryPerformance
    Bonjours
    A la suite d'un post sur le Forun Delphi, et les reponses faites par ShaiLeTroll, j'ai teste QueryPerformance, apres recherche sur le Forum C++Builder je n'ai rien trouve, je poste pour l'exemple un code qui est je pense fonctionnel, j'ai un doute sur les testes dans la derniere partie du programme.
    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
     
    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    _LARGE_INTEGER BeginTime,EndTime,TickPerSec;
    int tempo;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
         : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    tempo = 0;
    if (!QueryPerformanceFrequency(&TickPerSec)) return;
    QueryPerformanceCounter(&BeginTime);
    // placer le Delay a tester
    // Sleep(100); // millisecondes
    // ou
    for(int i = 1; i <= 5000000;i++)
    {
    tempo++;
    }
    Edit1->Text = tempo;
    QueryPerformanceCounter(&EndTime);
    double Delay1 = (double)(&EndTime.QuadPart - &BeginTime.QuadPart) / TickPerSec.QuadPart * 1000;
    Edit2->Text = Delay1;
    double Delay = (double)(&EndTime.QuadPart - &BeginTime.QuadPart) / TickPerSec.QuadPart;
    // la je ne suis pas sur des resultats
    if (1E-9 < Delay) //if (t <= 1E-9)
         Edit3->Text = ("Ghz / ns ") + (FloatToStr(Delay / 1e9));
    else if (1E-6 < Delay) //else if (t <= 1E-6)
         Edit3->Text = ("Mhz / micro s ") + (FloatToStr(Delay / 1e6));
    else if (1E-3 < Delay) //else if (t <= 1E-3)
         Edit3->Text = ("Khz / ms ") + (FloatToStr(Delay / 1e3));
    else
         Edit3->Text = ("Hz / s ") + (FloatToStr(Delay));
    }
    //---------------------------------------------------------------------------

  2. #2
    Membre éprouvé
    Avatar de Freeze
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 131
    Par défaut
    Oui effectivement, tu t'es un peu embrouillé les pinceaux, voici ce que j'ai écrit, et comme ça m'intéresse aussi, j'ai comparé les performances avec GetTickCount() pour voir...

    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
       _LARGE_INTEGER BeginTime,EndTime,TickPerSec;
     
       // retourne la fréquence du compteur haute performance
       if (!QueryPerformanceFrequency(&TickPerSec))
          return;
       else
          Edit1->Text = static_cast<double>(TickPerSec.QuadPart);
     
       // prise de référence de début
       QueryPerformanceCounter(&BeginTime);
       double temp=GetTickCount();
     
       int tempo=0;
       for(int i = 1; i <= 5000000;i++)
          tempo++;
     
       // prise de référence de fin
       QueryPerformanceCounter(&EndTime); 
       Edit4->Text = (AnsiString)(GetTickCount()-temp);   
     
       // nombre de comptages entre début et fin
       double Delay1 = static_cast<double>(EndTime.QuadPart - BeginTime.QuadPart);
       Edit2->Text = Delay1;
     
       // conversion en seconde en divisant le nombre de comptages par la fréquence de comptage
       double Delay = Delay1 / TickPerSec.QuadPart;
       Edit3->Text = Delay;
     
       // traitement final du temps réel entre le début et la fin
       if (Delay<1E-6)
            Edit5->Text = ("en ns ") + (FloatToStr(Delay * 1e9));
       else if (Delay<1E-3)
            Edit5->Text = ("en µs ") + (FloatToStr(Delay * 1e6));
       else if (Delay<1)
            Edit5->Text = ("en ms ") + (FloatToStr(Delay * 1e3));
       else
            Edit5->Text = ("en s ") + (FloatToStr(Delay));
    Pour cette action, j'obtiens une moyenne de temps de 28,86 ms pour le compteur haute performance et 31 ms pour le GetTickCount(), ce qui fait quand même une marge différentielle de près de 8%.

  3. #3
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 017
    Par défaut
    Blondelle, j'ai évoqué QueryPerformance pour mesurer le temps des fonctions que tu utilisais pour comprendre la contre-performance de ton code

    ce n'était pas pour faire une boucle de patience mais pour voir là ou ton code perdait du temps pour arriver à 12 minutes !

    Citation Envoyé par ShaiLeTroll Voir le message
    Il te faut mesurer avec QueryPerformanceCounter le temps de chaque étape
    il fallait comprendre
    Code pascal : 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
     
     
     
    TLargeInteger FStartTick, FTickPerSec, FEndTick;
     
    repeat
      {Mise en rotation des moteurs}
          FStartTick = GetTickCounter(FTickPerSec);
     
          DLPortOCX1.WritePort(AB, choix_sens);
     
          FEndTick = GetTickCounter(FTickPerSec);
          OutputDebugStringA(AnsiString("WritePort sens " + IntToStr(GetTickElapsedTime(FStartTick, FEndTick, FTickPerSec))).c_str());
     
          FStartTick = GetTickCounter(FTickPerSec);
     
          DLPortOCX1.WritePort(AB, choix_sens + choix_moteur);
     
          OutputDebugStringA(AnsiString("WritePort sens moteur" + IntToStr(GetTickElapsedTime(FStartTick, FEndTick, FTickPerSec))).c_str());
     
    ...
     
    until (inc_pas = choix_pas) or (aru = true);

    J'ai ces fonctions en C++Builder pour mesurer en ms !
    les versions similaires en Delphi
    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
     
    //---------------------------------------------------------------------------
    TLargeInteger GetTickCounter(TLargeInteger &ATickPerSec)
    {
      TLargeInteger Result;
     
      if (ATickPerSec.QuadPart <= 0)
        if ( ! QueryPerformanceFrequency(&ATickPerSec))
          ATickPerSec.QuadPart = 1000; // GetTickCount c'est 1000 ms pour 1 seconde
     
      if (ATickPerSec.QuadPart != 1000)
        if ( ! QueryPerformanceCounter(&Result))
          ATickPerSec.QuadPart = 1000; // GetTickCount c'est 1000 ms pour 1 seconde
     
      if (ATickPerSec.QuadPart == 1000)
        Result.QuadPart = GetTickCount(); // GetTickCount64 n'existe que depuis Win 6.0 !
     
      return Result;
    }
     
    //---------------------------------------------------------------------------
    unsigned GetTickElapsedTime(TLargeInteger &ABeginTick, TLargeInteger &AEndTick, TLargeInteger &ATickPerSec)
    {
      unsigned Result = 0;
     
      // Avec QueryPerformanceCounter, cela dépend du processeur, 100 ans pour 3Ghz, il ne devrait pas y avoir de problème
      // Si cela utilise GetTickCount, Bug des 49,7 jours, je le gère comme je peux !
     
      if ((ABeginTick.QuadPart > 0) && (AEndTick.QuadPart > 0))
      {
        // Si ABeginTick est supérieur à AEndTick, il y a eu un tour complet de Tick entre temps !
        if (ABeginTick.QuadPart > AEndTick.QuadPart)
          ABeginTick.QuadPart = 1; // cela surestimera le temps écoulé mais c'est mieux qu'un écart négatif !
     
        if (ATickPerSec.QuadPart)
          Result = (AEndTick.QuadPart - ABeginTick.QuadPart) / ATickPerSec.QuadPart;
      }
     
      return Result;
    }
    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

  4. #4
    Membre éprouvé
    Avatar de Freeze
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 131
    Par défaut
    Salut,

    Comme j'aime bien encapsuler, j'ai fait une petite classe pour mettre tout ça, c'est la classe TChronometre qui utilise le compteur haute performance s'il est disponible sinon il utilise le bon vieux GetTickCount() en ms.

    voilà ce que ça donne pour l'exemple précédent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
       TChronometre *t=new TChronometre();
       Edit1->Text = t->Frequence;
       t->Start();
     
       int tempo=0;
       for(int i = 1; i <= 5000000;i++)
          tempo++;
     
       t->Stop();
       Edit2->Text = t->Compte;
       Edit3->Text= t->Temps;
       Edit5->Text = t->TempsFormate;
       delete t;
    le fichier .cpp :

    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
    //---------------------------------------------------------------------------
    #include "Chronometre.h"
    //---------------------------------------------------------------------------
    // Constructeur
    //---------------------------------------------------------------------------
    TChronometre::TChronometre(void)
    {
       FHighPerformance=QueryPerformanceFrequency(&FFrequence);
    }
    //---------------------------------------------------------------------------
    // Destructeur
    //---------------------------------------------------------------------------
    TChronometre::~TChronometre(void)
    {
    }
    //---------------------------------------------------------------------------
    // Start
    //---------------------------------------------------------------------------
    void TChronometre::Start(void)
    {
       if (FHighPerformance)
          QueryPerformanceCounter(&FDepart);
       else
          FDepartTickCount=GetTickCount();
    }
    //---------------------------------------------------------------------------
    // Stop
    //---------------------------------------------------------------------------
    void TChronometre::Stop(void)
    {
       if (FHighPerformance)
          QueryPerformanceCounter(&FArrivee);
       else
          FArriveeTickCount=GetTickCount();
    }
    //---------------------------------------------------------------------------
    // GetFrequence
    //---------------------------------------------------------------------------
    double TChronometre::GetFrequence(void)
    {
       if (FHighPerformance)
          return (static_cast<double>(FFrequence.QuadPart));
       else
          return FREQUENCETICKCOUNT;
    }
    //---------------------------------------------------------------------------
    // GetCompte
    //---------------------------------------------------------------------------
    double TChronometre::GetCompte(void)
    {
       if (FHighPerformance)
          return (static_cast<double>(FArrivee.QuadPart-FDepart.QuadPart));
       else
          return (FArriveeTickCount-FDepartTickCount);
    }
    //---------------------------------------------------------------------------
    // GetTemps
    //---------------------------------------------------------------------------
    double TChronometre::GetTemps(void)
    {
       return (GetCompte()/GetFrequence());
    }
    //---------------------------------------------------------------------------
    // GetTempsFormate
    //---------------------------------------------------------------------------
    AnsiString TChronometre::GetTempsFormate(void)
    {
       double temps=GetTemps();
     
       if (temps<1E-6)
            return (FormatFloat("0.000",temps * 1E9)+" ns");
       else if (temps<1E-3)
            return (FormatFloat("0.000",temps * 1E6)+" µs");
       else if (temps<1)
            return (FormatFloat("0.000",temps * 1E3)+" ms");
       else
            return (FormatFloat("0.000",temps)+" s");
    }
    //---------------------------------------------------------------------------
    et le .h

    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
    //---------------------------------------------------------------------------
    #ifndef ChronometreH
    #define ChronometreH
    //---------------------------------------------------------------------------
    #include <vcl.h>
    //---------------------------------------------------------------------------
    #define FREQUENCETICKCOUNT 1000
    //---------------------------------------------------------------------------
    class TChronometre
    {
       private:      // déclarations privées
     
          bool FHighPerformance;
     
          _LARGE_INTEGER FDepart;
          _LARGE_INTEGER FArrivee;
          _LARGE_INTEGER FFrequence;
     
          double FDepartTickCount;
          double FArriveeTickCount;
     
          double GetFrequence(void);
          double GetTemps(void);
          double GetCompte(void);
          AnsiString GetTempsFormate(void);
     
       public:       // déclarations publiques
     
          __property double Frequence = {read=GetFrequence};
          __property double Temps = {read=GetTemps};
          __property double Compte = {read=GetCompte};
          __property AnsiString TempsFormate = {read=GetTempsFormate};
     
          void Start(void);
          void Stop(void);
     
          // Constructeur
          TChronometre(void);
     
          // Destructeur
          ~TChronometre(void);
    };
    //---------------------------------------------------------------------------
    #endif

  5. #5
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Merci Freeze et ShaiLeTroll pour vos reponses

    ShaiLeTroll j'avais bien compris pour tes explications, mais a la suite de mes testes je m'etais rendu compte que le probleme venait des temporisations du soft.

    Freeze il me semblait bien qu'il y avait un probleme dans le code, mais je ne voyais pas ou, elle est super ta classe.

    Pour info je numerise une fraiseuse d'etabli j'ai recupere un programme de commande avec le source, celui-ci ete prevu pour fonctionner avec Windows 95-98, pour XP je passe par DLport, bien sur au debut cela ne fonctionnait pas , apres avoir utilise des Sleep en temporisation le temps de fonctionnement etait trop long, j'ai donc tente des boucles de temporisation, mais celles ci doivent etre variable, pour avoir un fonctionnement correcte il me falait savoir le temps des temporisations.

    Comme QueryPerformance ne faisait l'objet d'aucun Post sur ce Forum j'ai poste dans le but de rendre service a d'autre qui connaissent des problemes similaires

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 017
    Par défaut
    Citation Envoyé par Freeze Voir le message
    Comme j'aime bien encapsulé, j'ai fait une petite classe pour mettre tout ça, c'est la classe TChronometre
    Je n'ai jamais pris le temps de le faire pourtant c'est aussi mon habitude, cela devrait être un objet commun, et oui ta classe est fort sympa !

    Citation Envoyé par blondelle Voir le message
    ShaiLeTroll j'avais bien compris pour tes explications, mais a la suite de mes testes je m'etais rendu compte que le probleme venait des temporisations du soft.
    Ok, un grand nombre d'itération à faire trop de Sleep(1) !
    En Delphi, je me suis fait WaitSleeping, conçu pour attendre sans saturer le CPU le remplissage aynchrone d'un TWebBrowser

    Tu devrais te faire une fonction équivalente genre MicroSleep en utilisant TChronometre + Sleep(0)
    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

  7. #7
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Merci ShaiLeTroll
    Je fais les temporisations en tenant compte de tes sugestions et remarques, de plus avant essais j'ai une evaluation des temps d'attente.

    Freeze ta classe ainsi que ton code previsualisation impression devraient etre proposees en sources sur le Forum, desole de te demander du boulot supplementaire

  8. #8
    Membre éprouvé
    Avatar de Freeze
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    131
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 131
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Tu devrais te faire une fonction équivalente genre MicroSleep en utilisant TChronometre + Sleep(0)
    effectivement, une simple fonction ajoutée dans TChronometre permet de gérer une attente dynamique de cette manière :

    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
    //---------------------------------------------------------------------------
    // AttenteDynamique - delai en ms
    //---------------------------------------------------------------------------
    void TChronometre::AttenteDynamique(double delai)
    {
       Start();
       Stop();
       while(GetTemps()<(delai*1E-3))
       {
          Sleep(1); // à voir selon la précision exigée
          Application->ProcessMessages();
          Stop();
       }
    }
    //---------------------------------------------------------------------------

  9. #9
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Merci Freeze
    J'ai du boulot pour demain pour integrer le code aux temporisations de mon programme

  10. #10
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 017
    Par défaut
    @Freeze, en fait le but était d'attendre moins de 1ms, d'où le QueryPerformance pour mesurer des temps en µs (voire ns)

    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
    //---------------------------------------------------------------------------
    // Attente Brève - delai en µs
    //---------------------------------------------------------------------------
    void TChronometre::MicroSleep(DWORD dwMicroseconds)
    {
       Start();
       Stop();
       double DelaiSeconds = dwMicroseconds * 1E-6;
       while(GetTemps() < DelaiSeconds)
       {
          Sleep(0); 
          Stop();
       }
    }
    //---------------------------------------------------------------------------
    Evidemement surtout pas de ProcessMessages() qui consomme un temps phénoménal
    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

  11. #11
    Membre confirmé
    Inscrit en
    Août 2010
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 123
    Par défaut
    Juste pour info et en espérant ne pas être hors sujet, il existe dans Delphi / C++ Builder une classe TStopwatch dans l'unité Diagnostics.

    http://docwiki.embarcadero.com/Libra...ics.TStopwatch

  12. #12
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 017
    Par défaut

    Et en plus maintenant c'est encaspulé dans une classe fournie par Embarcadero, depuis mon passe de D7 vers BCB2007 puis XE2 et aujourd'hui même XE3, je découvre au moins une classe (ou record évolué) de ce genre par semaine !
    Merci Pocoyote

    En ce moment même, je suis en train de supprimer mes attentes actives à base de Sleep au profit de TEvent, c'est bien plus élégant !
    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

  13. #13
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Le programme est operationnel je marque le post resolu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 05/03/2016, 13h01
  2. un textfield dans une page web à l'aide d'une servlet
    Par amelA dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 14/05/2006, 18h54
  3. supprimer item d'une listbox a l'aide d'un popup menu
    Par avogadro dans le forum Composants VCL
    Réponses: 14
    Dernier message: 24/04/2006, 22h08
  4. [VBA-E]Ouvrir une image jpg àl'aide d'une macro
    Par delamarque dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 15/03/2006, 09h47
  5. Réponses: 2
    Dernier message: 02/08/2005, 09h40

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