修改正确的MMDevApi.pas

unit MMDevApi;


{$MINENUMSIZE 4}
{$WEAKPACKAGEUNIT}


interface


uses
 Windows, ActiveX, ComObj, propsys, mmsystem,
 Winapi.Messages, System.SysUtils, System.Variants, System.Classes;


const
 CLASS_IMMDeviceEnumerator: TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
 IID_IMMDeviceEnumerator: TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
 IID_IMMDevice: TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
 IID_IMMDeviceCollection: TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
 IID_IAudioEndpointVolume: TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
 IID_IAudioMeterInformation: TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
 IID_IAudioEndpointVolumeCallback: TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';
 // undocumented
 IID_IRemoteAudioSession: TGUID = '{33969B1D-D06F-4281-B837-7EAAFD21A9C0}';
 IID_IAudioSessionQuerier: TGUID = '{94BE9D30-53AC-4802-829C-F13E5AD34776}';
 IID_IAudioSessionQuery: TGUID = '{94BE9D30-53AC-4802-829C-F13E5AD34775}';
 //
 IID_IAudioSessionEvents: TGUID = '{24918ACC-64B3-37C1-8CA9-74A66E9957A8}';
 IID_IAudioSessionControl: TGUID = '{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}';
 IID_ISimpleAudioVolume: TGUID = '{87CE5498-68D6-44E5-9215-6DA47EF883D8}';
 IID_IAudioSessionManager: TGUID = '{BFA971F1-4D5E-40BB-935E-967039BFBEE4}';
 IID_IAudioClient: TGUID = '{1CB9AD4C-DBFA-4c32-B178-C2F568A703B2}';
 IID_IAudioRenderClient: TGUID = '{F294ACFC-3146-4483-A7BF-ADDCA7C260E2}';


 DEVICE_STATE_ACTIVE = $00000001;
 DEVICE_STATE_DISABLE = $00000002;
 DEVICE_STATE_NOTPRESENT = $00000004;
 DEVICE_STATE_UNPLUGGED = $00000008;
 DEVICE_STATEMASK_ALL = $0000000F;


 // QueryHardwareSupport
 ENDPOINT_HARDWARE_SUPPORT_VOLUME = $00000001;
 ENDPOINT_HARDWARE_SUPPORT_MUTE = $00000002;
 ENDPOINT_HARDWARE_SUPPORT_METER = $00000004;




type
 EDataFlow = TOleEnum;


type AUDCLNT_SHAREMODE =(
  AUDCLNT_SHAREMODE_SHARED,
  AUDCLNT_SHAREMODE_EXCLUSIVE
);
type REFIID =(
IID_IAudioCaptureClient,IID_IAudioClock,//IID_IAudioSessionControl, IID_IAudioRenderClient,
IID_IAudioStreamVolume,IID_IChannelAudioVolume,IID_IMFTrustedOutput ) ;   //,IID_ISimpleAudioVolume




const
 eRender = $00000000;
 eCapture = $00000001;
 eAll = $00000002;
 EDataFlow_enum_count = $00000003;


type  ERole = TOleEnum;
type  REFERENCE_TIME=LONGLONG;




const
 eConsole = $00000000;
 eMultimedia = $00000001;
 eCommunications = $00000002;
 ERole_enum_count = $00000003;
 // AudioSessionState
 AudioSessionStateInactive = 0;
 AudioSessionStateActive = 1;
 AudioSessionStateExpired = 2;
 // AudioSessionDisconnectReason
 DisconnectReasonDeviceRemoval = 0;
 DisconnectReasonServerShutdown = DisconnectReasonDeviceRemoval + 1;
 DisconnectReasonFormatChanged = DisconnectReasonServerShutdown + 1;
 DisconnectReasonSessionLogoff = DisconnectReasonFormatChanged + 1;
 DisconnectReasonSessionDisconnected = DisconnectReasonSessionLogoff + 1;
 DisconnectReasonExclusiveModeOverride = DisconnectReasonSessionDisconnected + 1;




type
 PAUDIO_VOLUME_NOTIFICATION_DATA = ^AUDIO_VOLUME_NOTIFICATION_DATA;
 AUDIO_VOLUME_NOTIFICATION_DATA = packed record
  guidEventContext: TGUID;
  bMuted: BOOL;
  fMasterVolume: Single;
  nChannels: UINT;
  afChannelVolumes: array[1..1] of Single;
 end;


// type pp= ^pWAVEFORMATEX;  已测试,不能用


type


 IAudioRenderClient = interface(IUnknown)
['{F294ACFC-3146-4483-A7BF-ADDCA7C260E2}']
    function GetBuffer(const NumFramesRequested: UINT; out ppData: PByte): HResult; stdcall;
    function ReleaseBuffer(const NumFramesWritten: UINT32; const dwFlags: DWord): HResult; stdcall;
end;


 IAudioClient = interface(IUnknown)
  ['{1CB9AD4C-DBFA-4c32-B178-C2F568A703B2}']
    
    function Initialize(ShareMode: AUDCLNT_SHAREMODE; StreamFlags: Dword;
       hnsBufferDuration: REFERENCE_TIME; hnsPeriodicity: REFERENCE_TIME;
    pFormat: PWaveFormatEx; AudioSessionGuid: IUnknown): HResult; stdcall;       //LPCGUID


    function GetBufferSize(out pNumBufferFrames: UINT32): HResult; stdcall;
    function GetStreamLatency(out phnsLatency: REFERENCE_TIME): HResult; stdcall;
    function GetCurrentPadding(out pNumPaddingFrames: UINT32): HResult; stdcall;
    function IsFormatSupported(ShareMode: AUDCLNT_SHAREMODE; pFormat: PWaveFormatEx; out ppClosestMatch: PWaveFormatEx): HResult; stdcall;
    function GetMixFormat(out ppDeviceFormat: PWaveFormatEx): HResult; stdcall;
    function GetDevicePeriod(out phnsDefaultDevicePeriod: REFERENCE_TIME; phnsMinimumDevicePeriod: REFERENCE_TIME): HResult; stdcall;
    function Start(): HResult; stdcall;
    function Stop(): HResult; stdcall;
    function Reset(): HResult; stdcall;
    function SetEventHandle(const eventHandle: pHANDLE): HResult; stdcall;  //org:HANDLE
    function GetService(const riid: TGUID; out ppv: Pointer): HResult; stdcall;
    
 end;


 IAudioEndpointVolumeCallback = interface(IUnknown)
  ['{657804FA-D6AD-4496-8A60-352752AF4F89}']
  function OnNotify(pNotify: PAUDIO_VOLUME_NOTIFICATION_DATA): HRESULT; stdcall;
 end;


 IAudioEndpointVolume = interface(IUnknown)
  ['{5CDF2C82-841E-4546-9722-0CF74078229A}']
  function RegisterControlChangeNotify(pNotify: IAudioEndpointVolumeCallback): HRESULT; stdcall;
  function UnregisterControlChangeNotify(pNotify: IAudioEndpointVolumeCallback): HRESULT; stdcall;
  function GetChannelCount(var pnChannelCount: uint): HRESULT; stdcall;
  function SetMasterVolumeLevel(fLevelDB: Single; pguidEventContext: PGuid): HRESULT; stdcall;
  function SetMasterVolumeLevelScalar(fLevel: Single; pguidEventContext: PGuid): HRESULT; stdcall;
  function GetMasterVolumeLevel(var pfLevelDB: Single): HRESULT; stdcall
   ;
  function GetMasterVolumeLevelScalar(var pfLevel: Single): HRESULT; stdcall;
  function SetChannelVolumeLevel(nChannel: uint; fLevelDB: Single; pguidEventContext: PGuid): HRESULT; stdcall;
  function SetChannelVolumeLevelScalar(nChannel: uint; fLevel: Single; pguidEventContext: PGuid): HRESULT; stdcall ;
  function GetChannelVolumeLevel(nChannel: uint; fLevelDB: Single): HRESULT; stdcall;
  function GetChannelVolumeLevelScalar(nChannel: uint; fLevel: Single): HRESULT; stdcall;
  function SetMute(bMute: bool; pguidEventContext: PGuid): HRESULT; stdcall;
  function GetMute(var pbMute: bool): HRESULT; stdcall;
  function GetVolumeStepInfo(var pnStep: uint; var pnStepCount: uint): HRESULT; stdcall;
  function VolumeStepUp(pguidEventContext: PGuid): HRESULT; stdcall;
  function VolumeStepDown(pguidEventContext: PGuid): HRESULT; stdcall;
  function QueryHardwareSupport(var pdwHardwareSupportMask: uint): HRESULT; stdcall;
  function GetVolumeRange(var pflVolumeMindB: Single; var pflVolumeMaxdB: Single;
   var pflVolumeIncrementdB: Single): HRESULT; stdcall;
 end;


 IAudioMeterInformation = interface(IUnknown)
  ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']
  function GetPeakValue(out pfPeak: Single): HResult; stdcall;
  function GetMeteringChannelCount(out pnChannelCount: uint): HResult; stdcall;
  function GetChannelsPeakValues(u32ChannelCount: uint; afPeakValues: pSingle): HResult; stdcall;
  function QueryHardwareSupport(out pdwHardwareSupportMask: uint): HResult; stdcall;
 end;


 IMMDevice = interface(IUnknown)
  ['{D666063F-1587-4E43-81F1-B948E807363F}']
  function Activate(const iid: TGUID; dwClsCtx: uint; pActivationParams: PPropVariant; out ppInterface: IUnknown): HRESULT; stdcall;
  function OpenPropertyStore(stgmAccess: integer; out ppProperties: IPropertyStore): HRESULT; stdcall;
  function GetId(ppstrId: PWChar): HRESULT; stdcall;
  function GetState(var pdwState: uint): HRESULT; stdcall;
 end;




 IMMDeviceCollection = interface(IUnknown)
  ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']
  function GetCount(var pcDevices: uint): HRESULT; stdcall;
  function Item(nDevice: uint; out ppDevice: IMMDevice): HRESULT; stdcall;
 end;


 //IMMNotificationClient = interface(IUnknown)
 // ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']
 //end;


 IMMNotificationClient = interface(IUnknown)
['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']
  function OnDeviceStateChanged(const pwstrDeviceId: LPCWSTR;
                                  const dwNewState: DWord): HRESULT; stdcall;
    // Parameters
    // pwstrDeviceId [in]
    //  Pointer to the endpoint ID string that identifies the audio endpoint device.
    //  This parameter points to a null-terminated, wide-character string containing the endpoint ID.
    //  The string remains valid for the duration of the call.
    // dwNewState [in]
    //  Specifies the new state of the endpoint device.
    //  The value of this parameter is one of the following DEVICE_STATE_XXX constants:
    //    DEVICE_STATE_ACTIVE
    //    DEVICE_STATE_DISABLED
    //    DEVICE_STATE_NOTPRESENT
    //    DEVICE_STATE_UNPLUGGED


function OnDeviceAdded(const pwstrDeviceId: LPCWSTR): HRESULT; stdcall;
    // The OnDeviceAdded method indicates that a new audio endpoint device has been added.
    // Parameters
    //   pwstrDeviceId [in]
    //   Pointer to the endpoint ID string that identifies the audio endpoint device.
    //   This parameter points to a null-terminated, wide-character string containing
    //   the endpoint ID. The string remains valid for the duration of the call.


function OnDeviceRemoved(const pwstrDeviceId: LPCWSTR): HRESULT; stdcall;
  //  HRESULT OnDeviceRemoved(  [in] LPCWSTR pwstrDeviceId);


    // Parameters
    // flow [in]
    //  The data-flow direction of the endpoint device.
    //  This parameter is set to one of the following EDataFlow enumeration values:
    //    - eRender
    //    - eCapture
    //  The data-flow direction for a rendering device is eRender.
    //  The data-flow direction for a capture device is eCapture.
    // role [in]
    //  The device role of the audio endpoint device.
    //  This parameter is set to one of the following ERole enumeration values:
    //    - eConsole
    //    - eMultimedia
    //    - eCommunications
    // pwstrDefaultDeviceId [in]
    //  Pointer to the endpoint ID string that identifies the audio endpoint device.
    //  This parameter points to a null-terminated, wide-character string containing the endpoint ID.
    //  The string remains valid for the duration of the call.
    //  If the user has removed or disabled the default device for a particular role,
    //  and no other device is available to assume that role, then pwstrDefaultDeviceId is NULL.


function OnDefaultDeviceChanged(const flow: EDataFlow;
                                    const role: ERole;
                                    const pwstrDefaultDeviceId: LPCWSTR): HRESULT; stdcall;
    // The OnDefaultDeviceChanged method notifies the client that the default audio endpoint device for a particular device role has changed.
    // Parameters
    //   flow [in]
    //    The data-flow direction of the endpoint device.
    //    This parameter is set to one of the following EDataFlow enumeration values:
    //     - eRender  : The data-flow direction for a rendering device is eRender.
    //     - eCapture : The data-flow direction for a capture device is eCapture.
    //   role [in]
    //    The device role of the audio endpoint device.
    //    This parameter is set to one of the following ERole enumeration values:
    //    - eConsole
    //    - eMultimedia
    //    - eCommunications
    //   pwstrDefaultDevice [in]
    //    Pointer to the endpoint ID string that identifies the audio endpoint device.
    //    This parameter points to a null-terminated, wide-character string containing the endpoint ID.
    //    The string remains valid for the duration of the call.
    //    If the user has removed or disabled the default device for a particular role,
    //    and no other device is available to assume that role, then pwstrDefaultDevice is NIL.


   //function OnPropertyValueChanged(const pwstrDeviceId: LPCWSTR; const key: PROPERTYKEY): HRESULT; stdcall;
   function OnPropertyValueChanged(pwstrDeviceID: LPCWSTR; const key: PROPERTYKEY): HRESULT; stdcall;
   
    // Parameters
    //  pwstrDeviceId [in]
    //   Pointer to the endpoint ID string that identifies the audio endpoint device.
    //   This parameter points to a null-terminated, wide-character string that contains the endpoint ID.
    //   The string remains valid for the duration of the call.
    //  key [in]
    //   A PROPERTYKEY structure that specifies the property.
    //   The structure contains the property-set GUID and an index identifying a property within the set.
    //   The structure is passed by value. It remains valid for the duration of the call.
    //   For more information about PROPERTYKEY, see the Windows SDK documentation.
    //
    // Remarks
    //   A call to the IPropertyStore.SetValue method that successfully changes the value of
    //   a property of an audio endpoint device generates a call to OnPropertyValueChanged.
    //   For more information about IPropertyStore.SetValue, see the Windows SDK documentation.
    //   A client can use the key parameter to retrieve the new property value.
end;




 IMMDeviceEnumerator = interface(IUnknown)
  ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']
  function EnumAudioEndpoints(dataFlow: EDataFlow; dwStateMask: DWORD; out ppDevices: IMMDeviceCollection): HRESULT; stdcall;
  function GetDefaultAudioEndpoint(dataFlow: EDataFlow; role: ERole; out ppEndpoint: IMMDevice): HRESULT; stdcall;
  function GetDevice(pwstrId: PWChar; out ppDevice: IMMDevice): HRESULT; stdcall;
  function RegisterEndpointNotificationCallback(var pClient: IMMNotificationClient): HRESULT; stdcall;
  function UnregisterEndpointNotificationCallback(var pClient: IMMNotificationClient): HRESULT; stdcall;
 end;


 { undocumented }
 IRemoteAudioSession = interface(IUnknown)
  ['{33969B1D-D06F-4281-B837-7EAAFD21A9C0}']
  function func_a: HResult; stdcall;
  function func_b: HResult; stdcall;
  function func_c: HResult; stdcall;
  function func_d: HResult; stdcall;
  function func_e: HResult; stdcall;
  function func_f: HResult; stdcall;
  function func_g: HResult; stdcall;
  function func_h: HResult; stdcall;
  function func_i: HResult; stdcall;
  function func_j: HResult; stdcall;
  function func_k: HResult; stdcall;
  function GetProcessID(out pid: uint): HResult; stdcall;
 end;


 { undocumented }
 IAudioSessionQuerier = interface(IUnknown)
  ['{94BE9D30-53AC-4802-829C-F13E5AD34776}']
  function GetNumSessions(out NumSessions: uint): HResult; stdcall;
  function QuerySession(Num: uint; out Session: IUnknown): HResult; stdcall;
 end;
 { undocumented }
 IAudioSessionQuery = interface(IUnknown)
  ['{94BE9D30-53AC-4802-829C-F13E5AD34775}']
  function GetQueryInterface(out AudioQuerier: IAudioSessionQuerier): HResult; stdcall;
 end;


 IAudioSessionEvents = interface(IUnknown)
  ['{24918ACC-64B3-37C1-8CA9-74A66E9957A8}']
  function OnDisplayNameChanged(NewDisplayName: LPCWSTR; EventContext: pGuid): HResult; stdcall;
  function OnIconPathChanged(NewIconPath: LPCWSTR; EventContext: pGuid): HResult; stdcall;
  function OnSimpleVolumeChanged(NewVolume: Single; NewMute: LongBool; EventContext: pGuid): HResult; stdcall;
  function OnChannelVolumeChanged(ChannelCount: uint; NewChannelArray: PSingle; ChangedChannel: uint;
   EventContext: pGuid): HResult; stdcall;
  function OnGroupingParamChanged(NewGroupingParam, EventContext: pGuid): HResult; stdcall;
  function OnStateChanged(NewState: uint): HResult; stdcall; // AudioSessionState
  function OnSessionDisconnected(DisconnectReason: uint): HResult; stdcall; // AudioSessionDisconnectReason
 end;


 IAudioSessionControl = interface(IUnknown)
  ['{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}']
  function GetState(out pRetVal: uint): HResult; stdcall;
  function GetDisplayName(out pRetVal: LPWSTR): HResult; stdcall; // pRetVal must be freed by CoTaskMemFree
  function SetDisplayName(Value: LPCWSTR; EventContext: pGuid): HResult; stdcall;
  function GetIconPath(out pRetVal: LPWSTR): HResult; stdcall; // pRetVal must be freed by CoTaskMemFree
  function SetIconPath(Value: LPCWSTR; EventContext: pGuid): HResult; stdcall;
  function GetGroupingParam(pRetVal: pGuid): HResult; stdcall;
  function SetGroupingParam(OverrideValue, EventContext: pGuid): HResult; stdcall;
  function RegisterAudioSessionNotification(const NewNotifications: IAudioSessionEvents): HResult; stdcall;
  function UnregisterAudioSessionNotification(const NewNotifications: IAudioSessionEvents): HResult; stdcall;
 end;


 ISimpleAudioVolume = interface(IUnknown)
  ['{87CE5498-68D6-44E5-9215-6DA47EF883D8}']
  function SetMasterVolume(fLevel: Single; EventContext: pGuid): HResult; stdcall;
  function GetMasterVolume(out fLevel: Single): HResult; stdcall;
  function SetMute(bMute: LongBool; EventContext: pGuid): HResult; stdcall;
  
  function GetMute(out bMute: LongBool): HResult; stdcall;
 end;


 IAudioSessionManager = interface(IUnknown)
  ['{BFA971F1-4D5E-40BB-935E-967039BFBEE4}']
  function GetAudioSessionControl(AudioSessionGuid: pGUID; StreamFlag: uint;
   out SessionControl: IAudioSessionControl): HResult; stdcall;
  function GetSimpleAudioVolume(AudioSessionGuid: pGuid; StreamFlag: uint;
   out AudioVolume: ISimpleAudioVolume): HResult; stdcall;
 end;


// get ISimpleAudioVolume from ProcessID
function GetSimpleAudioVolumeFromPid(const AudioDevice: IMMDevice; pid: uint; out SimpleAudio: ISimpleAudioVolume; out currguid: tguid): Boolean; stdcall;
// get ISimpleAudioVolume from Process Handle
function GetSimpleAudioVolumeFromHandle(const AudioDevice: IMMDevice; Hnd: uint; out SimpleAudio: ISimpleAudioVolume; out currguid: tguid): Boolean; stdcall;
//
function GetSimpleAudioVolumeFromModuleName(const AudioDevice: IMMDevice; ModuleName: pWideChar; out SimpleAudio: ISimpleAudioVolume; out currguid: tguid): Boolean; stdcall;


implementation


uses tlhelp32;


function GetProcessIdFromModuleName(ModuleName: pWideChar): LongWord;
var
 ToolSnap: LongWord;
 ProcessEntry: ProcessEntry32W;
 bCont: LongBool;
 ModuleName16: WideString;
begin
 Result := 0;
 ModuleName16 := ModuleName;
 ToolSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 ProcessEntry.dwSize := sizeof(ProcessEntry);
 bCont := Process32FirstW(ToolSnap, ProcessEntry);
 while bCont do begin
  if ProcessEntry.szExeFile = ModuleName16 then
   Result := ProcessEntry.th32ProcessID;
  ProcessEntry.dwSize := sizeof(ProcessEntry);
  bCont := (Result = 0) and Process32NextW(ToolSnap, ProcessEntry);
 end;
 CloseHandle(ToolSnap);
end;


function GetSimpleAudioVolumeFromModuleName(const AudioDevice: IMMDevice; ModuleName: pWideChar; out SimpleAudio: ISimpleAudioVolume; out currguid: tguid): Boolean; stdcall;
var
 pid: LongWord;
begin
 pid := GetProcessIdFromModuleName(ModuleName);
 Result := GetSimpleAudioVolumeFromPid(AudioDevice, pid, SimpleAudio, currguid);
end;


function GetSimpleAudioVolumeFromHandle(const AudioDevice: IMMDevice; Hnd: uint; out SimpleAudio: ISimpleAudioVolume; out currguid: tguid): Boolean; stdcall;
var
 pid: uint;
begin
 GetWindowThreadProcessId(Hnd, pid);
 Result := GetSimpleAudioVolumeFromPid(AudioDevice, pid, SimpleAudio, currguid);
end;


function GetSimpleAudioVolumeFromPid(const AudioDevice: IMMDevice; pid: uint; out SimpleAudio: ISimpleAudioVolume; out currguid: tguid): Boolean; stdcall;
var
 SessionManager: IAudioSessionManager;
 SessionQuery: IAudioSessionQuery;
 SessionQuerier: IAudioSessionQuerier;
 RemoteSession: IRemoteAudioSession;
 SessionControl: IAudioSessionControl;
 dummy: IUnknown;
 MaxSession, Sessionpid: uint;
 hr, i: Integer;
begin
 Result := False;
 SessionManager := nil;
 SessionQuery := nil;
 SessionQuerier := nil;
 SessionControl := nil;


 // get AudioSessionManager
 hr := AudioDevice.Activate(IID_IAudioSessionManager, CLSCTX_ALL, nil, IUnknown(SessionManager));
 if Succeeded(hr) then begin
  // get SessionQuery
  hr := SessionManager.QueryInterface(IID_IAudioSessionQuery, SessionQuery);
  if Succeeded(hr) then begin
   // get SessionQuerier
   hr := SessionQuery.GetQueryInterface(SessionQuerier);
   if Succeeded(hr) then begin
   // check sessions
   hr := SessionQuerier.GetNumSessions(MaxSession);
   if Succeeded(hr) then
    if MaxSession > 0 then
     for i := 0 to MaxSession - 1 do begin
      dummy := nil;
      hr := SessionQuerier.QuerySession(i, dummy);
      RemoteSession := nil;
      if Succeeded(hr) then begin
      // get RemoteSession
      hr := dummy.QueryInterface(IID_IRemoteAudioSession, RemoteSession);
      if Succeeded(hr) then begin
       // compare ProcessID
       if Succeeded(RemoteSession.GetProcessID(Sessionpid)) then
        if Sessionpid <> 0 then
         if Sessionpid = pid then begin
         Result := Succeeded(RemoteSession.QueryInterface(IID_ISimpleAudioVolume, SimpleAudio));
         if Succeeded(dummy.QueryInterface(IID_IAudioSessionControl, SessionControl)) then
          SessionControl.GetGroupingParam(@currguid);
         SessionControl := nil;
         end;
       if Result then
        Break;
      end;
      end;
     end;
   RemoteSession := nil;
   SessionQuerier := nil;
   end;
   SessionQuery := nil;
  end;
  SessionManager := nil;
 end;
end;




end.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值