XL 2016 Fermer une fenetre windows de deuxieme niveau

treza88

XLDnaute Occasionnel
Bonjour a tous,

j'ai un code vba pour fermer une fenêtre Windows, mais il me semble qu'il ne fonction pas toujours correctement, du fait que ma fenêtre est une fenêtre ouverte de deuxième niveau donc le code ne la trouve pet être pas forcement a chaque fois.
Quelqu'un pourrait il me confirmer ou pas qu'il y a bien un problème.
Voici mon code:

VB:
Do

 

        FenRun = FindWindow(vbNullString, "fenetre a fermer")

 

        Call PostMessage(FenRun, WM_CLOSE, 0, 0)

 

        DoEvents

    Loop While FenRun <> FindWindow(vbNullString, "fenetre a fermer")
 

Dudu2

XLDnaute Barbatruc
On défini une constante "WM_CLOSE" qui est un integer de capacité de 16 bits?
Qu'une variable ou constante de type Integer soit représentée sur 16 bit n'a RIEN A VOIR avec la valeur 16 qu'on lui attribue.
Ici c'est la valeur 16 qui nous intéresse, et le type Integer est d'ailleurs incorrect par rapport au 2ème paramètre défini du SendMessage qui est de type Long.
VB:
Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal Msg As Long, wParam As Any, lParam As Any) As Long
Il aurait fallu, pour être 100% précis définir:
Const WM_CLOSE As Long = &H10
On s'en sort bien parce que le mode de passage du paramètre est ByVal et qu'il y a une conversion sous-jacente. Si c'était ByRef, le compilateur aurait dit "Pas bon !"
 

treza88

XLDnaute Occasionnel
OK merci pour ton complément d'info, je comprend mieux.
A par la différence entre Byval et Byref ou je dois encore bosser pour comprendre la subtilité entre les deux.
en tout cas merci pour pour les connaissances que tu m'as apporté et merci a toi aussi Danreb pour tes compléments d'informations.
je reviendrai vers vous si j'ai un quelconque bug mais dans mes premiers essaies ça a l'air stable.
et encore merci ce que vous m'avez appris.
 

treza88

XLDnaute Occasionnel
Alors excuse moi patricktoulon, mais le code de Dudu2 apparemment fonctionne et je voulais le comprendre, mais comme je te l'ai cité plus haut je vais étudier findwindowex et GetNextWindow, mais jusque la les infos ne sont pas facile a trouver sur findwindowex et GetNextWindow, dans le passé tu m'as déjà donner de bon coup de main sur le forum (ce que je n'oublie pas) et je vais donc creuser plus loin mes recherches et je n’hésiterai pas a revenir vers toi si mes recherche son infructueuse.
mais tes infos demande pour moi beaucoup de recherche pour les utiliser.
De mon coté tes compétences, pour moi, ne sont plus a vérifier, par contre les miennes sont a améliorer sans aucun doutes.
 

patricktoulon

XLDnaute Barbatruc
re

si un des modèles de dudu2 fonctionne alors la fenêtre qui est l'object de ta discussion n'est pas du second niveau

EN AUCUN CAS FINDWINDOW ne peut ATTEINDRE LE 2D NIVEAU

POUR LES DEUX AUTRES API

Fonction GetNextWindow

Declare Function GetNextWindow Lib "user32" Alias "GetWindow" ( _
ByVal hwnd As Long, _
ByVal wFlag As Long) As Long
Versions :
. Windows 95/98 : Oui
. Windows NT : A partir de 3.1
. Windows 2000/XP : Oui
Description :
Cette fonction permet de connaître la fenêtre suivante ou précédente de la fenêtre active (fonctionne également pour les fenêtres fille d'une MDI). Equivalent de ce que peut donner un [ALT][TAB] (ou [CTRL][TAB] dans le cas de MDI).
hwnd est le handle de la fenêtre de départ.
wFlag est une constante du tableau ci-dessous (en gros défini le sens de la recherche).


Constante​
Valeur​
Définition​
GW_HWNDNEXT2Définition de la fenêtre suivante.
GW_HWNDPREV3Définition de la fenêtre précédente.

-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------

FindWindowEx Function
Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hwndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long

Platforms


  • Windows 95: Supported.
  • Windows 98: Supported.
  • Windows NT: Requires Windows NT 4.0 or later.
  • Windows 2000: Supported.
  • Windows CE: Not Supported.


Description & Usage
FindWindowEx searches for a window matching a specified window class name and/or window name. The function searches all of the child windows of a given window (if desired), beginning with the windows below a specified child window. To ignore the window's class and/or title, pass a null string for those parameters.

Return Value
If successful, the function returns a handle to the found window. If no matching window could be found, or if an error occured, the function returns zero (use GetLastError to get the error code.

Visual Basic-Specific Issues
To pass a null string as one of the function's parameters, use the vbNullString constant.

Parameters


hWndParentA handle to the parent window to search the child windows of. To search all windows, specify 0 for this parameter. hWndChildAfterA handle to the child window specifying a place to begin searching. Searching begins with the child window immediately after this window in the Z-order. If this is 0, searching begins with the child window at the top of the Z-order. lpszClassThe name of the window class of the window to find. Specify a null string to ignore the class. lpszWindowThe name of the title bar text of the window to find. Specify a null string to ignore the window's title.
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
En revenant par hasard sur ce sujet, je vois ta remarque:
A par la différence entre Byval et Byref ou je dois encore bosser pour comprendre la subtilité entre les deux.

La différence est kolossale :)

Un argument ByVal (par valeur) sera transmis à la fonction par copie de la valeur passée à l'appel dans la variable locale à la fonction portant le nom du paramètre, après éventuelle implicite conversion par le compilateur.
Fonction(ByVal v as integer)
Call Fonction(x) -> v et x sont 2 zones mémoire différentes, x sera copié dans la zone locale à la fonction attribuée à v.
Dans la fonction, les modifications apportées à v ne modifient pas x.

Un argument ByRef (par référence ou pointeur) sera transmis à la fonction directement.
Fonction(ByRef v as integer)
Call Fonction(x) -> x et v représentent la même zone mémoire et doivent donc être du même type.
Dans la fonction, les modifications apportées à v modifient x.
C'est une manière par exemple, d'avoir des valeurs de retour de la fonction sans en utiliser le return.
 

patricktoulon

XLDnaute Barbatruc
re
perso je ne me sert que de byval , byref c'est par défaut si c'est omis

après
si le demandeur comprend un peu les api classique (et tu en fait une demo dans l'autre discussion
avec getwindow (5 et 2) sur handle de départ dans un do loop on choppe la/une des fenêtres fille

le send message convient après parfaitement
 

treza88

XLDnaute Occasionnel
Merci patricktoulon pour tes infos supplémentaires, mais j'ai essayé de trouver des exemples ,et je n'ai rien trouver pour que je puisse constituer un code pour faire des essayes.
Mes compétences sont trop limité pour faire le lien avec tes infos.
Désolé de ne pas arriver a suivre ta démarche.
Mais encore merci.
 

treza88

XLDnaute Occasionnel
Merci Dudu2 pour tes précisions sur byval et byref

Oui je la connait c'est celle que j'ai appelé plus bas fenêtre principale.

Sinon je suis toujours sur ce même code par contre j'ai un soucis en fonction de la présence ou pas de la fenêtre de deuxième niveau que je vais appeler "fenetre a fermer"
Si le fenêtre de second niveau est ouverte le code fonctionne par contre si elle n'existe pas le code ne fait rien, donc j'ai essayé ceci, mais çà ne fonctionne pas.
je n'arrive pas a afficher la fenêtre principale si la fenêtre de second niveau n'existe pas.
Avez vous une idée pour m'aider.
Mais peut être que mon code pour afficher la fenêtre principale n'est pas très correct.
voici le code:

VB:
Application.EnableEvents = True
Const WM_SETFOCUS As Long = &H7
Const WM_CLOSE As Integer = &H10
Dim Fenrun2
FenRun = FindWindow(vbNullString, "fenetre a fermer")

    Do
  Call SendMessage(FenRun, WM_CLOSE, 0, 0)
      DoEvents
    Loop While FenRun <> FindWindow(vbNullString, "fenetre a fermer")

Fenrun2 = FindWindow(vbNullString, "fenetre principale")
Call SendMessage(Fenrun2, WM_SETFOCUS, 0, 0)
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
que dit le debug avec ceci
VB:
#If VBA7 Then
    Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal uCmd As Long) As LongPtr
    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
    Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
#Else
    Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal uCmd As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
#End If
Sub testx()
'Application.EnableEvents = True
    Dim fen_Mère&, fen_Fille&, nom$
    Const WM_SETFOCUS As Long = &H7
    Const WM_CLOSE As Integer = &H10
    nom = Space(100)

    fen_Mère = FindWindow(vbNullString, "fenetre principale")    'adapter le titre de la fenetre ici
    'fen_Mère = Application.hwnd   'test avec l'application.hwnd 'directe

    fen_Fille = GetWindow(fen_Mère, 5)    'on passe a l'etage inferieur (les fenetres enfant)

    Do While Not fen_Fille = 0    'on passe en revue  les suivantes dans le meme etage
        'Recherche du nom de l'objet
        Longueur = GetClassName(fen_Fille, nom, 200)
        Debug.Print fen_Fille & "--->" & Trim(nom)
        fen_Fille = GetWindow(fen_Fille, 2)
    Loop


    'Conbient de handle arrive dans la console "debug"??????????????????



    'LAISSER BLOQUE CE QUI SUIT POUR L INSTANT
    'Do While Not fen_Fille = 0'ferme toutes les fenetre fille
    'Call SendMessage(fen_Fille, WM_CLOSE, 0, 0)
    'DoEvents
    'Loop
    'Call SendMessage(fen_fille, WM_CLOSE, 0, 0)'laisser bloqué pour l'instant
    'Call SendMessage(fen_Mère, WM_SETFOCUS, 0, 0)'laisser bloqué pour l'instant


End Sub
 

treza88

XLDnaute Occasionnel
voici ce que j'obtiens:

459884--->Afx:StatusBar:400000:8:10003:10
524938--->Afx:DockPane:400000:8:10003:10
656718--->Afx:DockPane:400000:8:10003:10
263410--->Afx:DockPane:400000:8:10003:10
264084--->Afx:DockPane:400000:8:10003:10
919442--->AfxMDIFrame140 0000:8:10003:10
 

Discussions similaires

Réponses
8
Affichages
627

Statistiques des forums

Discussions
312 113
Messages
2 085 430
Membres
102 889
dernier inscrit
monsef JABBOUR