how to adjust master volume in vista/xp

前端 未结 4 780
我寻月下人不归
我寻月下人不归 2021-01-13 01:20

i want to adjust the volume programatically like Get/SetMasterVolume in vista and xp? using mmsystem unit?

相关标签:
4条回答
  • 2021-01-13 02:01

    Windows XP:

    function SetMasterVolume(VolToSet: word; out VolSet: word): MMResult;
    var
      MixerHandle: HMixer;
      Volume: TMixerControlDetails_Unsigned;
      MixerLine: TMixerLine;
      MixerLineControls: TMixerLineControls;
      VolumeCtrl: TMixerControl;
      MixerControlDetails: TMixerControlDetails;
    begin
      // Get mixer handle
      Result := mixerOpen(@MixerHandle, 0, 0, 0, 0);
      if Result <> MMSYSERR_NOERROR then Exit;
      try
        // Get master volume line
        FillChar(MixerLine, SizeOf(TMixerLine), 0);
        MixerLine.cbStruct := SizeOf(TMixerLine);
        MixerLine.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
        Result := mixerGetLineInfo(MixerHandle, @MixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE);
    
        if Result <> MMSYSERR_NOERROR then Exit;
        // Get the volume control of the master volume line
        FillChar(VolumeCtrl, SizeOf(TMixerControl), 0);
        MixerLineControls.cbStruct := SizeOf(TMixerLineControls);
        MixerLineControls.dwLineID := MixerLine.dwLineID;
        MixerLineControls.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
        MixerLineControls.cControls := 1;
        MixerLineControls.cbmxctrl := SizeOf(TMixerControl);
        MixerLineControls.pamxctrl := @VolumeCtrl;
        Result := mixerGetLineControls(MixerHandle,@MixerLineControls,MIXER_GETLINECONTROLSF_ONEBYTYPE);
    
        if Result <> MMSYSERR_NOERROR then Exit;
        // Set details (volume) for the volume control of the master volume line
        FillChar(MixerControlDetails, SizeOf(TMixerControlDetails), 0);
        MixerControlDetails.cbStruct := SizeOf(TMixerControlDetails);
        MixerControlDetails.dwControlID := VolumeCtrl.dwControlID;
        MixerControlDetails.cChannels := 1;
        MixerControlDetails.cMultipleItems := 0;
        MixerControlDetails.cbDetails := SizeOf(TMixerControlDetails_Unsigned);
        MixerControlDetails.paDetails := @Volume;
        Volume.dwValue := VolToSet;
        Result := mixerSetControlDetails(MixerHandle, @MixerControlDetails,MIXER_SETCONTROLDETAILSF_VALUE);
      finally
        mixerClose(MixerHandle);
      end;
    end;
    

    And the call:

    var y:word;
    begin
      SetMasterVolume(2000,y);
    end;
    
    0 讨论(0)
  • 2021-01-13 02:04

    Final code is(for Delphi 7):

    unit DevUnit;
    
    
    interface
    
    uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL,ComObj;
    
    
    const
      // TypeLibrary Major and minor versions
      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}';
      DEVICE_STATE_ACTIVE                   = $00000001;
      DEVICE_STATE_UNPLUGGED                = $00000002;
      DEVICE_STATE_NOTPRESENT               = $00000004;
      DEVICE_STATEMASK_ALL                  = $00000007;
    
    type
      EDataFlow = TOleEnum;
    const
      eRender                               = $00000000;
      eCapture                              = $00000001;
      eAll                                  = $00000002;
      EDataFlow_enum_count                  = $00000003;
    
    type
      ERole = TOleEnum;
    
    const
      eConsole                              = $00000000;
      eMultimedia                           = $00000001;
      eCommunications                       = $00000002;
      ERole_enum_count                      = $00000003;
    
    type
    
      IAudioEndpointVolumeCallback = interface(IUnknown)
      ['{657804FA-D6AD-4496-8A60-352752AF4F89}']
      end;
    
      IMMAudioEndpointVolume = interface(IUnknown)
      ['{5CDF2C82-841E-4546-9722-0CF74078229A}']
        Function RegisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
        Function UnregisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
        Function GetChannelCount(out PInteger): Integer; stdcall;
        Function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID):Integer; stdcall;
        Function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID):Integer; stdcall;
        Function GetMasterVolumeLevel(out fLevelDB: single):Integer; stdcall;
        Function GetMasterVolumeLevelScaler(out fLevel: single):Integer; stdcall;
        Function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: single; pguidEventContext: PGUID):Integer; stdcall;
        Function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: single; pguidEventContext: PGUID):Integer; stdcall;
        Function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: single) : Integer; stdcall;
        Function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: single) : Integer; stdcall;
        Function SetMute(bMute: Boolean ; pguidEventContext: PGUID) :Integer; stdcall;
        Function GetMute(out bMute: Boolean ) :Integer; stdcall;
        Function GetVolumeStepInfo( pnStep: Integer; out pnStepCount: Integer):Integer; stdcall;
        Function VolumeStepUp(pguidEventContext: PGUID) :Integer; stdcall;
        Function VolumeStepDown(pguidEventContext: PGUID) :Integer; stdcall;
        Function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;
        Function GetVolumeRange(out pflVolumeMindB: single; out pflVolumeMaxdB: single; out pflVolumeIncrementdB: single): Integer; stdcall;
      end;
    
      IPropertyStore = interface(IUnknown)
      end;
    
    type
      IMMDevice = interface(IUnknown)
      ['{D666063F-1587-4E43-81F1-B948E807363F}']
        Function Activate(  refId :PGUID;
                            dwClsCtx: DWORD;
                            pActivationParams: PInteger ;
                            out pEndpointVolume: IMMAudioEndpointVolume): Hresult; stdCall;
        Function OpenPropertyStore(stgmAccess: DWORD; out ppProperties :IPropertyStore): Hresult; stdcall;
        Function GetId(out ppstrId: PLPWSTR ): Hresult; stdcall;
        Function GetState(out State :Integer): Hresult; stdcall;
      end;
    
      IMMDeviceCollection = interface(IUnknown)
      ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']
      end;
      IMMNotificationClient = interface (IUnknown)
      ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']
      end;
      IMMDeviceEnumerator = interface(IUnknown)
      ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']
        Function EnumAudioEndpoints( dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection:IMMDeviceCollection ): Hresult ; stdcall;
        Function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult ; stdcall;
        Function GetDevice( pwstrId: pointer ; out Dev :IMMDevice) : HResult; stdcall;
        Function RegisterEndpointNotificationCallback(pClient :IMMNotificationClient) :Hresult; stdcall;
      end;
      implementation
    end.
    
    0 讨论(0)
  • 2021-01-13 02:17

    The MMDevApi has a number of incorrect declarations. The double parameters should be single. The Boolean parameters work better as integer. And many if not all of the TGUID parameters should be PGUID. After correcting the declarations I was able to set the mute and the volume level.

    0 讨论(0)
  • 2021-01-13 02:20

    Here's the implementation of a general purpose api for audio: MMDevApi

    http://social.msdn.microsoft.com/Forums/en/windowspro-audiodevelopment/thread/5ce74d5d-2b1e-4ca9-a8c9-2e27eb9ec058

    and an example with a button

    unit Unit33;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, MMDevApi, ActiveX, StdCtrls;
    
    type
      TForm33 = class(TForm)
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form33: TForm33;
      endpointVolume: IAudioEndpointVolume = nil;
    
    implementation
    
    {$R *.dfm}
    
    
    procedure TForm33.Button1Click(Sender: TObject);
    var
      VolumeLevel: Single;
    begin
      if endpointVolume = nil then Exit;
      VolumeLevel := 0.50;
      endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
      Caption := Format('%1.8f', [VolumeLevel])
    end;
    
    procedure TForm33.FormCreate(Sender: TObject);
    var
      deviceEnumerator: IMMDeviceEnumerator;
      defaultDevice: IMMDevice;
    begin
      CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
      deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);
      defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);
    end;
    
    end.
    
    0 讨论(0)
提交回复
热议问题