Как глобально отключить и включить звук в Vista и 7, и получить состояние отключения звука? - PullRequest
3 голосов
/ 27 февраля 2010

Я использую старый добрый API Mixer прямо сейчас, но он не работает должным образом в Windows Vista и 7 в обычном режиме, а не в режиме совместимости с XP. Он отключает звук только для текущего приложения, но мне нужно глобальное (аппаратное) отключение звука. Как достичь цели? Есть ли способ кодировать это без COM-интерфейсов и странных вызовов на чистом C / C ++?

Ответы [ 2 ]

4 голосов
/ 27 февраля 2010

Аудиостек значительно переписан для Vista. Громкость и отключение звука для каждого приложения действительно были одной из новых функций. Для использования странного интерфейса IAudioEndpointVolume потребуется .

.
0 голосов
/ 17 июня 2014

Я недавно имел дело с этой же проблемой. У нас есть приложение для Windows, которое использует звуковую систему для сигнализации. Мы не можем вынести случайного отключения звука пользователем. Вот как я смог использовать предложенный выше интерфейс для решения этой проблемы:

Во время инициализации я добавил функцию для инициализации члена типа IAudioEndpointVolume. Это было немного сложно, и помощь не была настолько полезной, как могла бы быть. Вот как это сделать:

/****************************************************************************
**  Initialize the Audio Endpoint (Only for post XP systems)
****************************************************************************/
void CMuteWatchdog::InitAudioEndPoint(void)
{
   HRESULT hr;
   IMMDeviceEnumerator * pDevEnum;
   IMMDevice * pDev;

   const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
   const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);

   hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL,
      CLSCTX_ALL, IID_IMMDeviceEnumerator,
      (void**)&pDevEnum);

   m_pIaudEndPt = NULL;

   if(hr == S_OK)
   {
      hr = pDevEnum->GetDefaultAudioEndpoint(eRender, eConsole, &pDev);
      if(hr == S_OK)
      {
         DWORD dwClsCtx;
         const IID iidAEV = __uuidof(IAudioEndpointVolume);

         dwClsCtx = 0;

         hr = pDev->Activate(iidAEV, dwClsCtx, NULL, (void**) &m_pIaudEndPt);

         if(hr == S_OK)
         {
            // Everything is groovy.
         }
         else
         {
            m_pIaudEndPt = NULL; // Might mean it's running on XP or something.  Don't use.
         }

         pDev->Release();
      }
      pDevEnum->Release();
   }
}

...

Примерно раз в секунду я добавил простой вызов к следующему:

////////////////////////////////////////////////////////////////////////
// Watchdog function for mute.
void CMuteWatchdog::GuardMute(void)
{
   if(m_pIaudEndPt)
   {
      BOOL bMute;
      HRESULT hr;

      bMute = FALSE;

      hr = m_pIaudEndPt->GetMute(&bMute);

      if(hr == S_OK)
      {
         if(bMute)
         {
            m_pIaudEndPt->SetMute(FALSE, NULL);
         }
      }
   }
}

Наконец, когда программа завершает работу, не забудьте освободить выделенный ресурс.

////////////////////////////////////////////////////////////////////////
// De-initialize the watchdog
void CMuteWatchdog::OnClose(void)
{
   if(m_pIaudEndPt)
   {
      m_pIaudEndPt->Release();
      m_pIaudEndPt = NULL;
   }
}
...