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

API, COM et SDKs Delphi Discussion :

Changer les icônes de la barre de titre et/ou de la Taskbar en cours d'exéution


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut Changer les icônes de la barre de titre et/ou de la Taskbar en cours d'exéution
    Je développe une vaste DLL de soutien à un langage externe, en Delphi 6 Personal Edition.

    Dans ce contexte, je veux créer une fonction qui me permette de changer dynamiquement l'icône de la barre de titre de la form principale et/ou de changer l'icône qui s'affiche dans la barre des tâches (TaskBar). Pour cela, je tente d'utiliser l'API SendMessage avec le handle de la form principale et avec le code message WM_SETICON et le paramètre ICON_SMALL ou ICON_BIG.

    Problème:
    Mais, quelque soit le code utiisé, c'est toujours l'icône de la barre de titre de la fenêtre principale qui est changée (correctement), mais jamais celle de la barre des tâches.

    Pour opérer le changement d'icône, je charge une bitmap carrée de dimensions quelconque dans le presse-papier, dans le programme appelant (écrit dans un autre langage). Puis j'appelle une fonction dans ma DLL écrite en Delphi 6 PE pour effectuer le changement. Je procède comme suit:
    - vérification que le presse-papier contient bien une image
    - je récupère les dimensions de mon système pour petites ou grandes icônes par GetSystemMetrics (chez moi, ce sont 16x16 et 32x32)
    - chargement de cette image dans une bitmap temporaire
    - en fonction du code demandé (ICON_SMALL ou ICON_BIG) je crée une icône temporaire avec les dimensions adéquates
    - j'utilise SendMessage pour affecter l'icône temporaire
    - finalement, je libère les ressources remporaires

    Ai-je commis une erreur de logique ?
    Ai-je mal utilisé SendMessage ?

    Je joins un fichier ZIP contenant l'ensemble des sources, un fichier bitmap utilisé pour les tests et les EXE générés. Ce ZIP contient un projet pour la DLL avec l'extrait nécessaire limité à la fonctioin concernée, et un projet de programme en Delphi appelant ette fonction. Ce programme est une simulation du programme du langage externe utilisant normalement la DLL, mais du coup, tout est en Delphi 6 PE et met le problème en evidence.

    Merci d'avance pour votre aide !

    P.S. Je précise que je suis sous Windows 10 toutes mises à jour faites.
    Fichiers attachés Fichiers attachés

  2. #2
    Membre éprouvé
    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
    Points : 1 072
    Points
    1 072
    Par défaut
    Bonjour,

    avec ce code je change l'icône dans la barre des tâches:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SendMessage(Application.Handle, WM_SETICON, 1, aIcon.Handle);
    Cordialement,
    @+

  3. #3
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Cirec Voir le message
    Bonjour,

    avec ce code je change l'icône dans la barre des tâches:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SendMessage(Application.Handle, WM_SETICON, 1, aIcon.Handle);
    Cordialement,
    @+
    Merci pour ta réponse, Cirec. Je fais la même commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SendMessage(MainFormHandle,WM_SETICON,ICON_BIG,bigicon.Handle);
    J'ai vérifié: la constante BIG_ICON a bien la valeur 1. Et pourtant... le résultat est différent:
    c'est l'icône de la barre de titre de la fenêtre principale qui est changée, pas l'icône dans la barre des tâches.

    Est-ce que ça viendrait de la différence du handle ciblé par SendMessage:
    - tu utilises Application.handle
    - j'utiliser Form1.handle

    J'ai essayé de passer Application.Handle à ma DLL, mais le résultat est identique: pas de changement d'icône dans la barre des tâches. Par contre, l'icône de la barre de titre de la fenêtre principale n'est plus modifiée en utilisabt ICON_BIG, ce qui est plutôt correct.

    J'ai apporté la modification correspondante dans le ZIP ci-joint.
    Fichiers attachés Fichiers attachés

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 453
    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 453
    Points : 24 864
    Points
    24 864
    Par défaut
    Ce n'est qu'à partir de Delphi 2007 et l'apparition de MainFormOnTaskBar qui l'icone de la Taskbar est celui de la MainForm et non celui du progamme
    Donc D6 c'est Application
    Et D2007+ c'est selon si MainFormOnTaskBar est à True ou pas
    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

  5. #5
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Ce n'est qu'à partir de Delphi 2007 et l'apparition de MainFormOnTaskBar qui l'icone de la Taskbar est celui de la MainForm et non celui du progamme
    Donc D6 c'est Application
    Et D2007+ c'est selon si MainFormOnTaskBar est à True ou pas
    Ben... je veux bien... :mais:
    1. WM_SETICON avec ICON_SMALL, envoyé à Form1.Handle change correctement l'icône de la barre de titre de la form 1
    2. WM_SETICON avec ICON_BIG, envoyé à A1pplication.Handle ne change rien - ni l'icône de la barre de titre (correct) ni celle de la barre des tâches (anormal)
    3. WM_SETICON avec ICON_BIG, envoyé à Form1.Handle change l'icône de la barre de titre de al form 1 (anormal) mais pas celle de la barre des tâches (?)

    Je ne comprends pas ce fonctionnement. Qu'est-ce qu'il faut faire pour changer l'icône de la barre des tâches ? Après tout, ce sont juste des APIs Windows avec des handles, et Windows ne connaît rien de Delphi. C'est juste un process comme un autre. Pourquoi l'API ne marche pas ?

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 689
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 689
    Points : 13 118
    Points
    13 118
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    1. WM_SETICON avec ICON_SMALL, envoyé à Form1.Handle change correctement l'icône de la barre de titre de la form 1
    Oui et non. Réduis et restaure la fenêtre et tu constateras que l'icône a disparu.

    Citation Envoyé par KlausGunther Voir le message
    Après tout, ce sont juste des APIs Windows avec des handles, ...
    Encore faut-il que les handles soient valides

    Tu crées les icônes mais les détruis dans la foulée. WM_SETICON a lancé un rafraichissement immédiat de la fiche et son icône apparaît mais à la prochaine demande (ex. réduction/restauration) le handle est invalide.
    Même chose pour bigicon mais avec en prime un rafraichissement asynchrone du desktop par rapport à ton app ; le handle n'est jamais valide.

    En bref, il faut conserver l'icône pendant toute la durée de vie de l'app. Le plus simple est de passer par les blocs initialization/finalization.

    Voici un exemple avec en prime une façon beaucoup plus simple de convertir l'image en icône. Et accessoirement, autant passer le fichier en paramètre plutôt que l'image par le presse-papier

    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
    uses Controls, Math;
     
    var
      Icons: array[ICON_SMALL..ICON_BIG] of TIcon;
     
    procedure SetApplicationIcon(aType: integer; aFileName :PChar); stdcall; export;
    var
      Handle :THandle;
      Bmp    :TBitmap;
      Tmp    :TBitmap;
     
    begin
      if not aType in [ICON_SMALL, ICON_BIG] then Exit;
     
      Bmp := TBitmap.Create;
      Tmp := TBitmap.Create;
     
      try
        Handle     := IfThen(aType=ICON_SMALL, MainFormHandle, ApplicationHandle);
        Tmp.Width  := GetSystemMetrics(IfThen(aType=ICON_SMALL, SM_CXSMICON, SM_CXICON));
        Tmp.Height := GetSystemMetrics(IfThen(aType=ICON_SMALL, SM_CYSMICON, SM_CYICON));
     
        Bmp.LoadFromFile(aFileName);
        Tmp.Canvas.StretchDraw(Rect(0, 0, Tmp.Width, Tmp.Height), Bmp);
     
        with TImageList.CreateSize(Tmp.Width, Tmp.Height) do
        try
          AddMasked(Tmp, Tmp.TransparentColor);
          GetIcon(0, Icons[aType]);
        finally
          Free;
        end;
     
        SendMessage(Handle, WM_SETICON, aType, Icons[aType].Handle);
     
      finally
        Bmp.Free;
        Tmp.Free;
      end;
    end;
     
    exports SetApplicationIcon;
     
    initialization
      Icons[ICON_SMALL] := TIcon.Create;
      Icons[ICON_BIG]   := TIcon.Create;
     
    finalization
      Icons[ICON_SMALL].Free;
      Icons[ICON_BIG].Free;
    Exemple fait en D11. Je n'ai plus souvenir mais peut-être en D6 faut-il un StrPCopy pour convertir aFileName de PChar en string...

  7. #7
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut
    Merci, Andnotor, d'avoir pris le temps de regarder mon problème.

    De mon côté, j'ai creusé le sujet et je suis tombé également sur le fait que je ne dois pas libérer l'icône utilisée avant la fin du programme. Après coup, cela semnle logique: je fournis le handle de l'icône à l'API et ce handle doit rester valide. Dont acte.

    Je continue d'utiliser le presse-papier car cela s'intègre dans un ensemble d'une vingtaine de fonctions traitant des images, et tout passe par l'intermédiaire du presse-papier. Certes, ce n'est pas très élégant. Si j'etais en Delphi pur (application + DLL),, j'aurais certainement choisi un autre moyen de mémoire temporaire tel q'un TMemoryStream. Cependant, l'application est écrite dans un langage qui n'y donne pas accès mais qui utilise facilement le presse-papier. CEci motive mon choix.

    J'ai produit une nouvelle version de la fonction DLL en Delphi 6 PE uqi résout parfaitement mon problème. Je peux:
    - changer l'icône de la barre de titre de la fenêtre principale
    - changer l'icône de la barre de titre ET celle du bouton dans la barre des tâches
    - restaurer les icônes initiales

    Les icones restent après une séquence miniaturisation/resdtauration, sans problème. La modification de l'icône du bouton de la barre des tâches est visible également en utilisant ALT-TAB. Donc, pour moi, tout va bien et le problème est résolu. Merci à tous qui ont bien voulu m'aider.

    Ci-joint un ZIP contenant les deux projets Delphi (DLL avec la fonction concernée, programme application simulant mon application en langage externe), ainsi qu'une icône pour les tests, et les binaires (DLL et EXE). Cette solution intéressera peut-être quelqu'un.
    Fichiers attachés Fichiers attachés

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

Discussions similaires

  1. [Graphique] Changer l'aspect de la barre de titre
    Par pofet dans le forum Windows Forms
    Réponses: 6
    Dernier message: 14/06/2007, 10h06
  2. Réponses: 4
    Dernier message: 03/06/2007, 07h18
  3. Ajouter une icônes dans la barre de titre
    Par fraric dans le forum Windows Forms
    Réponses: 8
    Dernier message: 11/02/2007, 21h22
  4. [JTree] Changer les icônes
    Par Spoutnik dans le forum Composants
    Réponses: 4
    Dernier message: 12/09/2005, 08h54
  5. Icône dans la barre de titre
    Par Sephi dans le forum MFC
    Réponses: 7
    Dernier message: 28/10/2003, 17h58

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