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 :

MouseDown et Forme modale


Sujet :

C++Builder

  1. #1
    Invité
    Invité(e)
    Par défaut MouseDown et Forme modale
    Bonsoir,

    J'utilise actuellement une forme modale (TForm affichée par ShowModal()). Je souhaiterais qu'elle puisse se fermer quand l'utilisateur clique en dehors de la forme. Donc, idéalement, je voudrais quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void __fastcall TMaForme::FormMouseDown(TObject *Sender,
    	  TMouseButton Button, TShiftState Shift, int X, int Y)
    {
    if(X<0 || Y<0 || X>=Width || Y>=Height) {
    	ModalResult=mrCancel;
    }
    }
    Oui, mais voila, à la différence d'une forme affichée avec Show() et ayant capturé la souris, l'évènement MouseDown ne semble pas intervenir quand je clique en dehors de la forme modale... Je n'arrive pas non plus à capturer correctement la souris, car les évènements MouseEnter et MouseLeave semblent désactivés...

    Quelqu'un sait il comment faire?

    A défaut, j'aurais la question subsidiaire suivante ...

    Supposons que ce soit impossible, je sais avoir ce comportement pour une forme non modale (en capturant la souris quand on sort et qu'on entre dans la forme, et en écrivant le code ci dessus), mais je voudrais prévenir, comme dans une forme modale, le composant appelant de la fermeture de la forme (comme quand on fait des ShowModal()==mrOk)

    Merci d'avance,
    Francois

  2. #2
    Membre Expert

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 407
    Par défaut
    Salut !

    Tu peux utiliser une StayOnTop à la place de la modale.
    Dans sa classe tu rajoutes un pointeur vers TForm :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public:
    TForm *Target;

    Au moment de l'appel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MaStayOnTop->Target = this;
    MaStayOnTop->Show();
    Ensuite il suffit d'utiliser la OnDeactivate de la StayOnTop.

    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
     
    void __fastcall TMaStayOnTop::FormDeactivate(TObject *Sender)
    {
    if(Target->ClassNameIs("TForm1"))
        {
        switch(ModalResult)
            {
            case mrOk :
            ShowMessage("Action validée");
            break;
            case mrCancel :
            ShowMessage("Action annulée");
            break;
            }
        }
    }
    Pour les autres fenêtres (celles qui vont fermer la StayOnTop), on peut aussi le faire avec OnMouseMove :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y)
    {
    if(MaStyOnTop->Visible)
        {
        MaStayOnTop->ModalResult = mrCancel;
        MaStayOnTop->Hide();
        }
    }
    C'est assez simple comme mécanisme ...
    REM : ne pas oublier d'inclure le header des unités, là où on s'en sert !

    A plus !

  3. #3
    Invité
    Invité(e)
    Par défaut
    Salut Henderson,

    Je n'avais pas pensé aux StayOnTop, je vais expérimenter avec...

    J'ai trouvé une autre solution, qui conserve la forme modale. Apparemment, ce qui se passe, c'est que la forme modale intercepte les messages souris dès que celle ci quitte la forme. Pour éviter cela, j'ai ajouté un panel, qui contient tous les éléments de la forme, et qui est donc quitté avant que la souris quitte la forme. A ce moment, j'intercepte la souris (MouseCapture), et je me retrouve donc dans le cas souhaité, tout en conservant la forme modale.

    Ca donne donc un truc comme ca :

    - la Forme Modale contient un TPanel (Panel1) avec Align=alClient;, qui sert de conteneur à tous ses éléments

    A l'appel on fait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int res=FormeModale->ShowModal();
    if(res!=mrCancel) {
      switch(res) {
         // tous les cas...
      }
    }
    Dans la forme modale on va avoir :

    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
     
    /* capture de la souris, si le panel s'affiche ailleurs qu'à l'endroit où l'on clique... */
    void __fastcall TFormeModale::FormeModaleShow(TObject *Sender)
    {
    // code éventuel
    SetCapture(Panel1->Handle);
    }
     
    /* fin de la capture quand la souris est sur la forme */
    void __fastcall TFormeModale::Panel1MouseEnter(TObject *Sender)
    {
    ReleaseCapture();
    }
     
    /* capture quand on la quitte */
    void __fastcall TFormeModale::Panel1MouseLeave(TObject *Sender)
    {
    SetCapture(Panel1->Handle);
    }
     
    /* ferme quand on clique hors de la forme */
    void __fastcall TFormeModale::Panel1MouseDown(TObject *Sender,
    	  TMouseButton Button, TShiftState Shift, int X, int Y)
    {
    if(X<0 || Y<0 || X>=Width || Y>=Height) {
    	ReleaseCapture();
    	ModalResult=mrCancel;
    }
    }
    A priori, ca a l'air de bien fonctionner. Il reste ensuite de petits détails à gérer, pour faire que les composants contenus dans Panel1 s'activent automatiquement quand la souris revient sur la forme (sinon il faut cliquer deux fois), mais c'est en gros l'idée...

    Francois

Discussions similaires

  1. Form modale depuis une autre form elle même ayant un parent
    Par alacaraibe dans le forum Windows Forms
    Réponses: 2
    Dernier message: 08/06/2009, 14h02
  2. Utiliser form modal dans plusieurs form
    Par sondo dans le forum Langage
    Réponses: 2
    Dernier message: 11/11/2008, 17h25
  3. [.Net 1.1] griser l'écran derrière un form modal
    Par sCove dans le forum Windows Forms
    Réponses: 4
    Dernier message: 17/04/2008, 11h59
  4. Form Modal c'est quoi ?
    Par olibara dans le forum Windows Forms
    Réponses: 3
    Dernier message: 01/03/2008, 08h31
  5. rendre un Form modal en VBA
    Par stigma dans le forum IHM
    Réponses: 3
    Dernier message: 18/10/2007, 16h16

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