2010-07-16 6 views
7

Dieses "einfache" Problem scheint mit Nebenfragen behaftet zu sein.
z. Öffnet der neue Prozess mehrere Fenster; Hat es einen Begrüßungsbildschirm?
Gibt es einen einfachen Weg? (Ich bin eine neue Instanz von Notepad starten ++)Wie bekomme ich hWnd von Fenster geöffnet von 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? 
} 
... 

Antwort

12

Erster Einsatz WaitForInputIdle Ihr Programm pausieren, bis die Anwendung gestartet wurde und wartet auf eine Benutzereingabe (das Hauptfenster von dann erstellt werden sollte), dann verwenden EnumWindows und GetWindowThreadProcessId um festzustellen, welche Fenster im System zum erstellten Prozess gehören.

Zum Beispiel:

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

Dank Jon ... So kurzes Intervall Polling ist der Weg zu gehen ... das macht Sinn :) –

+0

ich jetzt durch Ihr Beispiel gerade arbeite ... und eine PS zu meinem vorherigen Kommentar: Ich habe gerade in MSDN bemerkt: WaitForInputIdle kann jederzeit verwendet werden, nicht nur während des Anwendungsstarts. WaitForInputIdle wartet jedoch nur einmal darauf, dass ein Prozess inaktiv wird. nachfolgende WaitForInputIdle-Aufrufe kehren sofort zurück, unabhängig davon, ob der Prozess inaktiv oder beschäftigt ist. * Es scheint, Umfrage ist keine gute Idee ... Ich werde ein paar Tests machen. –

+0

Sie sollten WaitForInputIdle nur verwenden, wenn der Prozess erstellt wird. Von nun an rufen Sie einfach den EnumWindows-Aufruf ab, um die aktualisierte Fensterliste zu erhalten. –