Boucle d'attente de fin de programme externe

Résolu
Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 - 9 mai 2011 à 09:26
Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 - 9 mai 2011 à 14:32
Bonjour à tous,

Voila mon souci.

J'ai un diaporama réalisé à l'aide d'un programme externe et qui produit un fichier exécutable autonome. Celui-ci dure un peu plus d'une heure.
Il accepte une bande son qui n'est qu'un MP3 indépendant qui démarre en même temps mais continue même si l'on fait une pause dans le diaporama.

Mon souci est le suivant:
Ma dernière diapo attend un morceau spécifique (la chute des cartoons d'après guerre avec diapo adéquate). Comme il est à peu près certain que durant une heure il y a aura forcément des pauses, la synchro entre son et image sera cassée. Le souci est le même pour la 2ème diapo.

J'ai donc imaginé un petit lanceur en VB6 qui lance l'exécutable par ShellExecuteEx:

Pour la 2ème diapo, j'ai en fait créer un diaporama avec une seule diapo (la 1ère) que je lance avec mon lanceur et un timer, l'évènement Timer se charge de fermer le diaporama (par TerminateProcess puisque CloseProcess est inefficace). Puis je lance mon 2ème diaporama qui contient les diapos 2 à n-1.

A la fin de celui-ci je comptais lancer le 3ème diaporama qui contient la diapo de chute. Le gros souci est que mon prog VB6 continue son exécution après le ShellExecuteEx(), il faut donc rajouter une boucle qui attendrait la fin du diaporama. Mais celui-ci s'arrête sur la dernière photo et attend que je le ferme manuellement. Je peux le faire puisque de toutes façons c'est moi qui le présente, mais on niveau de mon prog VB que mettre en condition de boucle, puisque là un timer ne sert à rien ?

J'espère que j'ai été assez clair car ce n'est pas simple à expliquer.

Je précise que l'exécutable/diaporama a été construit à partir d'un soft écrit en Delphi d'après ce que j'ai pu voir.

Ci-dessous mon code pour la 1ère Diapo:
Private Sub cmdLaunch_Click()
   Me.Hide
   Call p_oSettings.SetIntegerSettings("LauncherStage", 1)
   With p_tShellInfo
      .cbSize = Len(p_tShellInfo)
      .lpVerb "open":                                     .nShow vbMaximized
      .fMask = SEE_MASK_NOCLOSEPROCESS
' Lancement 1ère Diapo
      .lpFile = "D:\Applications\VB6\Slides Launcher\Test Files\Intro Guadeloupe.exe"
   End With
   Call ShellExecuteEx(p_tShellInfo):                       tmrLaunch.Enabled = True
   Do
'     void()
      DoEvents
   Loop Until Not tmrLaunch.Enabled
   Me.Show
   With p_tShellInfo
      .cbSize = Len(p_tShellInfo)
      .lpVerb "open":                                     .nShow vbMaximized
      .fMask = SEE_MASK_NOCLOSEPROCESS
      .lpFile = "D:\Applications\VB6\Slides Launcher\Test Files\Sequel Guadeloupe.exe"
   End With
' Lancement Diapos 2 à n-1
   Call ShellExecuteEx(p_tShellInfo)
Do
   DoEvents
Until ????
' Ici lancement de la chute
   Unload Me
End Sub


Merci d'avance pour vos suggestions.

Calade

2 réponses

Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 10
9 mai 2011 à 11:01
Rebonjour,

Je pense avoir une idée qui vaut d'être creusé.

Mon diaporama étant toujours en ZOder(0), je dois pouvoir récupérer son hWnd par l'API
GetForegroundWindow() puisque le membre hWnd de ShellProcInfo est à 0.

static hWnd as long
if hwnd = 0 then
   hWnd = GetForeGroundWindow()
endif
do while GetForeGroundWindow() = hWnd
   ' le diaporama tourne encore
   DoEvents
enddo
' là le diaporama n° 2 ne tourne plus, on peut lancer le 3ème



Ma question, est-ce que vous pensez qu'avec ce code je ne risque pas d'avoir de problèmes avec les autres applications.
Je précise qu'en "exploitation", mon diaporama tournera sur un portable qui ne fera que ça.




Calade
3
Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 10
9 mai 2011 à 14:32
Encore moi,

J'ai trouvé.
Voici mon code:

   tmrSlides.Enabled = True
   Call ShellExecuteEx(p_tShellInfo)
   Do
'     void()
      DoEvents
   Loop Until (Not tmrSlides.Enabled)
   Call EnumDesktopWindows(0&, AddressOf EnumWindowsProc, P_hWndSlides)
   Do While P_blnSlidesFound
'     Void()
      DoEvents
      P_blnSlidesFound = False
      Call EnumDesktopWindows(0&, AddressOf EnumWindowsProc, P_hWndSlides)
   Loop

Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
   Dim lngTitleLength As Long, strTitle As String
   lngTitleLength = GetWindowTextLength(hWnd)
   strTitle = Space(250)
   Call GetWindowText(hWnd, strTitle, lngTitleLength + 1)
   strTitle = Left$(strTitle, InStr(strTitle, Chr$(0)) - 1)
   If strTitle = "Diaporama" Then
      If lParam = 0 Then
         P_hWndSlides hWnd:                               P_blnSlidesFound True
      Else
         If hWnd P_hWndSlides Then P_blnSlidesFound True
      End If
   End If
   EnumWindowsProc = (Not P_blnSlidesFound)
End Function



tmrSlides et un timer qui est activé juste avant de lancer le diaporama n° 2 et désactivé 5 secondes après, uniquement pour s'assurer qu'il a bien eu le temps de se lancer sinon il n'a pas le temps d'être répertorier dans l'EnumWindows.
Donc une fois sur que mon diaporama est bien lancé, je fais un 1er EnumWindows pour chercher sont hWnd. Une fois celui-ci trouvé, je vais bouclé indéfiniment sur enumwindows qui va comparer le hWnd trouvé la 1ère fois avec le handle passé dans cette proc récursive. Tant qu'il trouve que le diaporama tourne, je continue à boucler dans mon enumwindows. Dès qu'il ne le trouve plus, parce que je l'ai arrêté, il termine la boucle infernale et je pourrais lancer le 3ème et dernier diaporama.

Pour ceux que cela intéresse, j'ai mis le code de lancement et la fonction EnumWindowsProc à mettre dans un module.
Calade
0
Rejoignez-nous