Newsgroup: it.comp.lang.visual-basic
Titolo: [?2] Eseguire Applicazioni come MDI

Avevo visto tempo fa un esempio per eseguire delle applicazioni (nel caso il
Notepad) da VB "catturandole" come se fossero delle finestre MDIChild.
Praticamente c'era una form MDI che conteneva un'istanza del notepad.
Mi servirebbe proprio quello, ho da eseguire 15 applicazioni
contemporaneamente (da un progetto VB, ovviamente) e mi piacerebbe poterle
racchiudere tutte in un'unica finestra MDI.
Ho cercato sul Sito Comune ed in giro ma non l'ho trovato. Qualcuno mi puo'
aiutare?
Ciao e grazie 1000

 racchiudere tutte in un'unica finestra MDI.
prova utilizzando la funzione dell'API SetParent()
ricomponi il link seguente se lo vedi 'spezzato':
http://groups.google.com/groups?as_q=setasparent&num=10&as_scoring=d&btn
G=Google+Search&as_epq=&as_oq=&as_eq=&as_ugroup=it.comp.lang.visual-basi
c&as_usubject=&as_uauthors=faber&as_umsgid=&lr=&as_drrb=q&as_qdr=&as_min
d=29&as_minm=3&as_miny=1995&as_maxd=15&as_maxm=10&as_maxy=2001
Ciao
Faber

racchiudere tutte in un'unica finestra MDI.
In effetti ricordo anch' io di averlo visto da qualche parte, ma non ricordo dove.
Ho provato allora ad adattare e semplificare un codice c++ che fa proprio
questo lavoro.
Il codice vb e' sotto la firma: provalo un po' e se ti da' qualche problema 
fammi sapere.
-- 
hth, hal
---------------- inizio codice vb ---------------------
'
' In un form MDI scrivere quanto segue:
'
Option Explicit
Private Sub MDIForm_Load()
    CaptureApp Me.hwnd, "notepad.exe"
End Sub
'
' In un modulo .bas (non .cls perche' occorre passare a windows
' l' indirizzo di una funzione)
'
Option Explicit
Private Const GWL_STYLE = (-16)
Private Const GW_CHILD = 5
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const STARTF_USESHOWWINDOW = &H1
Private Const SW_HIDE = 0
Private Const SW_SHOW = 5
Private Type STARTUPINFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type
Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
End Type
Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type
Private Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" ( _
                            ByVal lpApplicationName As String, ByVal lpCommandLine As String, _
                            ByRef lpProcessAttributes As Any, _
                            ByRef lpThreadAttributes As Any, _
                            ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
                            ByRef lpEnvironment As Any, ByVal lpCurrentDirectory As String, _
                            ByRef lpStartupInfo As STARTUPINFO, _
                            ByRef lpProcessInformation As PROCESS_INFORMATION _
                            ) As Long
Private Declare Function EnumWindows Lib "user32" ( _
                            ByVal lpEnumFunc As Long, ByVal lParam As Long _
                            ) As Long
Private Declare Function SetParent Lib "user32" ( _
                            ByVal hWndChild As Long, _
                            ByVal hWndNewParent As Long _
                            ) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" ( _
                            ByVal hwnd As Long, ByVal nIndex As Long _
                            ) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _
                            ByVal hwnd As Long, ByVal nIndex As Long, _
                            ByVal dwNewLong As Long _
                            ) As Long
Private Declare Function ShowWindow Lib "user32" ( _
                            ByVal hwnd As Long, ByVal nCmdShow As Long _
                            ) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" ( _
                            ByVal hwnd As Long, ByRef lpdwProcessId As Long _
                            ) As Long
 
Private Const pNULL = 0&
Private m_id As Long
Private m_hWnd As Long
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function CaptureApp(ByVal a_hWndParent As Long, ByVal a_pathApp As String) As Boolean
    If (a_hWndParent = 0) Then Exit Function
 
    Dim sui As STARTUPINFO
    Dim pi As PROCESS_INFORMATION
    Dim mi_Style As Long
 
    sui.cb = LenB(sui)
    sui.dwFlags = STARTF_USESHOWWINDOW
    sui.wShowWindow = SW_HIDE
 
    If (0 = CreateProcess(vbNullString, a_pathApp, _
                        ByVal pNULL, ByVal pNULL, 1, NORMAL_PRIORITY_CLASS, _
                        ByVal pNULL, vbNullString, sui, pi)) Then Exit Function
 
    m_id = pi.dwProcessId
    Do While (m_hWnd = 0)
        If EnumWindows(AddressOf EnumWindowsCallback, 0) = 0 Then Exit Do
    Loop
 
    If m_hWnd = 0 Then Exit Function
 
    If (pNULL = SetParent(m_hWnd, a_hWndParent)) Then Exit Function
    mi_Style = GetWindowLong(m_hWnd, GWL_STYLE)
    If (0 = SetWindowLong(m_hWnd, GWL_STYLE, mi_Style Or GW_CHILD)) Then Exit Function
 
    CaptureApp = (0 <> ShowWindow(m_hWnd, SW_SHOW))
End Function    '// CaptureApp
Public Function EnumWindowsCallback(ByVal hwnd As Long, ByVal lParam As Long) As Long
    Dim id As Long
    If (m_id = 0) Then Exit Function
    If (hwnd = 0) Then Exit Function
    Call GetWindowThreadProcessId(hwnd, id)
    If (id = m_id) Then
        m_hWnd = hwnd
        EnumWindowsCallback = 0
    Else
        EnumWindowsCallback = 1
    End If
End Function    '// EnumWindowsCallback

fammi sapere.
Uff... l'hai già fatto o devi ancora farlo? Cosa aspetti? ;-P
Ciao,
Moreno
-- 
#sirri#@#
morenosoft.com#
(togliete "#" dall'indirizzo)
Moreno Sirri VB Site - 
http://www.msvbsite.net
---------------------------------------------------------------------------
Le risposte alle tue domande le trovi sul Sito Comune di questo NewsGroup:
 
http://www.it-lang-vb.net
---------------------------------------------------------------------------

 hth, hal
ZAC2


L'antispam fallo mixed case...
Del tipo
marco.ToG...@martek.it
che freghi il 99% dei bot intelligenti (che cercano una parola maiuscola
all'interno del nome o del dominio, un .invalid alla fine del dominio, un
simbolo invalido all'interno del testo, le parola spam, antispam, removeme e
un po' di altre)...
Anche la versione inglese ReMoVeMeTORepLY puo' andar bene, che sei
internazionale :P
Ciaotutti,
*

>If (0 = SetWindowLong(m_hWnd, GWL_STYLE, mi_Style Or GW_CHILD)) Then Exit
Function
In questo passaggio mi esce dalla funzione. Pero' ho provato cosi' al volo,
non ho avuto tempo di guardarlo in dettaglio.
Ciao.

Ho provato, ma non mi e' riuscito di farlo funzionare correttamente, la
SetWindowLong mi ritorna sempre 0.
Commentandola ho notato che il Notepad aperto e' gia' un MDI child, sbaglia
solo il resize ed il move della finestra


solo il resize ed il move della finestra
Lo immagino :-)
Avrei bisogno di sapere il sitema operativo ed il codice di errore dell' api
(Err.LastDllError oppure GetLastError()).
-- 
ciao, hal

mi posti il codice c++ ( o il link) thanks!
Dato che ho perso il link :-( consumero' un po' di banda :-P
Il codice e' sotto la firma.
-- 
ciao, hal
------------------ INIZIO CODICE -------------------
HWND	m_LookHWnd;
DWORD	m_id;
BOOL CALLBACK EnumWindowsCallback( HWND hwnd,LPARAM lParam)
{
	DWORD id;
	GetWindowThreadProcessId(hwnd,&id);
	if(m_LookHWnd)
		return 0;
	if(id==m_id)
	{
		m_LookHWnd=hwnd;
		return 0;
	}
	return 1;
}
void CTestDlg::OnRun()
{
	if(m_LookHWnd)
		return ;
	ZeroMemory(&m_si,sizeof(STARTUPINFO));
	ZeroMemory(&m_pi,sizeof(PROCESS_INFORMATION));
	m_LookHWnd=0;
	m_si.cb=sizeof(STARTUPINFO);
	m_si.dwFlags=STARTF_USESHOWWINDOW;
	m_si.wShowWindow=SW_HIDE;
	CreateProcess(NULL,"notepad",NULL,NULL,true,0,NULL,NULL,&m_si,&m_pi);
	m_id=m_pi.dwProcessId;
	while(!m_LookHWnd)
		EnumWindows(&EnumWindowsCallback,0);
	::SetParent(m_LookHWnd,m_hWnd);
	LONG ret=::GetWindowLong(m_LookHWnd,GWL_STYLE);
	ret=::SetWindowLong(m_LookHWnd,GWL_STYLE,ret);
	::ShowWindow(m_LookHWnd,SW_SHOW);
}
--------------------- FINE CODICE -------------

(Err.LastDllError oppure GetLastError()).
Mi rispondo da solo: avrei dovuto leggere la documentazione di SetWindowLong:
per punizione scrivero' cento volte RTFM !
"
Windows 95/98/Me: The SetWindowLong function may fail if the window specified by the 
hWnd parameter does not belong to the same process as the calling thread. 
"
Ritengo percio' molto probabile che tu ricada nella casistica suesposta :-(
In compenso ho trovato un esempio di Ray Mercer che, pero', non funziona
correttamente sotto nt 4 e 5:
http://www.shrinkwrapvb.com/kidnap.htm
Fai un po' di prove, eventualmente ne riparliamo.
-- 
hth, hal

 Fai un po' di prove, eventualmente ne riparliamo.
Ok, grazie 1000.