SetParent hWndApp, Picture1.hWnd NE FONCTIONNE PAS [Résolu]

cs_didine13 96 Messages postés mardi 18 août 2009Date d'inscription 14 août 2013 Dernière intervention - 30 août 2010 à 15:24 - Dernière réponse : cs_didine13 96 Messages postés mardi 18 août 2009Date d'inscription 14 août 2013 Dernière intervention
- 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);  
Afficher la suite 

9 réponses

Répondre au sujet
Renfield 17307 Messages postés mercredi 2 janvier 2002Date d'inscription 18 janvier 2017 Dernière intervention - 31 août 2010 à 16:06
+1
Utile
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
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de Renfield
Renfield 17307 Messages postés mercredi 2 janvier 2002Date d'inscription 18 janvier 2017 Dernière intervention - 30 août 2010 à 15:40
0
Utile
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
Commenter la réponse de Renfield
cs_didine13 96 Messages postés mardi 18 août 2009Date d'inscription 14 août 2013 Dernière intervention - 31 août 2010 à 08:53
0
Utile
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)
Commenter la réponse de cs_didine13
Renfield 17307 Messages postés mercredi 2 janvier 2002Date d'inscription 18 janvier 2017 Dernière intervention - 31 août 2010 à 11:26
0
Utile
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
Commenter la réponse de Renfield
cs_didine13 96 Messages postés mardi 18 août 2009Date d'inscription 14 août 2013 Dernière intervention - 31 août 2010 à 14:22
0
Utile
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é.
Commenter la réponse de cs_didine13
Renfield 17307 Messages postés mercredi 2 janvier 2002Date d'inscription 18 janvier 2017 Dernière intervention - 31 août 2010 à 14:33
0
Utile
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
Commenter la réponse de Renfield
cs_didine13 96 Messages postés mardi 18 août 2009Date d'inscription 14 août 2013 Dernière intervention - 31 août 2010 à 15:08
0
Utile
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
Commenter la réponse de cs_didine13
Renfield 17307 Messages postés mercredi 2 janvier 2002Date d'inscription 18 janvier 2017 Dernière intervention - 31 août 2010 à 15:53
0
Utile
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
Commenter la réponse de Renfield
cs_didine13 96 Messages postés mardi 18 août 2009Date d'inscription 14 août 2013 Dernière intervention - 31 août 2010 à 18:14
0
Utile
Renfield tu est chef bravo et 1000 Mercis a toi
Commenter la réponse de cs_didine13

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.