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 :

Ajouter dynamiquement une TImage a un TForm / utiliser le "OnClick" de cette image


Sujet :

C++Builder

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Points : 44
    Points
    44
    Par défaut Ajouter dynamiquement une TImage a un TForm / utiliser le "OnClick" de cette image
    Voila je fais un programme type bataille navale en c++ sous borland 5.

    J'ai donc une TForm nommé Form1.
    Je voudrais pouvoir rajouter "dynamiquement" des navires sur mon IHM.
    C'est a dire, quand je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Armee * _larmee;
    _larmee = new Armee ;
    //ça me lance le constructeur de bateau
    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
     
    Armee::Armee()
    {
            int i;
            i = Form1->ComponentCount;
            _image = new TImage(Form1);
            i = Form1->ComponentCount;   // componentcount a augmenté de 1
            _image->Picture->LoadFromFile("armee.bmp");
            _image->Left = 321;
            _image->Top = 50;
            _image->Height = 30;
            _image->Width = 60;
            _image->Enabled = true;
            _image->Visible = true;
            _image->AutoSize = true;
    }
    grace a une petite boucle de test j'ai pu voir que mon image etait bien dans la liste des components de la form (Components[])

    Malgré ça, l'image n'apparait pas sur mon IHM... et j'avoue que je ne comprends vraiment pas pourquoi.
    Si qq'un a une idée qu'il n'hesite pas.

    Merci merci.

  2. #2
    Membre à l'essai
    Inscrit en
    Mai 2006
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 22
    Points : 15
    Points
    15
    Par défaut Membre Parent
    En fait il faut que tu ajoute un composant TPicture a ta form

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    TPicture *p =new TPicture(Form1);
    if(p){
    p->Parent = Form1; // Affichage sur la fiche
    p->Left = ...; // Placement de ton image
    p->LoadFromFile(...);
    p->Show();
    }
    Il faut obligatoirement affecter une valeur à la propriété parent de l'image pour qu'elle s'affiche.

    En espérant avoir bien répondu

  3. #3
    Membre chevronné

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Pour simplifier un peu ton code à la place de

    _image->Left = 321;
    _image->Top = 50;
    _image->Height = 30;
    _image->Width = 60;
    tu peut utiliser SetBounds(left, top, width, height) qui fait celà en une seule passe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    _image->SetBounds(321, 50, 60, 30);
    Comme l'indique Abargadon, c'est le Parent qui permet d'afficher l'objet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    _image->Parent = Form1;
    A plus !

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Points : 44
    Points
    44
    Par défaut
    Yes, merci bien pour l'info... vous n'imaginez pas le temps que j'ai perdu la dessus

    sympa le SetBounds() ^^

  5. #5
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Par contre, juste une remarque.

    Tu utilise Form1 dans ton objet Armee. Tu romps ainsi l'encapsulation.

    Tu devrais passer un TForm* en paramètre à ton constructeur, et travailler avec ce TForm, ceci afin que ton objet soit le moins dépendant d'autres.


    Cordialement,

    Arnaud

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Points : 44
    Points
    44
    Par défaut
    Me voila deja face a un nouveau probleme, et de taille.

    Comment faire pour par exemple definir une fonction "OnClick" sur mon image cree dynamiquement?

    pour une image classique on ferait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void __fastcall TForm1::Image0Click(TObject *Sender)
    {
     
    }
    mais la... je me demande bien ce que je vais pouvoir ecrire
    (et surtout ou je vais l'ecrire? dans armee.h, dans ihm.h ?...)

    ps:
    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 Armee // version courte
    {
            public:
            //int, int sont les coordonnées x, y de l'armee
            Armee(string, string, int, int);
            ~Armee();
     
            private:
            int _id;
            TImage * _image;
            int _x;
            int _y;
            string _nomjoueur;
            string _couleur;
     
    };
    Est ce qu'il y aura moyen que ça soit gerer "directement" ou est ce qu'il va falloir que je passe par une feinte du style "a chaque click sur l'ihm je regarde les coordonnées du click et je recherche ce qu'il y a a cette place" ? :s

  7. #7
    Membre chevronné

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Est-ce que par exemple, une classe dérivée de TImage ne serait pas immédiatement plus simple qu'une classe gérant un TImage ?

    Par ailleurs... elle sert à quoi cette image ?

    A plus !

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Points : 44
    Points
    44
    Par défaut
    Une classe derivé de TImage... hum... c'est a dire? que je cree une classe derivé de TImage?

    en fait comme je l'ai expliqué je fais une sorte de bataille navale, l'image sur l'ihm represente un navire ou une base.

    mais les navires je dois les creer dynamiquement (nombre illimité) du coup, une fois qu'il est affiché sur mon ihm je veux pouvoir cliquer dessus pour recuperer des informations le concernant.

    Comme si sur un logiciel de bataille navale, en cliquant sur le sous marin, on avait son nom qui apparaissait. (sauf que le sous marin on l'a crée durant le programme).

    Suis je plus clair?

    voila ma classe armée, une armee etant representer sur l'ihm par une image sur laquelle j'aimerais pouvoir cliquer pour acceder justement au donnée de l'armée en question:

    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
    class Armee
    {
            public:
     
            void Set_x(int value);
            int Get_x();
            void Set_y(int value);
            int Get_y();
            void Set_id(int value);
            int Get_id();
            void Set_nomjoueur(AnsiString value);
            AnsiString Get_nomjoueur();
            void Set_couleur(AnsiString value);
            AnsiString Get_couleur();
     
            void setcasedepart(int, int);
     
            //int, int sont les coordonnées x, y de l'armee
            Armee(AnsiString, AnsiString, int, int);
            ~Armee();
     
            private:
     
            int _id;
            TImage * _image;
            int _x;
            int _y;
     
            AnsiString _nomjoueur;
            AnsiString _couleur;
     
    };

  9. #9
    Membre chevronné

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Tout simplement parce que dans mon esprit Armee me fait penser à un ensemble d'unités et non pas à une unité.

    Dérivation comme... dérivation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class jBoat : public TImage
    {
    public :
    //Les propriétés de l'unité...
    //...
        __fastcall jBoat(TComponent Owner, AnsiString Filename);
        __fastcall ~jBoat();
        void __fastcall WhenMouseDown(TObject *Sender, 
            TMouseButton Button, TShiftState Shift, int X, int Y);
    };
    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
    __fastcall jBoat::jBoat(TComponent *Owner, AnsiString Filename)
        : TImage(Owner)
    {
    if(Owner->InheritsFrom(__classid(TWinControl)))
            Parent = (TWinControl*)Owner; //<< anecdotique
    if(FileExists(Filename))
        {
        Picture->LoadFromFile(Filename);
        //...
        }
    //...
    OnMouseDown = WhenMouseDown;
    }
     
    __fastcall jBoat::~jBoat()
    {
    }
     
    void __fastcall jBoat::WhenMouseDown(TObject *Sender, 
        TMouseButton Button, TShiftState Shift, int X, int Y)
    {
    // Loupé.. touché.. coulé.. déplacé.. 
    //Mot compte triple... dix de der et le petit au bout ?
    }
    En développant d'autres classes (dérivées de TComponent) on garde un lien entre tous les objets en attribuant à chacun d'eux (en fonction de leur strate) un propriétaire spécifique (Owner).

    Par exemple :

    Le jeu détient les joueurs
    Les joueurs détiennent les unités.

    On peut ainsi facilement remonter, grace à cette organisation, de l'unité vers le joueurs et du joueur vers le jeu !

    Celà dit... est-ce le but recherché ici ?
    A plus !

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Points : 44
    Points
    44
    Par défaut
    Ah bah ça marche niquel, merci bien, par contre j'aimerais bien une ptite explication pour la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    OnMouseDown = WhenMouseDown;
    Je ne comprends pas vraiment a quoi ça sert.

  11. #11
    Membre chevronné

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    OnMouseDown = WhenMouseDown;
    Ne fait rien d'autre qu'affecter une méthode à l'événement.

    Pour l'événement OnClick ça devient :

    Déclaration dans la classe (jBoat chez moi) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void __fastcall WhenClick(TObject *Sender);
    La méthode elle même :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void __fastcall jBoat::WhenClick(TObject *Sender)
    {
    //S'il y a quelque chose à faire c'est ici...
    }
    Donc dans ce cas :

    A plus !

    NB Le "When" est une habitude perso pour repérer mes événementielles.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 60
    Points : 44
    Points
    44
    Par défaut
    Autre question un peu lié
    sur mon ihm j'aurais:
    - des images pour representer mes objets "armée", cette image representant une base.

    - des images pour representer mes objets "escouade", sachant que les escouades font partie d'une armée.

    A la base j'avais creer dans ma classe armée un vecteur de pointeur sur escouade. Mais du coup quand je selectionne (via un click) une de mes escouades sur l'ihm, comment je fais pour savoir a quelle armée elle appartient?

    Sachant que je ne peux pas tant ma classe Escouade rajouter un pointeur sur armée (car ça ne veut pas compiler si on fait un truc "croisé" comme ça).

    Il y a bien la solution de passer par des identifiants a la con qui permettent de retrouver mais je voulais savoir si il y avait moyen de savoir directement... a mon avis non...

  13. #13
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Pour gérer des références croisées à la compilation, il te faut faire une déclaration anticipée.

    Par exemple, dans le Escouade.h, tu rajoute :
    avant la déclaration de ta classe Escouade.

    Ainsi tu résoudra ton problème de compilation.

    Cordialement,

    Arnaud

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

Discussions similaires

  1. [VBA] Ajouter dynamiquement une référence
    Par jpharand dans le forum VBA Access
    Réponses: 23
    Dernier message: 16/04/2010, 23h28
  2. Réponses: 1
    Dernier message: 10/06/2008, 22h17
  3. [DOM] Ajouter dynamiquement une zone de texte
    Par fadex dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 28/02/2007, 15h01
  4. Réponses: 7
    Dernier message: 01/03/2006, 18h14

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