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 :

[D10] Comment détecter si l'application a le focus ou pas ? [Windows]


Sujet :

Composants FMX Delphi

  1. #1
    Membre Expert
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 704
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 704
    Par défaut [D10] Comment détecter si l'application a le focus ou pas ?
    En FMX, comment détecter si l'application a le focus ou pas ?

    En VCL, il y a le composant TApplicationEvent, mais il n'a pas l'air d'exister en FMX.
    J'ai trouvé cette page (http://docwiki.appmethod.com/appmeth...plicationEvent) qui m'a l'air de parler de ce que je cherche, mais pas moyen de trouver comment ça s'utilise.

    Une idée ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. :bug: ___ "http://club.developpez.com/regles/#LIII-A"Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.3 Entreprise - Visual studio 2022
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.7)

  2. #2
    Membre actif Avatar de Coudrak
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 66
    Par défaut
    Je l'utilise comme ça (pour Android et iOS) :

    D'abord, créer une fonction private avec l'évènement qui t'intéresse (BecameActive j'imagine) :

    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
     
    function TForm1.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
    begin
      case AAppEvent of
        TApplicationEvent.FinishedLaunching: ;
        TApplicationEvent.BecameActive: ;
        TApplicationEvent.WillBecomeInactive: ;
        TApplicationEvent.EnteredBackground: ;
        TApplicationEvent.WillBecomeForeground: ;
        TApplicationEvent.WillTerminate: ;
        TApplicationEvent.LowMemory: ;
        TApplicationEvent.TimeChange: ;
        TApplicationEvent.OpenURL: ;
      end;
      Result := True;
    end;
    Puis assigner cette fonction dans FormCreate par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    var
      EventService: IFMXApplicationEventService;
    begin
      if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(EventService)) then
        EventService.SetApplicationEventHandler(HandleAppEvent);

  3. #3
    Membre Expert
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 704
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 704
    Par défaut
    Ça ressemble bien à ce que j'aimerais , mais ça ne fonctionne pas (d'après l'aide) pour windows (et c'est mon unique cible, pour l'instant).
    Donc comme le if retourne faux, la fonction n'est pas appelée.


    C'est réellement pas du tout géré sous windows (et il faut chercher une autre solution), ou il faut lui demander gentiment ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. :bug: ___ "http://club.developpez.com/regles/#LIII-A"Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.3 Entreprise - Visual studio 2022
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.7)

  4. #4
    Membre actif Avatar de Coudrak
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 66
    Par défaut
    Alors tout simplement l'évènement OnActivate de la form, non ?

  5. #5
    Membre Expert
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 704
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 704
    Par défaut
    Citation Envoyé par Coudrak Voir le message
    Alors tout simplement l'évènement OnActivate de la form, non ?
    L'ennui, c'est qu'il se déclenche à la fois quand je change de fenêtre (à l'intérieur de l'application) et quand je réactive l'application.
    Donc avec cet évènement, je ne peux pas identifier à coup sûr quand l'application perd ou récupère le focus.
    Pas simple ...
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. :bug: ___ "http://club.developpez.com/regles/#LIII-A"Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.3 Entreprise - Visual studio 2022
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.7)

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 937
    Billets dans le blog
    6
    Par défaut
    La solution pourrait-elle être d'avoir un système centralisé de OnActivate/OnDeactivate pour chaque fiche de l'application, qui fasse +1/-1 à une variable globale et quand tu es à 0, c'est que ton appli n'a plus le focus ?

    [EDIT] en y réfléchissant mieux, il m'apparaît que ça ne peut fonctionner comme ça...
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  7. #7
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 638
    Billets dans le blog
    65
    Par défaut
    Bonjour,

    moi j'ai d'abord pensé au TNotification mais je ne l'utilise que pour envoyer vers le centre de notification de windows et je ne sais pas si on peut envoyer la notification à un programme ? une sorte de push/get, je n'ai pas approfondi.

    Comme ce n'est que windows, il y a peut être aussi la solution WMI à fouiller

  8. #8
    Membre émérite
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Par défaut
    Bonjour,

    si la cible c'est Windows peut être que GetActiveWidow fera l'affaire
    dans un évènement OnTimer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      if GetActiveWindow <> 0 then
        Caption := 'Activé'
      else
        Caption := 'Non Activé'
    Si l'application à le focus elle renvoie le Handle de la fenêtre courante (MainForm, MessageBox ou autre Fiche)
    sinon elle renvoie 0

    j'ai testé ça devrait le faire (pour Windows)
    ça combiné avec le "OnActivate" ...

    Cordialement,

    @+

  9. #9
    Membre Expert
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 704
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 704
    Par défaut
    Bon, alors vu que c'est géré pour toutes les autres plates-formes sauf windows, j'ai un collègue qui a modifié l'unité FMX.Platform.Win pour que ça marche aussi (c'est bien sale comme solution, mais bon, avec FMX faut toujours tout faire soi-même ).

    Pour ceux que ça intéresse :
    Mon 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
    22
    23
    24
    procedure TFrm_Main.FormCreate(Sender: TObject);
    var
      EventService: IFMXApplicationEventService;
    begin
      if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, IInterface(EventService)) then
        EventService.SetApplicationEventHandler(HandleAppEvent);
     
    ...
     
    function TFrm_Main.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
    begin
      Result := True;
      case AAppEvent of
        TApplicationEvent.BecameActive:
          begin
    ...
          end;
     
        TApplicationEvent.WillBecomeInactive:
          begin
    ...
          end;
      end;
    end;
    En gros, ses modifications dans FMX.Platform.Win :
    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
    procedure RegisterCorePlatformServices;
    ...
       TPlatformServices.Current.AddPlatformService(IFMXApplicationEventService, PlatformWin);
     
     
    procedure UnregisterCorePlatformServices;
    ...
       TPlatformServices.Current.RemovePlatformService(IFMXApplicationEventService);
     
     
    procedure TPlatformWin.SetApplicationEventHandler(AEventHandler: TApplicationEventHandler);
    begin
      FOnApplicationEvent := AEventHandler;
    end;
     
     
    function TPlatformWin.HandleApplicationEvent(AEvent: TApplicationEvent; AContext: TObject): Boolean;
    begin
      Result := False;
     
      { Invoke application event}
      if Assigned(FOnApplicationEvent) then
        try
          Result := FOnApplicationEvent(AEvent, AContext);
        except
          Application.HandleException(Self);
        end;
    end;
     
     
    function WndProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
    ...
            WM_ACTIVATEAPP:
              begin
                Result := DefWindowProc(hwnd, uMsg, wParam, lParam);
     
                if BOOL(wParam)
                  then PlatformWin.HandleApplicationEvent(TApplicationEvent.BecameActive,nil)
                  else PlatformWin.HandleApplicationEvent(TApplicationEvent.WillBecomeInactive,nil) ;
     
                if BOOL(wParam)
                  then PlatformWin.RestoreApp;
              end;
    Et ça marche.


    pour votre aide.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. :bug: ___ "http://club.developpez.com/regles/#LIII-A"Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.3 Entreprise - Visual studio 2022
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.7)

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 13/04/2008, 11h29
  2. Comment détecter l'appui sur une touche hors de l'application ?
    Par freezerhm dans le forum Windows Forms
    Réponses: 6
    Dernier message: 06/04/2008, 22h53
  3. Réponses: 3
    Dernier message: 16/01/2008, 12h41
  4. Réponses: 11
    Dernier message: 03/09/2006, 21h25
  5. Réponses: 4
    Dernier message: 11/06/2006, 05h39

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