none
IMMNotificationClient: OnDefaultDeviceChanged callback is triggered too many times

    Question

  • Hi,

    I have a C++ desktop app which implements IMMNotificationClient interface and its OnDefaultDeviceChanged method. The problem is that when I disconnect the default device (audio device with usb connection) another device will be set as default. But OnDefaultDeviceChanged is called too many times. At least two times (one time for playback device and another time for a recording device) with incorrect deviceID. I need this deviceID to further call GetDevice from IMMDeviceEnumerator. And because those IDs are wrong, GetDevice fails. Is there a solution for this? or triage the amount of calls this callback is called? 

    Friday, May 24, 2019 9:21 AM

All replies

  • Hello,

    read the documentation, section Remarks: https://docs.microsoft.com/en-us/windows/desktop/api/mmdeviceapi/nf-mmdeviceapi-immnotificationclient-ondefaultdevicechanged

    It is said, that the function is called three times. Maybe in future Windows versions only two times.

    What is the problem when GetDevice fails while you change the Default device? You already catch the failed return state of GetDevice, so you can react on it.

    Regards, Guido


    Friday, May 24, 2019 9:37 AM
  • You misunderstood. Besides those three calls, the method is called again three times. And one set of calls I want to ignore because GetDevice fails when I get those.

    To be more exact. OnDefaultDeviceChanged is called three times, in that function I call getDevice which fails all three times. After some milliseconds pass, the function is again called three times and everything is ok. And GetDevice fails because the deviceID is invalid (no, it is not null). And what I want to do is to somehow ignore the first three calls, or to validate somehow that deviceID which I get in parameter.


    Friday, May 24, 2019 11:56 AM
  • Ok.

    Maybe you can use a static variable in the function that holds the id of the last device. As long as it does not change, you don't call GetDevice. Save the id in the static variable. Something like:

    {
      static long s_idLastDevice=0;
    
      // get the actual id
      long actual_id = ...
    
      // check, if it is a new id
      if (actual_id != s_idLastDevice)
      {
         s_idLastDevice = actual_id;
         // now call GetDevice
         GetDevice(id);
         // do the tasks with the new device
         ...
      }
    
      ...
    }

    As long as the id does not change, GetDevice will not be called. So the this part is only executed once with a valid device id.

    HTH, Guido


    Friday, May 24, 2019 12:48 PM