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 :

comment faire pour qu'un curseur devienne un parfait viseur?


Sujet :

C++Builder

  1. #1
    Candidat au Club
    Inscrit en
    Octobre 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 8
    Points : 3
    Points
    3
    Par défaut comment faire pour qu'un curseur devienne un parfait viseur?
    Bonjour,
    Je debute en C++, je voudrais creer un viseur, avec un cercle et son centre, qui peuvent passer au dessus d'autres images tout en étant transparent, et que le click de la sourie puisse toujours etre pris en compte. J'ai eu beau tenter de grapiller a droite a gauche, je n'arrive toujours pas a realiser ce que je veux. O Desespoir
    C'est assez exigeant, certes, mais au moins je sais ce que je veux.
    Aidez moi! Pleaaase.
    Merci
    PS: Je tiens a souligner que ce n'est pas pour un jeu, mais pour trouver le centre de cercles dont le diametre est connu... Car c fastidieux de le trouver a l'aveuglette.

  2. #2
    Membre habitué
    Homme Profil pro
    Chercheur génie électrique
    Inscrit en
    Mai 2002
    Messages
    263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur génie électrique
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 263
    Points : 136
    Points
    136
    Par défaut
    Je n'ai pas tout compris ta demande. Si on charge une image préfabriquée (avec transparent) comme image de curseur, est-ce que cela peut avancer ton projet?

  3. #3
    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
    Points : 3 766
    Points
    3 766
    Par défaut
    Salut romu37fr:
    Dans l'aide Windows SDK voir "CursorCreation", "LoadCursor"

  4. #4
    Candidat au Club
    Inscrit en
    Octobre 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    Avant tout, merci pour vos reponses.
    Le probleme est que justement je ne comprend rien aux explciations données avec l'aide. Je débute, et leurs consignes ne sont pas toujours évidentes.
    J'aimerai bien chargé une image, comme le suggere Xavier. Mais je ne sais pas comment convertir le curseur en cette image. Et imaginons que je charge un gif, pour avoir la transparence ou je veux, je ne sais pas comment faire en sorte que la transparence soit prise en compte...

  5. #5
    Membre chevronné

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Déclarer en global ou bien en tant que propriété de la form :

    Tu peux utiliser un TShape dont il faudra fixer certaines propriétés comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Shape1->Pen->Mode = pmNot;
    Shape1->Brush->Style = bsClear; //cercle non rempli
    Shape1->Shape = stCircle;
    Shape1->Cursor = crCross; //pour symboliser le centre du cercle
    Shape1->Tag = 30; //comme rayon du cercle
    On suppose pour Shape1 les trois événementielles de la souris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void __fastcall TForm1::Shape1MouseDown(TObject *Sender,
          TMouseButton Button, TShiftState Shift, int X, int Y)
    {
    int r = Shape1->Tag;
    int d = r * 2;
    Pos = Point(r,r);
    Shape1->OnMouseMove = Shape1MouseMove;
    Shape1->SetBounds(Shape1->Left - (r - X),
                      Shape1->Top - (r - Y),
                      d,
                      d);
    Shape1->BringToFront();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void __fastcall TForm1::Shape1MouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
    Shape1->SetBounds(Shape1->Left - Pos.x + X,
                      Shape1->Top - Pos.y + Y,
                      Shape1->Width,
                      Shape1->Height);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void __fastcall TForm1::Shape1MouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
    Shape1->OnMouseMove = NULL;
    }
    Dans le constructeur de la form on rajoute cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Shape1->OnMouseMove = NULL;
    Lorsque l'on clique sur le shape, ce dernier ce recentre sur les coordonnées de la souris et reste centré pendant tout le mouvement.

    Je ne suis pas certain que ce soit la solution attentdue donc... à suivre !

    A plus !

  6. #6
    Candidat au Club
    Inscrit en
    Octobre 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    Encore une fois avant tout, merci ^.^
    Mais... Il y a toujours un mais. Mais soit je suis vraiment nulle, soit je ne sais pas. Mais j'avais deja vu un code de ce type pour un viseur pour images de telescope je crois. Et j'avais rencontré les mêmes problemes:
    -Le cercle fuit le curseur et ne le suit pas (c frustrant)
    -Il en va de soit, le curseur n'est pas au centre du cercle...
    Je commence a croire que je ne suis pas faite pour la programmation

  7. #7
    Membre chevronné

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Je n'ai pourtant pas l'impression que le cercle fuit le curseur chez moi !
    De toute façon... c'est une méthode dont j'ai horreur !!!

    Par contre, il y a une autre possibilité, mais il faudrait dans ce cas travailler en graphisme, et ce y compris avec les images ce qui suppose aucun objet de la VCL sur la form ! C'est une autre approche !

    Est-ce que c'est dans ce sens là ?

    A plus !

  8. #8
    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
    Points : 3 766
    Points
    3 766
    Par défaut
    Salut romu37fr:
    J'avais fait un essai sur un TAnimate de poser un viseur, mais celui ci etait fixe, j'etais parti sur une Form, sans bordure et en jouant sur la transparance, mais la pour cadrer c'est le telescope qui bouge pas la Form.

  9. #9
    Membre chevronné

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    En ce qui concerne l'imperfection des cercles, il faut se souvenir qu'il n'existe pas de fractions de pixels.
    Par conséquent, lorsque le diamètre du cercle est pair (en terme de nombre de pixels), le centre du cercle est situé entre deux pixels !!!

    A plus !

  10. #10
    Candidat au Club
    Inscrit en
    Octobre 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    J'ai reussi a faire en sorte que ce cercle arrete de me fuire, mais je ne suis toujours pas au centre
    Pour le telescope j'avais donc mal compris desolée
    L'approche graphique peut etre une bonne idée, mais il faudrait incorporer un gif ? (pour la transparence) Je vais fouiner pour voir comment faire...

    PS: Le but de la manoeuvre est de compléter un programme deja créé, oú il faut trouver le centres de cercles sur des photos pas toujours tres nettes (parfois on ne voit qu'un tier du cercle) pour la suite du programme, et generalement ca donne ca:

  11. #11
    Candidat au Club
    Inscrit en
    Octobre 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    Bon, c'est encore moi.
    Apres avoir rereretaper le code donné par Henderson, et l'avoir reretester, il s'avere qu'il marche a merveille. J'ai juste reprecisé r=30 ds Shape1MouseDown. Mais je crois que je suis vraiment trop nulle, je ne comprend plus rien, mm si je n'ai jamais compris finallement...Désolée de vous avoir autant importunée alors que la reponse était deja la
    Merci infiniment. A bientot

  12. #12
    Membre chevronné

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 390
    Points : 1 777
    Points
    1 777
    Par défaut
    Salut !

    Sur un plan purement graphique, on peut objétiser ce viseur à l'aide d'une classe que je fais dériver ici de TComponent :

    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
    class jViseur : public TComponent
    {
    private :
    int FRayon;
    bool FVisible;
    TCanvas *Canvas;
    TPoint Pos;
    //Objets propres à cette classe
    TPen *Pen;
    TBrush *Brush;
     
        //méthode propre à l'objet permettant de le dessiner 
        void __fastcall Draw();
     
    protected :
     
        //méthode propre à l'objet permettant de fixer le rayon
        void __fastcall SetRayon(int R);
     
    public: //Tout ce que l'utlisateur va pouvoir utiliser
     
        //méthodes
        __fastcall jViseur(TComponent *AOwner, TCanvas *ACanvas);
        __fastcall ~jViseur();
     
        void __fastcall Show(int X, int Y);
        void __fastcall Move(int X, int Y);
        void __fastcall Hide();
     
        //propriétés :
        __property int Rayon={read=FRayon, write=SetRayon};
        __property bool Visible={read=FVisible};
    };
    Rayon est une propriété accessible en lecture et en écriture
    Visible n'est accessible qu'en lecture.

    Les méthodes de cette classe :

    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
    80
    81
    82
    83
    84
    __fastcall jViseur::jViseur(TComponent *AOwner, TCanvas *ACanvas)
        : TComponent(AOwner)
    {
    Canvas = ACanvas;
    FVisible = false;
    Brush = new TBrush;
    Brush->Style = bsClear;
    Pen = new TPen;
    Pen->Style = psSolid;
    Pen->Mode = pmNot;
    Pen->Color = clBlack;
    }
     
    __fastcall jViseur::~jViseur()
    {
    delete Pen;
    delete Brush;
    }
     
    void __fastcall jViseur::SetRayon(int R)
    {
    if(R < 0) R = R * -1; //ou R = abs(R) donc inclure math.h
    if(FVisible) Draw(); // efface
    FRayon = R;
    if(FVisible) Draw(); //dessine
    }
     
    void __fastcall jViseur::Draw()
    {
    //pour sauvegarder les liens vers les objets du canvas cible
    TPen *CPen;
    TBrush *CBrush;
     
    if(Canvas != NULL)
        {
        //sauvegarde des liens vers les objets
        CPen = Canvas->Pen;
        CBrush = Canvas->Brush;
     
        //L'objet se dessine avec ses propres objets
        Canvas->Pen = Pen;
        Canvas->Brush = Brush;
     
        //On dessine un cercle
        Canvas->Ellipse(Pos.x - FRayon,
                        Pos.y - FRayon,
                        Pos.x + FRayon,
                        Pos.y + FRayon);
     
        //On dessine une croix
        Canvas->MoveTo(Pos.x, Pos.y - 8); Canvas->LineTo(Pos.x, Pos.y + 8);
        Canvas->MoveTo(Pos.x - 8, Pos.y); Canvas->LineTo(Pos.x + 8, Pos.y);
     
        //restauration des liens des objets
        Canvas->Brush = CBrush;
        Canvas->Pen = CPen;
        }
    }
     
    void __fastcall jViseur::Show(int X, int Y)
    {
    if(!FVisible)
        {
        FVisible = true;
        Pos = Point(X,Y);
        Draw();
        }
    }
     
    void __fastcall jViseur::Hide()
    {
    if(FVisible)
        {
        Draw();
        FVisible = false;
        }
    }
     
    void __fastcall jViseur::Move(int X, int Y)
    {
    if(FVisible) Draw(); //efface
    Pos = Point(X,Y);
    if(FVisible) Draw(); //dessine
    }
    Le constructeur initialise les propriétés, en particulier le canvas cible qui est fourni en tant que paramètre et crée deux objets pour le dessin (Pen et Brush) dont il initialise les propriétés.
    Ces deux objets viendront se substituer à ceux du canvas cible pour éviter qu'ils soient modifiés par l'objet.
    Le fait de dériver de TComponent permet de ne pas se soucier de la destruction de l'objet car c'est son propriétaire qui s'en chargera le moment venu.
    Le destructeur détruit les objets créés.

    Draw permet de dessiner l'objet. Elle est privée car elle ne concerne pas l'utilisateur.

    Show rend l'objet visible et le dessine aux coordonnées (X,Y)
    Hide rend l'objet invisible
    Move permet de déplacer l'objet aux coordonnées (X,Y)

    On peut bien entendu apporter des modifications !

    Pour la démonstration, j'ai activé le KeyPreview (true) de la form car je donne ici la possibilité d'agir sur le rayon du cercle à l'aide des touches '<' et '>'.
    Le viseur ne devient visible que lorsque l'on clique avec le bouton gauche et disparait lors du relâchement.
    Voici comment ça se présente depuis l'unité de TForm1 :

    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
    jViseur *Viseur;
     
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    Viseur = new jViseur(this, Canvas);
    Viseur->Rayon = 25;
    }
     
    void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
    if(Button == mbLeft)
        {
        Screen->Cursor = crNone; //fait disparaître le curseur de la form
        Viseur->Show(X,Y);
        }
    }
     
    void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
    Viseur->Move(X,Y);
    }
     
    void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y)
    {
    Screen->Cursor = crDefault; //rétablit le curseur de la form
    Viseur->Hide();
    }
     
    void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)
    {
    if(Viseur->Visible)
        {
        if(Key == '>') Viseur->Rayon += 1;
        if(Key == '<') Viseur->Rayon -= 1;
        }
    }
    Comme tu peux le voir, seule la classe jViseur demande quelques efforts de programmation.
    Son utilisation est simple.

    Cette solution n'est envisageable que si l'image cible est dessinée sur la form car tout se passe au niveau de cette form.
    Cela dit, à tester malgré tout sur un TImage chargé avec un bitmap !

    A plus !

  13. #13
    Candidat au Club
    Inscrit en
    Octobre 2006
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    ^.^ Alors: la premiere methode n'est pas idéale, surtout avec une image derriere.
    Mais la dexieme est parfaite et fontionne a merveille.
    Infiniment merci. Merci, merci, merci...
    Je suis contente.

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 03/06/2015, 06h47
  2. Réponses: 0
    Dernier message: 30/05/2015, 02h05
  3. Réponses: 2
    Dernier message: 10/06/2010, 10h10
  4. Comment faire pour que mon image devienne un lien
    Par pierrot10 dans le forum Général JavaScript
    Réponses: 38
    Dernier message: 25/06/2007, 20h49
  5. Réponses: 6
    Dernier message: 25/08/2006, 15h16

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