Создать процесс без клавиатуры и мыши, взаимодействия и фокуса

Как создать / порождать процесс Win32 без фокусировки и взаимодействия мыши и клавиатуры?

Может кто-то упомянул наиболее подходящую функцию Win API для создания оконного процесса, не отображая его как верхнее окно, но оставаясь позади в других открытых окнах?

(Предположим, что вам нужно порождать / создавать процесс оконной(не полноэкранной) исполняемой программы Direct3D, и эта программа завершается родительской программой, поэтому нет необходимости во взаимодействии с пользователем, но автоматизируется, поэтому при ее создании она должна отображаться за другими уже открытыми окнами).

1 ответ

Запуск процесса с неактивным значением 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);
}
Другие вопросы по тегам