【问题标题】:How to get hWnd of window opened by ShellExecuteEx.. hProcess?如何获得由 ShellExecuteEx .. hProcess 打开的窗口的 hWnd?
【发布时间】:2011-03-17 05:04:57
【问题描述】:

这个“简单”的问题似乎充满了附带问题。
例如。新进程是否打开多个窗口;它有启动画面吗?
有简单的方法吗? (我正在启动一个新的 Notepad++ 实例)

...
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?
}
...

【问题讨论】:

    标签: c++ process window handle


    【解决方案1】:

    首先使用WaitForInputIdle 暂停您的程序,直到应用程序启动并等待用户输入(此时应该已经创建了主窗口),然后使用EnumWindowsGetWindowThreadProcessId 确定哪些窗口在系统属于创建的进程。

    例如:

    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.....
    }
    

    【讨论】:

    • 谢谢乔恩...如此短的间隔轮询是要走的路...这是有道理的:)
    • 我现在正在研究您的示例......以及对我之前评论的 PS:我刚刚在 MSDN 中注意到:WaitForInputIdle 可以随时使用,而不仅仅是在应用程序启动期间。然而,WaitForInputIdle 只等待进程空闲一次;随后的 WaitForInputIdle 调用立即返回,无论进程是空闲还是忙碌。 * 轮询似乎不是一个好主意……我会做一些测试。
    • 您应该只需要在创建进程时使用WaitForInputIdle。从那时起,只需轮询 EnumWindows 调用即可获取更新的窗口列表。
    • 太棒了 :) 整洁甜美! ...(但我没有足够的分数来标记它,(还)。
    • 我使用了你的代码,它工作正常,但在 ShellExecuteEx 完成后 hProcess 始终为 0。什么给了?
    猜你喜欢
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    • 2013-07-13
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多