В моем приложении 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
}
Этот код прекрасно восстановил окно переднего плана, но мне не нравится константа, которую я должен использовать в качестве параметра Спать функция.
Как следствие, Второй вопрос: Можно ли «разбудить» поток в тот момент, когда игрок инициализируется? В качестве альтернативы, как мне определить время, необходимое для инициализации игрока (учитывая, что игроком по умолчанию может быть что угодно, и для начала потребуется совсем другое время)?
Замечания:
Первый вопрос: возможно ли принудительно открывать плеер в «тихом» режиме (свернутым и не активным)?
Нет, лучшее, что вы можете сделать, это запросить его, и запросы можно игнорировать. Вы уже обнаружили эту часть.
Второй вопрос: можно ли «разбудить» нить в тот момент, когда проигрыватель инициализируется?
Нет, момент, когда процесс полностью инициализирован, не определен. Вы уже обнаружили WaitForInputIdle
и его ограничения. Но представьте себе медиаплеер, который извлекает изображение обложки компакт-диска в фоновом режиме (не так уж надуманно, для этого не нужно задерживать звук) — когда он завершит инициализацию?
Кроме того, имейте в виду, что ShellExecute
может даже не начать новый процесс. Если он существует, он может использовать его для открытия файла.
Других решений пока нет …