PDA

View Full Version : [VB6] Avviare applicazione esterna in una form


andreapav
29-12-2014, 14:17
Ciao a tutti.

Ho due vecchie applicazioni in VB6, devo integrare una nell'altra e volevo semplicemente avviare la seconda in una form della prima.

Ho iniziato usando notepad come esempio, avvio correttamente l'exe ma non riesco a cambiargli il parent..non capisco cosa sbaglio.
Il codice è:

pid = Shell("notepad.exe")
SetParent pid, frmMDI.hwnd
MoveWindow pid, 0, 1000, frmMDI.ScaleWidth, frmMDI.ScaleHeight, 1


Grazie in anticipo.

Daniels118
29-12-2014, 14:47
Prima di tutto fai un test sul valore di ritorno, se restituisce null chiama GetLastError per ottenere informazioni sull'errore.
Poi, devi utilizzare le funzioni GetWindowLong e SetWindowLong per azzerare il bit WS_POPUP e impostare il bit WS_CHILD. Come se non bastasse, devi utilizzare SetWindowPos con il flag SWP_FRAMECHANGED.

andreapav
29-12-2014, 15:45
Grazie, ma non mi è chiaro cosa fanno questi due metodi e come li devo usare.

A occhio ho provato con:
gwl = GetWindowLong(pid, GWL_HINSTANCE)
per prendere l'istanza (anche con GWL_WNDPROC), e poi
swl = SetWindowLong(pid, GWL_HWNDPARENT, frmMDI.hwnd)
per aggiornargli il parent. Infine
swp = SetWindowPos(pid, HWND_TOP, 0, 1000, 0, 0, SWP_FRAMECHANGED)
per modificargli la posizione. Non vedo nulla di diverso.

gwl così però non serve a nulla, ma se lo uso al posto di pid ho errori.

Daniels118
29-12-2014, 16:33
Come dicevo devi utilizzare le funzioni GetWindowLong e SetWindowLong per azzerare il bit WS_POPUP e impostare il bit WS_CHILD:
style = GetWindowLong(myWindow, GWL_STYLE)
style = style And Not WS_POPUP
style = style Or WS_CHILD
SetWindowLong(myWindow, GWL_STYLE, style)
Rivedendo il tuo codice mi sono accorto che stai passando a SetParent il pid invece dell'handle, devi scrivere ancora un po' di codice:
http://msdn.microsoft.com/en-us/magazine/cc301495.aspx

andreapav
07-01-2015, 10:17
Ciao.
Riporto nel caso possa essere utile in futuro, la soluzione.

Option Explicit

Private my_lang As String ' indica la lingua corrente della form

''''''''''''''''''''''''''''''''''''''''''''''''''''''

Const GW_HWNDNEXT = 2
Const SW_SHOW = 5

'Const WS_THICKFRAME = &H40000
Const WS_CLIPSIBLINGS = &H4000000
Const WS_CLIPCHILDREN = &H2000000
Const WS_VISIBLE = &H10000000
Const WS_DISABLED = &H8000000
Const WS_MINIMIZE = &H20000000
Const WS_MAXIMIZE = &H1000000
Const WS_CAPTION = &HC00000
Const WS_BORDER = &H800000
Const WS_DLGFRAME = &H400000
Const WS_VSCROLL = &H200000
Const WS_HSCROLL = &H100000
Const WS_SYSMENU = &H80000
Const WS_THICKFRAME = &H40000
Const WS_MINIMIZEBOX = &H20000
Const WS_MAXIMIZEBOX = &H10000


Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd 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 GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwprocessid As Long) As Long

Function ProcIDFromWnd(ByVal hwnd As Long) As Long
Dim idProc As Long

' Get PID for this HWnd
GetWindowThreadProcessId hwnd, idProc

' Return PID
ProcIDFromWnd = idProc
End Function

Function GetWinHandle(hInstance As Long) As Long
Dim tempHwnd As Long

' Grab the first window handle that Windows finds:
tempHwnd = FindWindow(vbNullString, vbNullString)

' Loop until you find a match or there are no more window handles:
Do Until tempHwnd = 0
' Check if no parent for this window
If GetParent(tempHwnd) = 0 Then
' Check for PID match
If hInstance = ProcIDFromWnd(tempHwnd) Then
' Return found handle
GetWinHandle = tempHwnd
' Exit search loop
Exit Do
End If
End If

' Get the next window handle
tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT)
Loop
End Function

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub Command1_Click()

Dim hWndChild As Long
Dim hInst As Long

' run/show application (get handler)
hInst = Shell(frmMDI.ExtApplicationPath)
hWndChild = GetWinHandle(hInst)

Call SetParent(hWndChild, Me.hwnd)

' remove control box..
Dim NewStyle As Long
NewStyle = SetWindowLong(hWndChild, GWL_STYLE, WS_VISIBLE Or WS_CLIPSIBLINGS)

' window resize...
Call ShowWindow(hWndChild, SW_MAXIMIZE)

End Sub

andreapav
07-01-2015, 10:42
Riguardo al FindWindow, se necessario, definire la caption della form che si sta cercando:

tempHwnd = FindWindow(vbNullString, frmMDI.ExtApplicationCaption)