C++ 如何在Vista和7中全局静音和取消静音,并获得静音状态?

C++ 如何在Vista和7中全局静音和取消静音,并获得静音状态?,c++,c,audio,windows-vista,mixer,C++,C,Audio,Windows Vista,Mixer,我现在使用的是旧的好的MixerAPI,但它在WindowsVista&7上的正常工作模式下,而不是在XP兼容模式下,并没有达到预期的效果。它只为当前应用程序静音,但我需要一个全局(硬件)静音。如何重新设定目标?有没有办法用纯C/C++编写这个没有COM接口和奇怪调用的代码?Vista的音频堆栈被显著重写。每个应用程序的音量和静音控制确实是新功能之一。使用时需要奇怪的呼叫。我最近处理过同样的问题。我们有一个Windows应用程序,它使用声音系统进行报警。我们不能容忍用户无意中对音响系统进行静音。

我现在使用的是旧的好的MixerAPI,但它在WindowsVista&7上的正常工作模式下,而不是在XP兼容模式下,并没有达到预期的效果。它只为当前应用程序静音,但我需要一个全局(硬件)静音。如何重新设定目标?有没有办法用纯C/C++编写这个没有COM接口和奇怪调用的代码?

Vista的音频堆栈被显著重写。每个应用程序的音量和静音控制确实是新功能之一。使用时需要奇怪的呼叫。

我最近处理过同样的问题。我们有一个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;
   }
}

你能为上述问题提供一个工作样本吗?有没有办法放弃COM,并用纯C或C++编写代码?如果你以前从未编写过任何COM代码,那么你就过着幸福的生活。这是没有办法的。你可以从设计界面的人那里得到一个代码示例。链接: