2010-03-04 18 views
5

müzik anahtarsız bir klavyeye sahiptir, bu da PC'mdeki müziğin sesini, çalmasını, durmasını vb. Anlamazsanız, this klavyem ve this değil.Bilgisayarımın ses düzeyi nasıl programlanır?

Klavyemdeki birim özelliğini oluşturmak için Windows ve Delphi veya C# klavye kancalarını uygulamak istiyorum, ancak kodu nasıl açacağımı bilmiyorum. this ve this örneklerini deniyordum ama işe yaramadı (hepsi bu arada Delphi'de).

Ses düzeyini kodlayarak nasıl açacağınızı biliyor musunuz?

+0

okumak isteyebilirsiniz Bazı makaleler: http://www.codeguru.com/csharp/csharp/cs_graphics/sound/article.php/c10931 http://www.dreamincode.net/forums/ index.php?showtopic = 45693 –

cevap

6

Autohotkey bu işi yapar. Tüm ses aygıtları için ses seviyesi/ses kısma düzeylerini ayarlayabilen bir "SoundSet" komutuna sahiptir. Size yardımcı olabilecek bu kılavuzu en

+0

Yine de biraz komut dosyası gerektiriyor - eğer etrafta dolaşıyorsanız, birileri otomatik olarak otomobili komut dosyası oluşturdu. –

+1

güzel !! '^! NumpadSub :: Send {Volume_Up 10}' '^! NumpadAdd :: Gönder {Volume_Down 10}' '^! NumpadEnter :: Gönder {Volume_Mute}' – Joe

8

Delphi kod izler.

benim keyhook lParamda anahtarın VK kodu ile benim ana forma bir mesaj gönderir

,

procedure TmainFrm.keyHook(var msg: TMessage); 
begin 
    case msg.LParam of 
    VK_VOLUME_UP : g_mixer.volume := g_mixer.volume + 2048; 
    VK_VOLUME_DOWN: g_mixer.volume := g_mixer.volume - 2048; 
    VK_VOLUME_MUTE: g_mixer.muted := not g_mixer.muted; 
    end; 
end; 

cilt aralığı .. 65535 0; bant dışı değerler sessizce düzeltilir.

-

unit Mixer; 

interface 

type 

    Tmixer = class 
    protected 
    function getMute: boolean; virtual; abstract; 
    function getVolume: integer; virtual; abstract; 
    procedure setVolume(Value: integer); virtual; abstract; 
    procedure setMute(Value: boolean); virtual; abstract; 
    public 
    property volume: integer read getVolume write setVolume; 
    property muted: boolean read getMute write setMute; 
    end; 

function g_mixer: Tmixer; 

implementation 

uses 
    Windows, MMSystem, MMDevApi_tlb, ComObj, ActiveX, SysUtils; 

// --------------------------------------------------------------------------- 

type 

    TxpMixer = class(Tmixer) 
    private 
    Fmxct: integer; 
    Fmixer: HMIXER; 
    procedure chk(r: MMRESULT); 
    protected 
    function getMute: boolean; override; 
    function getVolume: integer; override; 
    procedure setVolume(Value: integer); override; 
    procedure setMute(Value: boolean); override; 
    public 
    constructor Create; 
    destructor Destroy; override; 
    end; 

    TvistaMixer = class(Tmixer) 
    private 
    FmmDev: IMMDevice; 
    FmmDevEnum: IMMDeviceEnumerator; 
    FmmEndpoint: IMMAudioEndpointVolume; 
    protected 
    function getMute: boolean; override; 
    function getVolume: integer; override; 
    procedure setVolume(Value: integer); override; 
    procedure setMute(Value: boolean); override; 
    public 
    constructor Create; 
    end; 

// --------------------------------------------------------------------------- 

var 
    _g_mixer: Tmixer; 

function g_mixer: Tmixer; 
var 
    VerInfo: TOSVersioninfo; 
begin 
    if (_g_mixer = nil) then 
    begin 
    VerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo); 
    GetVersionEx(VerInfo); 
    if (VerInfo.dwMajorVersion >= 6) then 
     _g_mixer := TvistaMixer.Create 
    else 
     _g_mixer := TxpMixer.Create; 
    end; 
    result := _g_mixer; 
end; 

// --------------------------------------------------------------------------- 

{ TxpMixer } 

procedure TxpMixer.chk(r: MMRESULT); 
var 
    s: string; 
begin 
    if (r = MMSYSERR_NOERROR) then 
    exit; 
    setLength(s, MMSystem.MAXERRORLENGTH + 1); 
    waveOutGetErrorText(r, @s[1], MMSystem.MAXERRORLENGTH); 
    raise Exception.Create(StrPas(pChar(s))); 
end; 

// --------------------------------------------------------------------------- 

constructor TxpMixer.Create; 
begin 
    Fmxct := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; 
    chk(mixerOpen(@Fmixer, 0, 0, 0, 0)); 
end; 

// --------------------------------------------------------------------------- 

destructor TxpMixer.Destroy; 
begin 
    if (Fmixer <> 0) then 
    mixerClose(Fmixer); 
    inherited; 
end; 

// --------------------------------------------------------------------------- 

function TxpMixer.getMute: boolean; 
var 
    MasterMute: TMixerControl; 
    Details: TMixerControlDetails; 
    BoolDetails: TMixerControlDetailsBoolean; 
    Line: TMixerLine; 
    Controls: TMixerLineControls; 
begin 
    ZeroMemory(@Line, SizeOf(Line)); 
    Line.cbStruct := SizeOf(Line); 
    Line.dwComponentType := Fmxct; 
    chk(mixerGetLineInfo(0, @Line, MIXER_GETLINEINFOF_COMPONENTTYPE)); 

    ZeroMemory(@Controls, SizeOf(Controls)); 
    Controls.cbStruct := SizeOf(Controls); 
    Controls.dwLineID := Line.dwLineID; 
    Controls.cControls := 1; 
    Controls.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE; 
    Controls.cbmxctrl := SizeOf(MasterMute); 
    Controls.pamxctrl := @MasterMute; 
    chk(mixerGetLineControls(0, @Controls, MIXER_GETLINECONTROLSF_ONEBYTYPE)); 

    Details.cbStruct := SizeOf(Details); 
    Details.dwControlID := MasterMute.dwControlID; 
    Details.cChannels := 1; 
    Details.cMultipleItems := 0; 
    Details.cbDetails := SizeOf(BoolDetails); 
    Details.paDetails := @BoolDetails; 
    chk(mixerGetControlDetails(0, @Details, MIXER_GETCONTROLDETAILSF_VALUE)); 

    result := BoolDetails.fValue <> 0; 
end; 

// --------------------------------------------------------------------------- 

function TxpMixer.getVolume: integer; 
var 
    Line: TMixerLine; 
    Controls: TMixerLineControls; 
    MasterVolume: TMixerControl; 
    Details: TMixerControlDetails; 
    UnsignedDetails: TMixerControlDetailsUnsigned; 
begin 
    ZeroMemory(@Line, SizeOf(Line)); 
    Line.cbStruct := SizeOf(Line); 
    Line.dwComponentType := Fmxct; 
    chk(mixerGetLineInfo(Fmixer, @Line, MIXER_GETLINEINFOF_COMPONENTTYPE)); 
    ZeroMemory(@Controls, SizeOf(Controls)); 
    Controls.cbStruct := SizeOf(Controls); 
    Controls.dwLineID := Line.dwLineID; 
    Controls.cControls := 1; 
    Controls.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME; 
    Controls.cbmxctrl := SizeOf(MasterVolume); 
    Controls.pamxctrl := @MasterVolume; 
    chk(mixerGetLineControls(Fmixer, @Controls, MIXER_GETLINECONTROLSF_ONEBYTYPE)); 

    details.cbStruct := SizeOf(Details); 
    details.dwControlID := MasterVolume.dwControlID; 
    details.cChannels := 1; 
    details.cMultipleItems := 0; 
    details.cbDetails := SizeOf(UnsignedDetails); 
    details.paDetails := @UnsignedDetails; 
    chk(mixerGetControlDetails(Fmixer, @Details, MIXER_GETCONTROLDETAILSF_VALUE)); 
    result := UnsignedDetails.dwValue; 
end; 

// --------------------------------------------------------------------------- 

procedure TxpMixer.setMute(Value: boolean); 
var 
    Line: TMixerLine; 
    Controls: TMixerLineControls; 
    MasterMute: TMixerControl; 
    Details: TMixerControlDetails; 
    BoolDetails: TMixerControlDetailsBoolean; 
begin 
    ZeroMemory(@Line, SizeOf(Line)); 
    Line.cbStruct := SizeOf(Line); 
    Line.dwComponentType := Fmxct; 
    chk(mixerGetLineInfo(Fmixer, @Line, MIXER_GETLINEINFOF_COMPONENTTYPE)); 
    ZeroMemory(@Controls, SizeOf(Controls)); 
    Controls.cbStruct := SizeOf(Controls); 
    Controls.dwLineID := Line.dwLineID; 
    Controls.cControls := 1; 
    Controls.dwControlType := MIXERCONTROL_CONTROLTYPE_MUTE; 
    Controls.cbmxctrl := SizeOf(masterMute); 
    Controls.pamxctrl := @masterMute; 
    chk(mixerGetLineControls(Fmixer, @Controls, MIXER_GETLINECONTROLSF_ONEBYTYPE)); 

    details.cbStruct := SizeOf(Details); 
    details.dwControlID := MasterMute.dwControlID; 
    details.cChannels := 1; 
    details.cMultipleItems := 0; 
    details.cbDetails := SizeOf(BoolDetails); 
    details.paDetails := @BoolDetails; 
    mixerGetControlDetails(0, @Details, MIXER_GETCONTROLDETAILSF_VALUE); 
    if (Value) then 
    BoolDetails.fValue := 1 
    else 
    BoolDetails.fValue := 0; 

    chk(mixerSetControlDetails(0, @Details, MIXER_SETCONTROLDETAILSF_VALUE)); 
end; 

// --------------------------------------------------------------------------- 

procedure TxpMixer.setVolume(Value: integer); 
var 
    Line: TMixerLine; 
    Controls: TMixerLineControls; 
    MasterVolume: TMixerControl; 
    Details: TMixerControlDetails; 
    UnsignedDetails: TMixerControlDetailsUnsigned; 
begin 
    if (value < 0) then 
    value := 0; 
    if (value > 65535) then 
    value := 65535; 

    ZeroMemory(@Line, SizeOf(Line)); 
    Line.cbStruct := SizeOf(Line); 
    Line.dwComponentType := Fmxct; 
    chk(mixerGetLineInfo(Fmixer, @Line, MIXER_GETLINEINFOF_COMPONENTTYPE)); 
    ZeroMemory(@Controls, SizeOf(Controls)); 
    Controls.cbStruct := SizeOf(Controls); 
    Controls.dwLineID := Line.dwLineID; 
    Controls.cControls := 1; 
    Controls.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME; 
    Controls.cbmxctrl := SizeOf(MasterVolume); 
    Controls.pamxctrl := @MasterVolume; 
    chk(mixerGetLineControls(Fmixer, @Controls, MIXER_GETLINECONTROLSF_ONEBYTYPE)); 

    details.cbStruct := SizeOf(Details); 
    details.dwControlID := MasterVolume.dwControlID; 
    details.cChannels := 1; 
    details.cMultipleItems := 0; 
    details.cbDetails := SizeOf(UnsignedDetails); 
    details.paDetails := @UnsignedDetails; 
    UnsignedDetails.dwValue := Value; 
    chk(mixerSetControlDetails(Fmixer, @Details, MIXER_SETCONTROLDETAILSF_VALUE)); 
end; 

// --------------------------------------------------------------------------- 

{ TvistaMixer } 

constructor TvistaMixer.Create; 
begin 
    CoCreateInstance(CLSID_MMDeviceEnumerator, nil, CLSCTX_ALL, IID_IMMDeviceEnumerator, FmmDevEnum); 
    FmmDevEnum.GetDefaultAudioEndpoint(eRender, eMultimedia, FmmDev); 
    FmmDev.Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, nil, FmmEndpoint); 
end; 

// --------------------------------------------------------------------------- 

function TvistaMixer.getMute: boolean; 
begin 
    FmmEndpoint.GetMute(Result); 
end; 

// --------------------------------------------------------------------------- 

function TvistaMixer.getVolume: integer; 
var 
    VolLevel: Single; 
begin 
    FmmEndpoint.GetMasterVolumeLevelScalar(VolLevel); 
    result := Round(VolLevel * 65535); 
end; 

// --------------------------------------------------------------------------- 

procedure TvistaMixer.setMute(Value: boolean); 
begin 
    FmmEndpoint.SetMute(Value, nil); 
end; 

// --------------------------------------------------------------------------- 

procedure TvistaMixer.setVolume(Value: integer); 
var 
    fValue: Single; 
begin 
    if (value < 0) then 
    value := 0; 
    if (value > 65535) then 
    value := 65535; 
    fValue := Value/65535; 
    FmmEndpoint.SetMasterVolumeLevelScalar(fValue, nil); 
end; 

// --------------------------------------------------------------------------- 

end. 

-

unit MMDevApi_tlb; 

interface 
    uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL,ComObj; 
const 
    // TypeLibrary Major and minor versions 

    CLSID_MMDeviceEnumerator: 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}'; 
    GUID_NULL: TGUID        = '{00000000-0000-0000-0000-000000000000}'; 

    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 GetMasterVolumeLevelScalar(out fLevel: single):Integer; stdcall; 
    Function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: TGUID):Integer; stdcall; 
    Function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: single; pguidEventContext: TGUID):Integer; stdcall; 
    Function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double) : Integer; stdcall; 
    Function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double) : 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: TGUID) :Integer; stdcall; 
    Function VolumeStepDown(pguidEventContext: TGUID) :Integer; stdcall; 
    Function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall; 
    Function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall; 
    end; 

    IPropertyStore = interface(IUnknown) 
    end; 

type 
    IMMDevice = interface(IUnknown) 
    ['{D666063F-1587-4E43-81F1-B948E807363F}'] 
    Function Activate( const refId :TGUID; 
         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

Bu Glob mükemmel cevap bir ektir. SetMute/GetMute fonksiyon tanımlamaları 32bit tamsayı Tamsayı değişkenler kullanmak ve tamsayı Delphi boole'sini döküm için

unit MMDevApi_tlb; 
const 
    DEVICE_STATE_ACTIVE  = $00000001; 
    DEVICE_STATE_UNPLUGGED = $00000002; 
    DEVICE_STATE_NOTPRESENT = $00000004; 
    DEVICE_STATEMASK_ALL  = $00000007; 

    IMMAudioEndpointVolume = interface(IUnknown) 
    ['{5CDF2C82-841E-4546-9722-0CF74078229A}'] 
    Function SetMute(iMute: Integer; pguidEventContext: PGUID) :Integer; stdcall; 
    Function GetMute(out iMute: Integer) :Integer; stdcall; 

Değişim SetMute ve GetMute beyanı değerleri kullanmalıdır.

yöntem çağrıları daha sonra var iMute: tamsayı AudioEndVol.SetMute (tamsayı (CheckBox1.Checked), @GUID_NULL); AudioEndVol.GetMute (iMute);

Boole kullanılması trayicon'un dilsiz durumunu düzgün bir şekilde tanımlamamasını sağlar ve sesi açmaz. Aynı şey, 32bit'lik tamsayı parametresi veya bellek hizalamaları rasgele olarak bozulduğunda kullanılmalıdır. Ben bu yüzden bir googled bir akıl yürütme anlamadım ve mükemmel bir JEDI makale bulundu.

Bazı win32 çağrıları bit değeri hakkında çok seçici, Delphi Bool/Boolean her zaman C meslektaşlarıyla iyi gitmiyor. Tam bir bit eşlemesine sahip olmak için C bool değişkenini temsil etmek için 32 bit tamsayı kullanın. Çoğu win32 C yöntemleri o kadar katı değildir ve boole/boolean ile iyi çalışır. Bu özel MMDeviceAPI.SetMute işlevi nadir bir köşe durumudur ve Delphi programcıları çok etkilenir. http://blog.delphi-jedi.net/2008/09/25/bool-boolean-and-integer/

İlgili konular