2010-07-16 11 views
7

Questa "semplice" questione sembra essere irta di problemi collaterali.
es. Il nuovo processo apre più finestre; Ha uno splash screen?
C'è un modo semplice? (Sto iniziando una nuova istanza di Notepad ++)Come ottenere hWnd della finestra aperta da ShellExecuteEx .. hProcess?

... 
std::tstring tstrNotepad_exe = tstrProgramFiles + _T("\\Notepad++\\notepad++.exe"); 

SHELLEXECUTEINFO SEI={0}; 
sei.cbSize  = sizeof(SHELLEXECUTEINFO); 
sei.fMask  = SEE_MASK_NOCLOSEPROCESS; 
sei.hwnd   = hWndMe; // This app's window handle 
sei.lpVerb  = _T("open"); 
sei.lpFile  = tstrNotepad_exe.c_str();  
sei.lpParameters = _T(" -multiInst -noPlugins -nosession -notabbar "; 
sei.lpDirectory = NULL; 
sei.nShow  = SW_SHOW; 
sei.hInstApp  = NULL;  
if(ShellExecuteEx(&sei)) 
{ // I have sei.hProcess, but how best to utilize it from here? 
} 
... 

risposta

12

Primo utilizzo WaitForInputIdle per mettere in pausa il programma fino a quando ha iniziato l'applicazione ed è in attesa per l'input dell'utente (la finestra principale dovrebbe essere stato creato da allora), quindi utilizzare EnumWindows e GetWindowThreadProcessId per determinare quali finestre del sistema appartengono al processo creato.

Ad esempio:

struct ProcessWindowsInfo 
{ 
    DWORD ProcessID; 
    std::vector<HWND> Windows; 

    ProcessWindowsInfo(DWORD const AProcessID) 
     : ProcessID(AProcessID) 
    { 
    } 
}; 

BOOL __stdcall EnumProcessWindowsProc(HWND hwnd, LPARAM lParam) 
{ 
    ProcessWindowsInfo *Info = reinterpret_cast<ProcessWindowsInfo*>(lParam); 
    DWORD WindowProcessID; 

    GetWindowThreadProcessId(hwnd, &WindowProcessID); 

    if(WindowProcessID == Info->ProcessID) 
     Info->Windows.push_back(hwnd); 

    return true; 
} 

.... 

if(ShellExecuteEx(&sei)) 
{ 
    WaitForInputIdle(sei.hProcess, INFINITE); 

    ProcessWindowsInfo Info(GetProcessId(sei.hProcess)); 

    EnumWindows((WNDENUMPROC)EnumProcessWindowsProc, 
     reinterpret_cast<LPARAM>(&Info)); 

    // Use Info.Windows..... 
} 
+0

Grazie Jon ... così breve intervallo di polling è la strada da percorrere ... che abbia un senso :) –

+0

sto lavorando attraverso il vostro esempio ora ... e PS al mio commento precedente: ho appena notato in MSDN: WaitForInputIdle può essere utilizzato in qualsiasi momento, non solo durante l'avvio dell'applicazione. Tuttavia, WaitForInputIdle attende solo una volta che un processo diventi inattivo; le successive chiamate WaitForInputIdle ritornano immediatamente, indipendentemente dal fatto che il processo sia inattivo o occupato. * Sembra che il sondaggio non sia una buona idea ... Farò qualche test. –

+0

È necessario utilizzare WaitForInputIdle solo al momento della creazione del processo. Da quel momento in poi, basta interrogare la chiamata EnumWindows per ottenere l'elenco delle finestre aggiornate. –