SetParent hWndApp, Picture1.hWnd NE FONCTIONNE PAS

Résolu
cs_didine13 Messages postés 96 Date d'inscription mardi 18 août 2009 Statut Membre Dernière intervention 14 août 2013 - 30 août 2010 à 15:24
cs_didine13 Messages postés 96 Date d'inscription mardi 18 août 2009 Statut Membre Dernière intervention 14 août 2013 - 31 août 2010 à 18:14
Bonjour,

Je cherche à exécuter un exe virtual (dans un RES) grâce BoxedApp SDK et l’ouvrir dans la même form de mon application, le fichier exe s’ouvre mais ne veut pas s’intégrer dans mon application ni dans une form normal ni dans un mdi ni un picturebox.
J’ai déjà posé la question sur le forum de BoxedApp SDK mais je n’est pas eu de reponse.
Par contre il donne un code mais pour c++, moi je suis zéro en c++
Pouvez-vous m’aider SVP
DEMO http://boxedapp.com/download/boxedappsdk__demo.zip

MON CODE VB6
Private Sub Form_Load()
Dim hInst As Long, hWndApp As Long
BoxedAppSDK_Init
Dim hModule As Long
Dim hResInfo As Long
Dim hResData As Long
Dim lpImageData As Long
Dim dwImageSize As Long

hModule =  GetModuleHandle("MonProg")

hResInfo = FindResource(hModule, "MG", "IM")
hResData = LoadResource(hModule, hResInfo)
lpImageData = LockResource(hResData)
dwImageSize = SizeofResource(hModule, hResInfo)

BoxedAppSDK_EnableOption DEF_BOXEDAPPSDK_OPTION__ALL_CHANGES_ARE_VIRTUAL, True
Dim hfile As Long
hfile = CreateFile("ExeVir.exe", GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0)
Dim temo As Long

WriteFile hfile, lpImageData, dwImageSize, Temp, 0
BoxedAppSDK_EnableOption DEF_BOXEDAPPSDK_OPTION__ALL_CHANGES_ARE_VIRTUAL, False
BoxedAppSDK_EnableOption DEF_BOXEDAPPSDK_OPTION__EMBED_BOXEDAPP_IN_CHILD_PROCESSES, True

'hInst = Shell("ExeVir.exe")
'hInst = Shell("ExeVir.exe", vbNormalFocus)

ShellExecute picPrinc.hWnd, "open", "ExeVirtual.exe", ByVal 0&, 0&, 1
hWndApp = GetWinHandle(hInst)

'With an external application it works App.Path & "\ExeVirtual.exe"
SetParent hWndApp, Picture1.hWnd
Me.Caption = GetText(hWndApp)
End Sub




CODE C++
BoxedAppSDK_Init();  
HMODULE hModule  = GetModuleHandle(NULL);  
HRSRC hResInfo = FindResource(hModule, _T("BIN1"), _T("BIN"));  
HGLOBAL hResData = LoadResource(hModule, hResInfo);  
LPVOID lpData = LockResource(hResData);  
DWORD dwSize = SizeofResource(hModule, hResInfo);  
HANDLE hFile =   
   BoxedAppSDK_CreateVirtualFile(  
      _T("app1.exe"),   
      GENERIC_WRITE,   
      FILE_SHARE_READ,   
      NULL,   
      CREATE_NEW,   
      0,   
      NULL);  
DWORD temp;  
WriteFile(hFile, lpData, dwSize, &temp, NULL);  
CloseHandle(hFile);  
ShellExecute(NULL, NULL, _T("app1.exe"), NULL, NULL, SW_SHOW);  

9 réponses

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
31 août 2010 à 16:06
Allez, je te code la chose :
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (lpClassName As Any, lpWindowName As Any) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function SetWindowText Lib "user32.dll" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long
Private Declare Function WaitForInputIdle Lib "user32.dll" (ByVal hProcess As Long, ByVal dwMilliseconds As Long) As Long

Private Const PROCESS_QUERY_INFORMATION As Long = (&H400)
Private Const PROCESS_VM_READ As Long = (&H10)
Private Const GW_HWNDNEXT As Long = 2&

Private Sub Form_Load()
Dim hPid As Long
Dim hTestPid As Long
Dim hProcess As Long
Dim hOpenedWindow As Long
    '# Shell renvoie un Process ID, identifiant global au niveau de Windows
    hPid = Shell("calc.exe")
    '# On demande la création d'un handle propre a ton application et son espace mémoire
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, hPid)
    If hProcess <> -1 Then
        '# On va attendre que le process soit en état de répondre : que sa fenetre existe bien et réponde.
        Do
            DoEvents
        Loop While WaitForInputIdle(hProcess, 200)
        '# On libère le hProcess
        CloseHandle hProcess
        
        '# On récupère la première fenetre du poste
        hOpenedWindow = FindWindow(ByVal 0&, ByVal 0&)
        Do While hOpenedWindow
            '# Si nous faisons bien face a une fenetre de niveau 0
            If GetParent(hOpenedWindow) = 0& Then
                '# On récupère le ProcessID de la fenetre considérée
                GetWindowThreadProcessId hOpenedWindow, hTestPid
                '# Si elle appartient au processus que nous avons lancé...
                If hTestPid = hPid Then
                    '# On quitte la boucle
                    Exit Do
                End If
            End If
            '# Sinon,  on passe a la fenetre suivante
            hOpenedWindow = GetWindow(hOpenedWindow, GW_HWNDNEXT)
        Loop
        
        '# On modifie le titre de la calculatrice, pour bien voir que nous avons trouvé son Handle.
        If hOpenedWindow Then
            SetWindowText hOpenedWindow, "HANDLE de la calculatrice trouvé...."
        Else
            MsgBox "Fenetre non trouvée"
        End If
    End If
End Sub



Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
1
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
30 août 2010 à 15:40
ton GetWinHandle tiens il bien compte du fait qu'il faut attendre un minimum de temps avant que la fenetre ne soit crée... ?

je pense que non, tout simplement ^^

en gros, tu lance l'exe et cherche la fenetre en même temps...

ajoutes un WaitForInputIdle entre l'appel et la recherche de la fenetre, ca devrait aider.

pour t'en convaincre, tentes ton SetParent avec la valeur en dure du hWnd de la fenetre a incorporer... (recuperable via Spy++ par exemple)


Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
cs_didine13 Messages postés 96 Date d'inscription mardi 18 août 2009 Statut Membre Dernière intervention 14 août 2013
31 août 2010 à 08:53
Salut Renfield,

Voila j'ai essayé avec WaitForInputIdle mais rien ne ce passe je me demande si elle est bien écrite, mais avec un simple sleep ça fonctionne (sleep 1000)


Call WaitForInputIdle(hWndApp, 1000)
ou
Call WaitForInputIdle(hWndApp, INFINITE)
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
31 août 2010 à 11:26
la question est simple, au final, retrouves-tu bien le handle de ta fenetre, avant de faire ton SetParent ?

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_didine13 Messages postés 96 Date d'inscription mardi 18 août 2009 Statut Membre Dernière intervention 14 août 2013
31 août 2010 à 14:22
Oui je peut récupérer le handle grâce au sleep mais, je voudrais la fonction WaitForInputIdle que je n'arrive toujours pas a utilisé.
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
31 août 2010 à 14:33
ben tu fais une simple boucle...

Do
    DoEvents
Loop While WaitForInputIdle(hProcess, 200)


en utilisant comme hProcess la valeur de ton handle de process...

voir ShellExecuteEx

qu'utilises-tu pour rechercher ensuite la bonne fenetre ? te faut un EnumWindows, qui testes avec GetWindowThreadProcessId si la fenetre enumerée est bien issue de ton process cible.

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
cs_didine13 Messages postés 96 Date d'inscription mardi 18 août 2009 Statut Membre Dernière intervention 14 août 2013
31 août 2010 à 15:08
Merci Renfield mais ça ne fonction toujours pas
quand j'utilise le code plus bas la fentre principale ne s'affiche plus mais, je la vois dans gestion des taches et l'autre fenêtre s'affiche comme d'habitude (seule)

Do
    DoEvents
Loop While WaitForInputIdle(hProcess, 200)




hInst = Shell("ExeVir.exe")
'Sleep 1000 
Do
DoEvents
Loop While WaitForInputIdle(hProcess, 200)
'Call WaitForInputIdle(hProcess, 200)
' Pour rechercher ensuite la bonne fenêtre
hWndApp1 = FindWindowEx(hWndApp, 0&, vbNullString, "MonProg") ' c'est la Caption de l'application
SetParent hWndApp1, Me.hWnd
Sleep 10
hWndApp = hWndApp1
Me.Caption = GetText(hWndApp)



Voila un exemple qui date hier sans modifications d'aujourd'hui

http://rapidshare.com/files/416081675/proj.rar
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
31 août 2010 à 15:53
Comment récupères tu ton hProcess ?

comme je te le conseilles, ne passes pas par un FindWindow, pour bien cibler la fenetre de l'instance du soft que tu as lancé.

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
0
cs_didine13 Messages postés 96 Date d'inscription mardi 18 août 2009 Statut Membre Dernière intervention 14 août 2013
31 août 2010 à 18:14
Renfield tu est chef bravo et 1000 Mercis a toi
0
Rejoignez-nous