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 :

TADOConnection + Unresolved external


Sujet :

C++Builder

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 65
    Par défaut TADOConnection + Unresolved external
    Bonjour,

    Je travaille actuellement sous C++ Builder 5 et essaie d'implémenter une classe qui me permettra de me connecter à différentes bases de données pour les besoin de l'application que je réalise.
    J'ai fait le choix d'une classe statique, à savoir que l'ensemble des attributs et méthodes sont statiques.

    Mon premier problème est que j'obtiens les messages suivants à la compilation :
    [Lieur Erreur] Unresolved external 'Database::cnnSQLBIF' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER5\PROJECTS\DATABASE.OBJ
    [Lieur Erreur] Unresolved external 'Database::cnnSQLData' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER5\PROJECTS\DATABASE.OBJ
    J'ai vérifié plusieurs fois si je n'avais pas oublié un petit quelque chose et, à première vue, il me semble que non.

    Mon deuxième problème est le fait que lorsque je veux instancier mon objet TADOConnection, je suis censé faire :
    cnnMDB = new TADOConnection(this);
    J'obtiens alors le message suivant :
    [C++ Erreur] Database.cpp(23): E2297 'this' ne peut être utilisé que dans une fonction membre
    Je comprends pourquoi le compilateur me signale cette erreur (c'est logique, vu que c'est du statique, le pointeur this ne fait référence à rien), je ne peux donc pas faire ça.
    Mais alors, comment dois-je procéder ? Suis-je obligé de faire de cette façon ? Y a-t-il une alternative ?

    Voici le code pour mieux comprendre et visualiser :

    Database.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
     
    #ifndef DatabaseH
    #define DatabaseH
     
    #include <ADODB.hpp>
     
    class Database
    {
       private:
            static TADOConnection *cnnMDB;
            static TADOConnection *cnnSQLBIF;
            static TADOConnection *cnnSQLData;
       public:
            static bool __fastcall openMDBConnection(String dbName);
            static bool __fastcall openSQLConnection(bool bForBif, String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String dbName);
            static bool __fastcall openSQLConnections(String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String BIFDBName, String DataDBName);
     
    };
    #endif
    Database.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 <vcl.h>
    #pragma hdrstop
     
    #include "Database.h"
     
    bool __fastcall Database::openMDBConnection(String dbName)
    {
       String cs = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dbName;
       // voir message compilo quand commentaire retiré
       //cnnMDB = new TADOConnection(this);
       Database::cnnMDB->CursorLocation = clUseClient;
       Database::cnnMDB->ConnectionString = cs;
       Database::cnnMDB->LoginPrompt = false;
       try { Database::cnnMDB->Connected = true; }
       catch (EADOError *e) { return false; }
     
       return true;
    }
     
    bool __fastcall Database::openSQLConnection(bool bForBif, String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String dbName)
    {
       String cs = "Provider=SQLOLEDB.1;Password=" + pw + ";Persist Security Info=True;" + "User ID=" + userName + ";Initial Catalog=" + dbName;
     
       if(serverNamedPipe != "")
            cs += ";Data Source=" + serverNamedPipe;
       else
            cs += ";Network Address=" + serverAddress + ";Network Library=dbmssocn";
     
       if(serverCustom != "")
       {
            cs = serverCustom;
            cs = StringReplace(cs, "<PW>", pw, TReplaceFlags());
            cs = StringReplace(cs, "<ID>", userName, TReplaceFlags());
            cs = StringReplace(cs, "<DB>", dbName, TReplaceFlags());
       }
     
       if(bForBif)
       {
            // voir message compilo quand commentaire retiré
            //cnnSQLBIF = new TADOConnection(this);
            Database::cnnSQLBIF->CursorLocation = clUseClient;
            Database::cnnSQLBIF->ConnectionString = cs;
            Database::cnnSQLBIF->LoginPrompt = false;
            try { Database::cnnSQLBIF->Open(userName, pw); }
            catch (EADOError *e) { return false; }
     
            return true;
       }
       else
       {
            // voir message compilo quand commentaire retiré
            //cnnSQLData = new TADOConnection(this);
            Database::cnnSQLData->CursorLocation = clUseClient;
            Database::cnnSQLData->ConnectionString = cs;
            Database::cnnSQLData->LoginPrompt = false;
            try { Database::cnnSQLData->Open(userName, pw); }
            catch (EADOError *e) { return false; }
     
            return true;
       }
    }
     
    bool __fastcall Database::openSQLConnections(String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String BIFDBName, String DataDBName)
    {
       bool rc;
     
       rc = openSQLConnection(true, userName, pw, serverNamedPipe, serverAddress, serverCustom, BIFDBName);
       if(rc)
       {
            rc = openSQLConnection(false, userName, pw, serverNamedPipe, serverAddress, serverCustom, DataDBName);
            if(!rc)
                    Database::cnnSQLBIF->Close();
       }
     
       return rc;
    }
     
    #pragma package(smart_init)
    J'ai également une autre question :

    Comment accéder à des composants de ma GUI depuis une autre classe, composants déclarés dans la partie __published du .h ?

    Merci d'avance.

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 106
    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 106
    Par défaut
    les membres statiques nécessitent un emplacement de stockage a mettre dans le .H et le CPP selon ta préférence

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    TADOConnection* Database::cnnMDB = NULL;
    TADOConnection* Database::cnnSQLBIF = NULL;
    TADOConnection* Database::cnnSQLData = NULL;
    Pourquoi utilises-tu du static ?
    Si tu fais un objet C++ standard, comme c'est le cas, tu peux juste créer une variable globale en allocation statique qui te servira de singleton !
    Tu pourras avoir des membres d'instance, c'est plus simple non que de créer toutes la classe en static !


    Tu dois mettre NULL comme Onwer,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       cnnMDB = new TADOConnection(NULL);
    si il se montre capricieux, cela arrive
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       cnnMDB = new TADOConnection((TComponent*)NULL);
    Ne pas oublier de faire autant de delete que new dans ta future fonction closeMDBConnection

    Plusieurs questions, dans le même sujet, ce n'est pas conforme au règles du forum, passons ...

    Si tu veux utiliser les membres d'une classe dans le fichier d'une autre classe, tu dois inclure le .h utilisé dans le fichier .CPP qui l'utilisera !
    C'est la base de l'include !



    Avant d'aller plus loin, il te faudrait revoir les Bases du C++ et C++Builder !
    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

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 65
    Par défaut
    Tout d'abord merci d'avoir répondu.
    Et un merci de plus car tes conseils quant à mon problème de TADOConnection ont porté leurs fruits, ça marche maintenant magnifiquement bien !

    En ce qui concerne l'utilisation des membres de mon autre classe, j'avais déjà essayé d'inclure le .h, sans succès (suis quand même pas aussi débutant que ça ^^). Voici le code :

    Gui.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
     
    #ifndef GuiH
    #define GuiH
     
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ComCtrls.hpp>
    #include <Dialogs.hpp>
    #include <ADODB.hpp>
    #include <Db.hpp>
     
    class TInterface : public TForm
    {
    __published:	// Composants gérés par l'EDI
            TLabel *userNameLabel;
    private:	// Déclarations utilisateur
    public:	// Déclarations utilisateur
            __fastcall TInterface(TComponent* Owner);
    };
     
    extern PACKAGE TInterface *Interface;
     
    #endif
    CmdLine.cpp (là où je voudrais pouvoir avoir accès au TLabel) :
    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
     
    #include <vcl.h>
    #pragma hdrstop
     
    #include <IniFiles.hpp>
    #include "CmdLine.h"
    #include "Gui.h"
     
    void __fastcall CmdLine::readSettings()
    {
       String path = ExtractFilePath(Application->ExeName)+"settings.ini";
       TIniFile *settings = new TIniFile(path);
     
       if(settings->SectionExists("init"))
       {
            userNameEdit->Text = settings->ReadString("init", "username", "def");
       }
    }
     
    #pragma package(smart_init)
    Le message d'erreur :
    [C++ Erreur] CmdLine.cpp(16): E2451 Symbole 'userNameEdit' non défini

    Merci d'avance.

  4. #4
    Membre Expert
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Billets dans le blog
    1
    Par défaut
    Salut
    en principe cela devrait être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Interface->userNameLabel=settings->ReadString("init", "username", "def");
    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 65
    Par défaut
    Citation Envoyé par DjmSoftware Voir le message
    Salut
    en principe cela devrait être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Interface->userNameLabel=settings->ReadString("init", "username", "def");
    cdlt
    Effectivement, cela marche maintenant correctement, merci à toi !


    ShaiLeTroll :
    Quand tu dis :
    "Pourquoi utilises-tu du static ?
    Si tu fais un objet C++ standard, comme c'est le cas, tu peux juste créer une variable globale en allocation statique qui te servira de singleton !
    Tu pourras avoir des membres d'instance, c'est plus simple non que de créer toutes la classe en static !"


    Tu me conseilles d'utiliser le patron de conception singleton en gros ? J'y avais déjà pensé mais l'idée de faire des classes statiques m'a semblé plus facile au premier abord. Je sais bien que ce n'est pas une "bonne pratique" mais disons que le programme sur lequel je travaille n'a pas vraiment été pensé objet mais plutôt procédural (je dois en fait ré-écrire et optimiser un programme écrit en VB6 à la base). Quels seraient les avantages à ta proposition ? Je ne suis pas si expérimenté que ça, toute idée est bonne à prendre et à creuser.

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 106
    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 106
    Par défaut
    En fait, static, ça te fait faire plus de code !

    tu pouvais faire ceci

    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
    class CDatabase
    {
       private:
            TADOConnection *cnnMDB;
            TADOConnection *cnnSQLBIF;
            TADOConnection *cnnSQLData;
       public:
            CDatabase();
            ~CDatabase();
            bool __fastcall openMDBConnection(String dbName);
            bool __fastcall openSQLConnection(bool bForBif, String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String dbName);
            bool __fastcall openSQLConnections(String userName, String pw, String serverNamedPipe, String serverAddress, String serverCustom, String BIFDBName, String DataDBName);
    };
     
    extern CDatabase MyDatabase;
    dans le CPP, tu une seule variable globale !

    tu peux ainsi utiliser le this au besoin, ça te fait moins de mot clé, en plus, je trouve l'appel est plus "lisible"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CDatabase::openMDBConnection(...);
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MyDatabase.openMDBConnection(...);
    et le couple constructeur\destructeur
    tu n'as pas besoin d'y pense avec une variable en allocation statique, le destructeur sera appelé automatiquement et libérera tes objets internes !

    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
     
    CDatabase::~CDatabase()
    {
      cnnMDB = NULL;
      cnnSQLBIF = NULL;
      cnnSQLData = NULL;
    }
     
    CDatabase::~CDatabase()
    {
      delete cnnMDB;
      cnnMDB = NULL;
     
      delete cnnMDB;
      cnnSQLBIF = NULL;
     
      delete cnnMDB;
      cnnSQLData = NULL;
    }
    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
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2009
    Messages : 65
    Par défaut
    Merci pour ces précisions, je comprends maintenant mieux les avantages qu'une telle approche pourrait apporter.
    J'ai juste une seule question :

    Quand on fait : extern CDatabase MyDatabase;
    Tu me confirmes bien que l'objet MyDatabase sera accessible depuis d'autres classes pour peu qu'elles incluent le .h ?
    Vu que j'ai besoin d'avoir accès à cet objet dans d'autres classes, il faut absolument que je puisse y accéder de l'extérieur.

    En fait ce que je voulais faire à la base, c'est faire des classes statiques en déclarant les constructeurs en private de manière à ce qu'elles ne puissent pas être instanciées (en gros je voulais faire des classes 100% statiques).
    Cette manière de faire est-elle vraiment à éviter ?

    Encore merci.

  8. #8
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 106
    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 106
    Par défaut
    je ne suis pas un grand expert du C++ mais c'est ce que j'ai aussi compris

    dans le CPP : CDatabase MyDatabase; va fournir l'emplacement mémoire
    dans le .H extern CDatabase MyDatabase; va juste indiquer l'existence d'une variable
    Effectivement, lors de l'include du .H cela te donnera accès à la variable !

    En Delphi, c'est bien plus simple dans l'équivalent du Header, on fait juste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var
      MyDatabase: CDatabase;
    Pour le static à 100%, j'en ai fait, en Delphi on a même un possibilité de faire de polymorphisme sur des méthodes statiques et virtuelles, cela n'est pas possible en C++, donc j'ai appris à faire autrement !

    Pour le constructeur masqué, je fais la même chose avec un Singleton, mes objets héritent souvent du TObject donc new obligatoire !

    j'ignore si tu peux le faire avec des objet en allocation statique, vu que le constructeur est privé tu n'y as donc plus accès, je n'ai jamais tenté !

    perso, j'ai fait un truc comme ça dans plusieurs DLL qui respecte le même modèle d'implémentation et d'interfaces !

    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
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
      static CCustomDLLExports DllExportObject; // mon singleton !!!
     
      switch( reason )
      {
        case DLL_PROCESS_ATTACH :
          DllExportObject.DLLProcessAttach();
        break;
     
        case DLL_THREAD_ATTACH :
        case DLL_THREAD_DETACH :
        break;
     
        case DLL_PROCESS_DETACH :
          DllExportObject.DLLProcessDettach();
     
        break;
      }
     
      return 1;
    }
    Chaque DLL à sa propre classe Export héritant du même ancêtre !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class CCustomDLLExports : public CAbstractDLLExports 
    {
    public:
      /*override*/virtual TAbstractProvider* GetHardwareProviderInstance(); 
    };
    une classe ancêtre commune

    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
    class CAbstractDLLExports 
    {
      friend class THardwareAbstractProvider;
     
    protected:
      // Membres Protégés Statiques
      static CAbstractDLLExports* FInstance;
     
      // Méthodes Abstraites Protégées devant être redéfinies
      /*abstract*/virtual THardwareAbstractProvider* GetHardwareProviderInstance() = 0;
     
    public:
      // Méthodes Publiques
      void DLLProcessAttach();  // Must Call on DLL_PROCESS_ATTACH
      void DLLProcessDettach(); // Must Call on DLL_PROCESS_DETACH
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void CAbstractDLLExports::DLLProcessAttach()
    {
        CAbstractDLLExports::FInstance = this;
    }
     
    void CAbstractDLLExports::DLLProcessDettach()
    {
      CAbstractDLLExports::FInstance = NULL;
    }
    DLLProcessAttach() et DLLProcessDettach() aurait pu être le constructeur et le destructeur, je n'ai pas testé, en théorie ça devrait fonctionner, en plus cela m'aurait éviter de faire des appels explicites dans le DLLMain !

    L'objet DllExportObject est une instance unique créée avec le mot clé static dans le corps d'une fonction, cela donne un objet global !
    Comme je récupère un pointeur dessus, je peux l'utiliser ailleurs !

    Ensuite, dans le reste du code (bcp de code abstrait), j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CAbstractDLLExports::FInstance->GetHardwareProviderInstance()->MethodTruc()
    Et tout cela aurait très bien pu être simplifié par un simple passage de paramètre dans GetHardwareProviderInstance !

    Que veux-tu, on part sur des trucs compliqués, ensuite, on hésite toujours à revenir dessus (surtout quand tu dois du coup modifier les n implémentations)
    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

Discussions similaires

  1. TADOConnection + Unresolved external
    Par Tenebrous dans le forum C++
    Réponses: 1
    Dernier message: 15/02/2012, 10h24
  2. unresolved external symbol _IID_IDi
    Par PC23 dans le forum DirectX
    Réponses: 6
    Dernier message: 05/08/2005, 10h38
  3. PB de buil : unresolved external symbol
    Par dede92 dans le forum Windows
    Réponses: 8
    Dernier message: 13/12/2004, 11h21
  4. unresolved external symbol _IID_IDirectDraw7
    Par lvdnono dans le forum DirectX
    Réponses: 2
    Dernier message: 15/06/2004, 21h05
  5. Réponses: 4
    Dernier message: 23/04/2004, 16h06

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