Windows — Как принудительно открыть файл & quot; молча & quot; (свернуто, не активно) с использованием функционала c ++ WinAPI?

В моем приложении WinAPI C ++ я пытаюсь открыть аудиофайл с помощью системного плеера по умолчанию, используя ShellExecuteEx:

int OpenFileWithDefaultProgram(const std::wstring& path, int showMode, HANDLE* hProc) {
SHELLEXECUTEINFO shInfo;
::ZeroMemory(&shInfo, sizeof(SHELLEXECUTEINFO));
shInfo.cbSize = sizeof(SHELLEXECUTEINFO);
shInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shInfo.hwnd = NULL;
shInfo.lpVerb = L"open";
shInfo.lpFile = path.c_str();
shInfo.nShow = showMode;
::ShellExecuteEx(&shInfo);
*hProc = shInfo.hProcess;
return (int)shInfo.hInstApp;
}

OpenFileWithDefaultProgram функция называется так:

HANDLE hProc;
int error = OpenFileWithDefaultProgram(path, SW_SHOWMINNOACTIVE, &hProc);
if (error <= 32) {
// Process error
} else {
// Some actions
}

тем не мение SW_SHOWMINNOACTIVE Этот параметр игнорируется некоторыми проигрывателями (например, MediaPlayerClassic HomeCinema — MPC HC), что приводит к открытию проигрывателя с изменением окна переднего плана и даже отображением окна проигрывателя, не свернутого на некоторых ПК.

Первый вопрос: Можно ли принудительно открыть плеер в «тихом» режиме (свернутым и не активным)?

Я также пытался использовать GetForegroundWindow а также SetForegroundWindow, что не помогло, пока я не добавил Спать сразу после OpenFileWithDefaultProgram (как я понимаю, игроку нужно некоторое время для инициализации, и в течение этого времени окно переднего плана не меняется):

HWND hWndForeground = GetForegroundWindow();
HANDLE hProc;
int error = OpenFileWithDefaultProgram(path, SW_SHOWMINNOACTIVE, &hProc);
if (error <= 32) {
// Process error
} else {
Sleep(100);
SetForegroundWindow(hWndForeground);
// Some actions
}

Этот код прекрасно восстановил окно переднего плана, но мне не нравится константа, которую я должен использовать в качестве параметра Спать функция.

Как следствие, Второй вопрос: Можно ли «разбудить» поток в тот момент, когда игрок инициализируется? В качестве альтернативы, как мне определить время, необходимое для инициализации игрока (учитывая, что игроком по умолчанию может быть что угодно, и для начала потребуется совсем другое время)?

Замечания:

  • Я пробовал звонить WaitForSingleObject (hProc, INFINITE), он просто не заканчивает ожидание, так как проигрыватель не завершает работу после воспроизведения;
  • Я пробовал звонить WaitForInputIdle (hProc, INFINITE), немедленно возвращается без ожидания (возможно, так как у игрока нет очереди сообщений).

0

Решение

Первый вопрос: возможно ли принудительно открывать плеер в «тихом» режиме (свернутым и не активным)?

Нет, лучшее, что вы можете сделать, это запросить его, и запросы можно игнорировать. Вы уже обнаружили эту часть.

Второй вопрос: можно ли «разбудить» нить в тот момент, когда проигрыватель инициализируется?

Нет, момент, когда процесс полностью инициализирован, не определен. Вы уже обнаружили WaitForInputIdle и его ограничения. Но представьте себе медиаплеер, который извлекает изображение обложки компакт-диска в фоновом режиме (не так уж надуманно, для этого не нужно задерживать звук) — когда он завершит инициализацию?

Кроме того, имейте в виду, что ShellExecute может даже не начать новый процесс. Если он существует, он может использовать его для открытия файла.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]