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

Langage Delphi Discussion :

Icône de barre de tâches qui ne s'affiche pas en premier plan


Sujet :

Langage Delphi

  1. #1
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut Icône de barre de tâches qui ne s'affiche pas en premier plan
    Bonjour tout le monde,

    Je travaille sur une application en XE7 sous Firemonkey. Cette précision est là uniquement pour indiquer que je ne peux pas utiliser de composant TTrayIcon.
    J'ai donc implémenter une gestion classique de trayicon en utilisant les messages Windows (avec compilation conditionnelle évidemment).
    Tout fonctionne bien à un détail près. Au premier appel, mon popup menu apparait bien au premier plan.
    Mais ensuite, quoique je fasse, si j'ai une application ouverte sur le bureau, le menu "apparait" (si on peut dire) en arrière-plan sur le bureau.
    Ce que je fais me parait pourtant du plus classique et je commence à tourner en rond sur ce "détail".

    Une idée du pourquoi du comment ?

    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
     
    {$IFDEF MSWINDOWS}
    var
      OldWindowProc: Pointer = nil;
      NewWindowProc: Pointer = nil;
     
    function NewWndProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
    var Mess : TMessage;
    begin
      if hwnd = FormMain.WinHandle.Wnd then
      begin
         case uMsg of
          WM_ICONRESPONSE:
          begin
            Mess.Msg    := uMsg;
            Mess.WParam := wParam;
            Mess.lParam := lParam;
            Mess.Result := 0;
            FormMain.Dispatch(Mess);
            Result := 0;
          end
          else
          Result := CallWindowProc(OldWindowProc, hwnd, uMsg, wParam, lParam);
         end;
      end
      else
        Result := CallWindowProc(OldWindowProc, hwnd, uMsg, wParam, lParam);
    end;
    {$ENDIF}
     
    ...
     
    {$IFDEF MSWINDOWS}
    procedure TFormMain.IconResponse(var Msg: TMessage);
    var
      pt: TPoint;
    begin
      case Msg.lParam of
        WM_LBUTTONDOWN:
        begin
          FormMain.WindowState := System.UITypes.TWindowState.wsNormal;
          FormMain.Show;
        end;
        WM_RBUTTONDOWN:
        begin
          GetCursorPos(pt);
          PopupMenu1.Popup(pt.x, pt.y);
        end;
      end;
    end;
    {$ENDIF}
    *****************

    un peu plus de précision :
    Je lance l'application depuis Delphi.
    La trayicon fonctionne plusieurs fois d'affilée tant qu'aucune autre application n'a pris le focus sur Windows.
    Si je je clique (et rien d'autre) sur une application visible sur le bureau (par exemple dans l'IDE) et que je reteste ma trayicon, c'est là que ça ne fonctionne plus.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 454
    Points : 24 866
    Points
    24 866
    Par défaut
    A l'époque de D6, j'ai aussi un appel de popup

    Voici un extrait du code, le commentaire n'est pas très explicite, je pense que cela indiquait une prise de focus d'une fenêtre non visible ! ???
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ...
      // NotifyPopup est le popup lors du clic sur la petite icone
      if (Msg.LParam = WM_RBUTTONDOWN)  then
      begin
         if GetCursorPos(PM) then
         begin
            SetForegroundWindow(Handle); // Jamais apparent 
            NotifyPopup.Popup(PM.x, PM.y);
         end;
    ...
    J'ai remarqué en XE2 que le mode Debug modifie subtilement la gestion du focus d'une application débuggée qui semble avoir plus de difficulté à être au premier plan (comme si Delphi tentait de lui voler la vedette en particulier lors d'un point d'arrêt)
    Cela en VCL, d'ailleurs, le MainFormOnTaskBar influence aussi ce genre de comportement

    En FMX, cela doit être différent.
    D'ailleurs la MainForm c'est la fenêtre qui contient le Popup
    Evite la variable FormMain, utilise Self dans IconResponse, pour le callback, difficile de faire autrement avec FormMain !

    Dans TOUS mes NotifyIcon, je séparais la fenêtre invisible qui contenait le Popup et la fenêtre affiché à l'écran
    As-tu essayé de créer une fenêtre secondaire que tu affiches ou caches selon les actions utilisateurs ?
    Cela évitera de faire un Hide sur la fenêtre qui contient le Popup, cela peut nuire au Focus
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    J'ai une question de novice (je n'utilise pas FMX) mais pourquoi vous ne pouvez pas utiliser TTrayIcon (étant donné que ce n'est pas un composant visuel de la form) ?

    Effectivement je comprend qu'on ne puisse déposer sur une fiche fmx un composant VCL mais n'est il pas possible d'instancier (conditionnellement) sur le oncreate de la fiche le composant TTrayIcon ?

  4. #4
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Bon la curiosité étant plus forte, je me répond à moi même

    J'ai créé une application FMX de type entête/pied :

    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
    unit HeaderFooterTemplate;
     
    interface
     
    uses
    {$IFDEF MSWINDOWS}
      vcl.ExtCtrls, {$ENDIF}
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls;
     
    type
      THeaderFooterForm = class(TForm)
        Header: TToolBar;
        Footer: TToolBar;
        HeaderLabel: TLabel;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormShow(Sender: TObject);
        {$IFDEF MSWINDOWS}procedure TrayIcon1DblClick(Sender: TObject);{$ENDIF}
      private
        {$IFDEF MSWINDOWS}TrayIcon1 : TTrayIcon;{$ENDIF}
      public
        { Public declarations }
      end;
     
    var
      HeaderFooterForm: THeaderFooterForm;
     
    implementation
     
    {$R *.fmx}
     
     
     
    procedure THeaderFooterForm.FormCreate(Sender: TObject);
    begin
    {$IFDEF MSWINDOWS}
       TrayIcon1 := TTrayIcon.Create(self);
    {$ENDIF}
    end;
     
    procedure THeaderFooterForm.FormDestroy(Sender: TObject);
    begin
    {$IFDEF MSWINDOWS}
       TrayIcon1.Free;
    {$ENDIF}
    end;
     
    procedure THeaderFooterForm.FormShow(Sender: TObject);
    begin
    {$IFDEF MSWINDOWS}
      TrayIcon1.Hint := 'Ca fonctionne !';
      TrayIcon1.OnDblClick := TrayIcon1DblClick;
      TrayIcon1.Visible := True;
     
    {$ENDIF}
    end;
    {$IFDEF MSWINDOWS}
    procedure THeaderFooterForm.TrayIcon1DblClick(Sender: TObject);
    begin
      // double clic
      TrayIcon1.Visible := False;
    end;
    {$ENDIF}
    end.
    Elle fonctionne correctement, j ai bien le trayicon et quand je doubleclic dessus il disparaît bien.

  5. #5
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    Citation Envoyé par Barbibulle Voir le message
    J'ai une question de novice (je n'utilise pas FMX) mais pourquoi vous ne pouvez pas utiliser TTrayIcon (étant donné que ce n'est pas un composant visuel de la form) ?

    Effectivement je comprend qu'on ne puisse déposer sur une fiche fmx un composant VCL mais n'est il pas possible d'instancier (conditionnellement) sur le oncreate de la fiche le composant TTrayIcon ?
    En général, je n'aime pas trop mélanger les choux et les carottes mais ça pourrait être une solution.
    Là, il faut aussi gérer la création complète du popupmenu qui n'est pas lui aussi du même type en VCL et en FMX.
    Je pensais m'en tirer à meilleur compte au design.
    Comme tout bon programmeur, je suis fainéant

  6. #6
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    A l'époque de D6, j'ai aussi un appel de popup

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ...
      // NotifyPopup est le popup lors du clic sur la petite icone
      if (Msg.LParam = WM_RBUTTONDOWN)  then
      begin
         if GetCursorPos(PM) then
         begin
            SetForegroundWindow(Handle); // Jamais apparent 
            NotifyPopup.Popup(PM.x, PM.y);
         end;
    ...
    Le SetForegroundWindow(Handle); apporte du mieux mais affiche l'application en même temps que le popupmenu.

    Quand tu dis

    je séparais la fenêtre invisible qui contenait le Popup
    tu parles uniquement du composant TPopupmenu ou de la gestion complète de windowProc et TrayIconData en plus ??

  7. #7
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    Citation Envoyé par Barbibulle Voir le message
    Bon la curiosité étant plus forte, je me répond à moi même

    J'ai créé une application FMX de type entête/pied :

    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
    unit HeaderFooterTemplate;
     
    interface
     
    uses
    {$IFDEF MSWINDOWS}
      vcl.ExtCtrls, {$ENDIF}
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls;
     
     
    procedure THeaderFooterForm.FormCreate(Sender: TObject);
    begin
    {$IFDEF MSWINDOWS}
       TrayIcon1 := TTrayIcon.Create(self);
    {$ENDIF}
    end;
     
    procedure THeaderFooterForm.FormDestroy(Sender: TObject);
    begin
    {$IFDEF MSWINDOWS}
       TrayIcon1.Free;
    {$ENDIF}
    end;
     
    end.
    Elle fonctionne correctement, j ai bien le trayicon et quand je doubleclic dessus il disparaît bien.
    Oui, ça fonctionne, c'est vrai.

    Je viens de tenter le coup mais en rajoutant vcl.ExtCtrls , Delphi râle (en premeir) sur une propriété inexistante dans le MuiltiResBitmap de mon TImage présent sur la TForm.
    Évidemment puisque ça n'existe pas en vcl et qu'il le prend dans cette librairie.
    Si je règle ça, ça va sans doute créer une autre incohérence.
    Bref, s'il faut faire des ajustements un peu partout en position de uses, en adaptation diverses, ça commence à couter plus cher que ça ne rapporte.

    Si le client se plaint, à défaut de trouver une solution simple, j'aviserai.

  8. #8
    Membre expert
    Avatar de Barbibulle
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    2 048
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 2 048
    Points : 3 342
    Points
    3 342
    Par défaut
    Effectivement, ce n'est pas terrible.
    Il va du coup chercher le composant TImage dans la VCL au lieu FMX. Ce qui oblige à déclarer FMX.Objects dans les uses juste après VCL.ExtCtrl


    J'ai modifié mon code pour voir la gestion du menupopup.

    Effectivement il faut utiliser celui de la VCL (et donc le créer à la volée) mais on peut utiliser les actions du composant FMX

    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
    85
    86
    87
    88
    89
    90
    91
    unit HeaderFooterTemplate;
     
    interface
     
    uses
    {$IFDEF MSWINDOWS}
      vcl.ExtCtrls, vcl.Menus, FMX.Objects, {$ENDIF}
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
      System.Actions, FMX.ActnList;
     
    type
      THeaderFooterForm = class(TForm)
        Header: TToolBar;
        Footer: TToolBar;
        HeaderLabel: TLabel;
        ActionList1: TActionList;
        Action1: TAction;
        Image1: TImage;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormShow(Sender: TObject);
        {$IFDEF MSWINDOWS}procedure TrayIcon1DblClick(Sender: TObject);  {$ENDIF}
        procedure Action1Execute(Sender: TObject);
     
      private
        {$IFDEF MSWINDOWS}TrayIcon1 : TTrayIcon;
                          MonPopup : TPopupMenu;
                          MenuItem : TMenuItem;
        {$ENDIF}
      public
        { Public declarations }
      end;
     
    var
      HeaderFooterForm: THeaderFooterForm;
     
    implementation
     
    {$R *.fmx}
     
     
     
    procedure THeaderFooterForm.Action1Execute(Sender: TObject);
    begin
    {$IFDEF MSWINDOWS}
      TrayIcon1.Hint := 'Action 1 !';
    {$ENDIF}
    end;
     
     
     
    procedure THeaderFooterForm.FormCreate(Sender: TObject);
    begin
    {$IFDEF MSWINDOWS}
       TrayIcon1 := TTrayIcon.Create(self);
       MonPopup  := vcl.Menus.TPopupMenu.Create(self);
       MenuItem  := vcl.Menus.TMenuItem.Create(self);
    {$ENDIF}
    end;
     
    procedure THeaderFooterForm.FormDestroy(Sender: TObject);
    begin
    {$IFDEF MSWINDOWS}
       TrayIcon1.Free;
       MonPopup.Free;
    {$ENDIF}
    end;
     
    procedure THeaderFooterForm.FormShow(Sender: TObject);
    begin
    {$IFDEF MSWINDOWS}
      MenuItem.Caption := Action1.Text;
      MenuItem.Action  := Action1;
      MonPopup.Items.Add(MenuItem);
     
      TrayIcon1.PopupMenu :=  MonPopup;
      TrayIcon1.Hint := 'Ca fonctionne !';
      TrayIcon1.OnDblClick := TrayIcon1DblClick;
      TrayIcon1.Visible := True;
     
    {$ENDIF}
    end;
    {$IFDEF MSWINDOWS}
    procedure THeaderFooterForm.TrayIcon1DblClick(Sender: TObject);
    begin
      // double clic
      TrayIcon1.Visible := False;
    end;
    {$ENDIF}
    end.

    C'est vrai qu'on mélange les choux et les carottes mais en même temps en faisant des {$IFDEF MSWINDOWS} on fait également du mélange.

    Le plus ennuyeux c'est effectivement la maîtrise des portés des uses.

  9. #9
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    Je prendrai surement cette solution si il y a une remontée du client.

    Il faudra quand même que je vois si ça résout mon problème d'affichage du popupmenu en arrière-plan, sinon, ça ne servira pas à grand-chose.

  10. #10
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    J'ai finalement été curieux moi aussi.
    Solution testée et approuvée !
    Le menu s'affiche bien en premier plan.

    Merci

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

Discussions similaires

  1. [AC-2007] Sous Formulaire : barre de défilement qui ne s'affiche pas
    Par dave92 dans le forum IHM
    Réponses: 1
    Dernier message: 12/05/2022, 12h19
  2. Alert qui ne s'affiche pas au premier plan
    Par rillette87 dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 07/06/2011, 00h39
  3. [CS4] Barre des propriétés qui ne s'affiche pas correctement
    Par FuegoAtao dans le forum Dreamweaver
    Réponses: 0
    Dernier message: 18/04/2010, 19h07
  4. Réponses: 1
    Dernier message: 09/02/2008, 18h55
  5. Form de base qui ne s'affiche pas en arrière plan
    Par FamiDoo dans le forum Windows Forms
    Réponses: 6
    Dernier message: 27/01/2008, 18h11

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