-1

如何在 没有鼠标和键盘焦点和交互的情况下创建/生成Win32进程?

有人可以提到最合适的Win API函数来创建窗口进程而不让它显示为最顶层的窗口,但留在其他打开的窗口中吗?

(假设您必须生成/创建一个 窗口(不是全屏)Direct3D程序可执行文件的进程,并且该程序由父程序终止,因此不需要用户交互而是自动化,因此当它被创建时,它应该显示在其他已经打开的窗口后面)。

4

1 回答 1

0

使用非活动 SW_* 值启动进程是不够的,但如果您是前台窗口,您也可以调用LockSetForegroundWindow禁用SetForegroundWindow

void backgroundcalc_simple()
{
    LockSetForegroundWindow(LSFW_LOCK);
    ShellExecute(NULL, NULL, TEXT("Calc"), NULL, NULL, SW_SHOWNA);
    // Cannot unlock here without a hacky call to Sleep
}

如果您的应用程序不需要,SetForegroundWindow那么您不必解锁,但无论如何这样做可能是个好主意:

BOOL CALLBACK ProcessHasVisibleWindowProc(HWND hWnd, LPARAM Param)
{
    if (IsWindowVisible(hWnd) && (WS_CAPTION & GetWindowLongPtr(hWnd, GWL_STYLE)))
    {
        DWORD thispid, *wantedpid = (DWORD*) Param;
        if (GetWindowThreadProcessId(hWnd, &thispid) && thispid == *wantedpid)
        {
            *wantedpid = 0;
            return FALSE;
        }
    }
    return TRUE;
}
BOOL ProcessHasVisibleWindow(DWORD Pid)
{
    if (!Pid) return FALSE;
    EnumWindows(ProcessHasVisibleWindowProc, (LPARAM) &Pid);
    return Pid == 0;
}

BOOL WaitForVisibleProcessWindow(DWORD Pid, DWORD Timeout)
{
    DWORD start = GetTickCount();
    for (;;)
    {
        if (ProcessHasVisibleWindow(Pid)) return TRUE;
        if (GetTickCount() - start >= Timeout && Timeout != INFINITE) break;
        Sleep(50);
    }
    return FALSE;
}

void backgroundcalc()
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_FORCEOFFFEEDBACK|STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOWNA;
    WCHAR cmd[MAX_PATH];
    lstrcpy(cmd, TEXT("Calc"));
    LockSetForegroundWindow(LSFW_LOCK);
    if (CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
    {
        WaitForInputIdle(pi.hProcess, 3333);
        WaitForVisibleProcessWindow(pi.dwProcessId, 1000*10);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    LockSetForegroundWindow(LSFW_UNLOCK);
}
于 2017-09-15T10:35:30.930 回答