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

Composants FMX Delphi Discussion :

Perte de focus [Windows]


Sujet :

Composants FMX Delphi

  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut Perte de focus
    Bonjour,

    je suis en train de préparer un petit papier sur la possibilité d'ajouter un bouton de clôture à un TTabItem. J'ai réussi à le faire avec style pas forcément élégance de deux manières différentes donc pas de souci de ce côté. Ce qui me gêne c'est la perte de focus ou du moins est-ce ainsi que je l’interprète.
    Symptôme : lorsque je clôture un onglet, le menu système de la forme (je teste sous windows) n'est plus actif, il faut que je clique dans le cadre de la forme pour que celui-ci réagisse à nouveau.

    J'ai tenté ce code
    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
    procedure TForm1.CloseTab(sender: TObject);
    var i : Integer;
        KeyChar : Char;
        Key : Word;
     
    begin
    // recherche de l'onglet 
    for I := 0 to TabControl1.TabCount-1 do
      if TabControl1.Tabs[i]=TButton(Sender).TagObject then Break;
    // clôture de l'onglet
    if i<TabControl1.TabCount then TabControl1.Delete(i);
     
    // la fenêtre perd le focus si plus de tabitems 
    // code fonctionnel mais inefficace au niveau du menu système 
    if TabControl1.TabCount>0 then  TabControl1.ActiveTab.SetFocus
    else begin
       Key:=vkTab;
       KeyChar:=#9;
       KeyDown(Key,KeyChar,[]);
    end;
    end;
    Une idée ou est-ce un petit bogue de Tokyo (10.2.3)
    Je peux bien sûr vous fournir le code complet au besoin
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Je me posais des questions car même un bouton placé sur une "page" du TabControl avait le même comportement !


    Ce "problème" n'a pas attiré grand monde mais le forum Embarcadero m'a donné la solution merci aux deux intervenants (Claude et EmailX45

    Je pense que c'est ce Claude qui a mis le doigt dessus l'évènement doit être "publié" avant la destruction, il faut donc écrire une tâche reportée
    Je ne connaissais ni cette contrainte ni cette technique mais c'est efficace

    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
    procedure TForm1.CloseTab(sender: TObject);
    var i : Integer;
    begin
    // rechercher l'onglet ,y a t'il certainement mieux qu'une boucle ?
    for I := 0 to TabControl1.TabCount-1 do
      if TabControl1.Tabs[i]=TButton(Sender).TagObject then Break;
     
    if i<TabControl1.TabCount then
     // Publier l'évènement  
     TTask.Run(
        procedure
        begin
          TThread.Synchronize(nil,
            procedure
            begin
             TabControl1.Delete(i);  // TButton(Sender).TagObject.DisposeOf; 
            end);
        end);
    end;
    Je vais maintenant étudié de plus près le code de EmailX45 mais d'ores et déjà, je passe le sujet en résolu
    une FAQ, un tutoriel, un billet dans mon blog ou un mix de ces possibilités devrait bientôt suivre
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    l'évènement doit être "publié" avant la destruction
    Je pense plutôt qu'il voulait dire "relaché" / "terminé"

    Intéressant cette technique. Etant sur D7 (et windows), n'ayant pas les fonctions anonymes, quand je tombais sur un cas comme ca, je faisais un PostMessage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    const WM_DELETETAB = WM_USER=1;
    [...]
      procedure DeleteTab(var msg: TMessage); message WM_DELETETAB;
    [...]
    if i<TabControl1.TabCount then
      PostMesssage(Self.Handle, WM_DELETETAB, i, 0);
     
    procedure TForm14.DeleteTab(var msg: TMessage);
    begin
      TabControl1.Delete(msg.WParam);  // TButton(Sender).TagObject.DisposeOf; 
    end;
    Effectivement, il ne faut pas détruire l'objet qui envoie l’événement, même si dans beaucoup de cas, il n'y a plus d'utilisation de Self après l'appel de l’événement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TButton.Click;
    begin
      if Assigned(FOnClick) then
        FOnClick(Self); //Si on détruit le bouton dans le OnClick,
      Self.Repaint;      // cet appel ou tout autre code du bouton plantera !
    end;

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par guillemouze Voir le message
    Je pense plutôt qu'il voulait dire "relaché" / "terminé"
    Oui, GoogleTrad n'est peut-être pas si bon que ça

    Etant sur D7 (et windows), n'ayant pas les fonctions anonymes, quand je tombais sur un cas comme ca, je faisais un PostMessage
    Je voudrais éviter les PostMessage autant que ce peut, j'ai un doute de portabilité sur ce genre de chose
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Je voudrais éviter les PostMessage autant que ce peut, j'ai un doute de portabilité sur ce genre de chose
    Entièrement d'accord, je donnais juste mon alternative dans le cas ou on n'a pas accès aux nouveautés du langage comme c'était mon cas.
    Mais je suis entièrement preneur de la solution de Claude pour reporter l'appel d'un bout de code; elle est beaucoup plus élégante, portable, et simple à mettre en place ... quand on a ce qu'il faut pour le faire (pas mécontent d'avoir enfin laché ce D7)

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

Discussions similaires

  1. [C#] Detecter la perte de focus
    Par iowa dans le forum Windows Forms
    Réponses: 10
    Dernier message: 15/03/2006, 14h03
  2. Réponses: 9
    Dernier message: 02/02/2006, 15h46
  3. Comment détecter la perte de focus d'une fenêtre
    Par Leviathan_72 dans le forum Windows
    Réponses: 5
    Dernier message: 31/12/2005, 00h22
  4. excel -> test lors de la perte du focus d'une cellule
    Par greg778 dans le forum Macros et VBA Excel
    Réponses: 24
    Dernier message: 26/09/2005, 17h26
  5. [VB.NET] Perte de focus entre deux form
    Par toniolol dans le forum Windows Forms
    Réponses: 2
    Dernier message: 05/07/2005, 08h00

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