Retour à la documentation

FindWindow()

 

Nous allons évoquer :

 

La base du fonctionnement de la fonction

Les bug éventuels

Compléter son usage en affichant la fenêtre recherchée si elle existe

Le cas ou la fenêtre appelée a été minimisée

Ce qu’il faudrait faire

Note dUFLP

 

 

La fonction de base

 

 FindWindow() retourne le Handle d’une fenêtre et 0 si elle n’existe pas.

Ceci est un moyen pratique de savoir si une fenêtre est ouverte ou non, et peut donc servir à déterminer si une application est lancée ou non

 L’idée de cet article a débuté par la fonction WindowExist située dans MiscApi.prg de dUflp.

Pour des raisons de compréhension, elle est adaptée au français

function FenetreExiste(cNomBarreDeTitre)
/*
   Can be used to see if a Window exists by text in
   titlebar (this does assume you know what the text is) ...
   Posted by Andrew Shimmin in the dBASE Users'Groups
   February 1, 2008 


   Cette fonction utilise le nom de la barre de titre
   Eviter les caractères accentués et spéciaux
   Cette fonction n'est pas sensible à la casse
*/
local nWinHandle
if type("FindWindow") # "FP"
  extern CHANDLE FindWindow(CSTRING,CSTRING)
user32 from "FindWindowA"
endif
nWinHandle = FindWindow(0,cNomBarreDeTitre)
return (nWinHandle > 0) // renvoie true si la fenêtre existe

 

Bugs éventuels

 

dBASE utilise les caractères Unicode alors que  findWindow() attend des caractères ANSI.

Il suffit de convertir les caractères Unicode en Ansi pour solutionner ce cas. Le code suivant paru dans les newsgroups dBase, traite ce point.

Function FromUnicode(c)
   local cText,nLen,nInd
   nLen=len(c)
         cText = ""
         For nInd = 0 To nLen - 1
              cText += Chr(c.GetByte(nInd))
         EndFor
   return cText

 

Compléter l’usage en affichant la fenêtre

 

Il peut être intéressant, si la fenêtre existe, de la remettre devant l’utilisateur.
Pour cela on ne va pas simplement tester l’existence ou non de la fenêtre, on va la gérer un peu plus car à son identificateur unique (Handle).

Function AfficheFenetre(cText)
// active les fonctions si elles n’existent pas
if type('FindWindow') # 'FP'
    extern chandle FindWindow(cstring, cstring);
    user32 from 'FindWindowA'
endif
if type('BringWindowToTop') # 'FP'
   extern clogical BringWindowToTop(chandle) user32
endif
// recherche l’existence du titre de la fenêtre
n = FindWindow(null,cText)
// si elle existe, l’affiche au premier plan
if n # 0
  BringWindowToTop(n)
Else
   msgbox(cText + " n'est pas en cours d'exécution", "Information", 0 + 16)
endif

 

 

Le cas où la fenêtre appelée avait été minimisée

 

Cette fonction semble simple, mais il reste un problème. Si la fenêtre a été réduite, elle ne s’affiche pas ! On va donc la forcer à reprendre sa place grâce à OpenIcon.

Le code devient donc :

 

Function AfficheFenetre(cFenetre)>
// active les fonctions si elles n'existent pas
if type('FindWindow') # 'FP'    
   extern chandle FindWindow(cstring,cstring);    
   user32 from 'FindWindowA'
endif
if type('BringWindowToTop') # 'FP'   
   extern clogical BringWindowToTop(chandle) user32
   endif
// recherche l'existence du titre de la fenêtre
n = FindWindow(null,cFenetre)
// si elle existe, l'affiche au premier plan
if n # 0   
   if type("OpenIcon") # "FP"      
     extern clogical OpenIcon(chandle) user32   
   endif   
nAffiche = openicon(n)   
BringWindowToTop(n)
Else
   msgbox(cFenetre + "n'est pas en cours d'exécution", "Information", 0 + 16)
endif

 

Ce qu’il faudrait faire

 

Un vrai programmeur, ce qui n’est pas mon cas, testerait si l’application est déjà minimisée ou non par :

If type("IsIconic") # "FP"
    extern clogical IsIconic(chandle) user32
endif

Le bon code serait donc

if n # 0              // existe
   If type("IsIconic") # "FP"
      extern clogical IsIconic(chandle) user32
   endif
   nReduit = IsIconic(n)    // vérifie l’état de la fenêtre
   if nReduit
      if type("OpenIcon") # "FP"
         extern clogical OpenIcon(chandle) user32
      endif
       nAffiche = openicon(n)
   endif   && nReduit   BringWindowToTop(n)
Else
   msgbox(cFenetre + " n'est pas en cours d'exécution", "Information", 0 + 16)
endif

 

Mais puisqu’il faut lancer une première fois un ordre extern pour voir si l’application est iconisée, il me semble aussi rapide d’utiliser directement l’ordre d’agrandir la fenêtre pour la remettre à sa position précédente. Toujours autant de temps d’exécution en moins


Note dUFLP

La version V de dUFLP a intégré la fonction windowExist(cWindowname) dans   MiscAPI.prg qui utilise findwindow.

 

Sources :
Forums dBASE
Findwindow : pas retrouvé un lien vers un texte en français de msdn qui explique le fonctionnement détaillé de findwindow()
OpenIcon : http://msdn.microsoft.com/en-us/library/ms633535(VS.85).aspx
IsIconic : http://msdn.microsoft.com/en-us/library/ms633527(VS.85).aspx

Maurice Abraham – 28 août 2009

Dernière modification : mercredi 05 octobre 2011 17:32:51