Programatically control the "Sound Control" (Volume)

I need to take control of the "Sound Control" (Volume Control) of my computer (the icon aside the clock in windows).

Tiplically this icon controls the volume of anything is played on a windows computer (with your mouse). Well, i need to disable that little application and use my own VB.NET or C# application.

Is there some way or code example to do this?
LVL 2
José PerezAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

oobaylyCommented:
I've had to do this before, and found this code that does the dirty work for you.
http://social.msdn.microsoft.com/forums/en-US/isvvba/thread/05dc2d35-1d45-4837-8e16-562ee919da85/

Disabling the standard windows Volume Control should be a matter of unchecking the "Place volume icon in the taskbar" option in "Sound and Audio Devices Properties"
AudioMixerHelper.cs.txt
0
strickddCommented:
There is a nice batch file you can download and make cmd calls to: http://www.nirsoft.net/utils/nircmd.html
0
José PerezAuthor Commented:
i now have visual c# 2008, could you please tell me how to make it work?

it is not working if i copy and paste this code into a new form.

Oscar
0
Become a Microsoft Certified Solutions Expert

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

oobaylyCommented:
Can you give us a bit more information as to why it's not working. Any exceptions, compile errors etc.
The version of VS shouldn't make a difference as to whether it works or not.

On my machine, the volume operates in the range of 0 -> 65535 (ushort.MinValue -> ushort.MaxValue)
The way I checked for this is to set the volume to minimum & maximum and then call GetVolume() to determine the respective values. As far as I remember, this should vary from system to system though.
int percentage = 50;
int volume = (int)(percentage * ushort.MaxValue / 100);
AudioMixerHelper.SetVolume(volume);

Open in new window

0
José PerezAuthor Commented:
no file found error.

could you please upload a zip file with the working code?

Oscar
0
oobaylyCommented:
What do you mean by "no file found error". Is this a compile error, or a run-time error?
If it's a compile error, can you give us the exact error message.
If it's a runtime error, can you give us the exact exception and its stack trace.

All you have to do is create a new class in your project, copy and paste all the code into the file and voila, you should have access to the AudioMixerHelper.SetVolume method.

Add the following code to an empty console application project, or you can compile with the following command:
c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc.exe VolumeControl.cs.txt

Amendment to my last comment, the last line should read:
As far as I remember, this shouldn't vary from system to system though.


VolumeControl.cs.txt
0
José PerezAuthor Commented:
ok, i have the compiled version, now i need to add a form for visual testing, can you please tell me how to test it from a visual form?
0
oobaylyCommented:
Well, once you've understood how my example works, it shouldn't be a problem incorporating it into a Windows Forms project. All you have to do is add the same class to the project (without the Main method of course). Then you can call the SetVolumeMethod in an event like a Button Click event, etc.:
PhidgetTestAudioMixerHelper.SetVolume(ushort.MaxValue);
0
José PerezAuthor Commented:
can't make it. can you please do it and upload it?
0
oobaylyCommented:
To be quite honest, I don't understand what you mean be "do it". It is just a matter of adding a class to your project, as you would normally do with any other class that you create in a project, and copying & pasting the code from the forum.
0
José PerezAuthor Commented:
i'll be honest too. i am a vb 6.0 programmer and for me has been very difficult to move from vb to .net technolgy, i find it so complicated.

the thing is that I couldn't find any code in vb to do this correctly, so i posted in this forum because i read that there are a lot more possiblities in c# .net.
0
oobaylyCommented:
I can empathise with that! Took me a bit of effort moving to VB.Net from VB6, and plenty of frustration too.

If we start from scratch, so you can see how I mean adding the code to your project
  1. Open VS (I'm guessing you're using VS C# express), and create a new "Windows Forms Application" project
  2. In "Solution Explorer", right click on the project tree and select "Add" -> "Class"
  3. Rename the class "AudioMixerHelper" and click "Add"
  4. Delete all the code out of the new file that's been opened, and paste in all the code from box below
  5. Now go back to the Designer view of Form1, add two buttons to it, titling one "Get volume", and the other "Set Volume"
  6. Double click on "Get Volume" to create a click event handler and add the following code into the method:
          int percentage = 100 * PhidgetTest.AudioMixerHelper.GetVolume() / ushort.MaxValue;
          MessageBox.Show(percentage.ToString());
  7. Go back to the designer view, and double click on "Set Volume" to create a click event handler and add the following code into the method:
          int percentage = 50;
          PhidgetTest.AudioMixerHelper.SetVolume(percentage * ushort.MaxValue / 100);
  8. Press F5 to start the application, and check that the two buttons work as expected




using System;
 
using System.Runtime.InteropServices;
 
 
namespace PhidgetTest
 
{
 
    public class AudioMixerHelper
 
    {
 
        public const int MMSYSERR_NOERROR = 0;
 
        public const int MAXPNAMELEN = 32;
 
        public const int MIXER_LONG_NAME_CHARS = 64;
 
        public const int MIXER_SHORT_NAME_CHARS = 16;
 
        public const int MIXER_GETLINEINFOF_COMPONENTTYPE = 0x3;
 
        public const int MIXER_GETCONTROLDETAILSF_VALUE = 0x0;
 
        public const int MIXER_GETLINECONTROLSF_ONEBYTYPE = 0x2;
 
        public const int MIXER_SETCONTROLDETAILSF_VALUE = 0x0;
 
        public const int MIXERLINE_COMPONENTTYPE_DST_FIRST = 0x0;
 
        public const int MIXERLINE_COMPONENTTYPE_SRC_FIRST = 0x1000;
 
        public const int MIXERLINE_COMPONENTTYPE_DST_SPEAKERS =
 
            (MIXERLINE_COMPONENTTYPE_DST_FIRST + 4);
 
        public const int MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE =
 
            (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3);
 
        public const int MIXERLINE_COMPONENTTYPE_SRC_LINE =
 
            (MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2);
 
        public const int MIXERCONTROL_CT_CLASS_FADER = 0x50000000;
 
        public const int MIXERCONTROL_CT_UNITS_UNSIGNED = 0x30000;
 
        public const int MIXERCONTROL_CONTROLTYPE_FADER =
 
            (MIXERCONTROL_CT_CLASS_FADER | MIXERCONTROL_CT_UNITS_UNSIGNED);
 
        public const int MIXERCONTROL_CONTROLTYPE_VOLUME =
 
            (MIXERCONTROL_CONTROLTYPE_FADER + 1);
 
 
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerClose(int hmx);
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerGetControlDetailsA(int hmxobj, ref
 
                  MIXERCONTROLDETAILS pmxcd, int fdwDetails);
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerGetDevCapsA(int uMxId, MIXERCAPS
 
            pmxcaps, int cbmxcaps);
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerGetID(int hmxobj, int pumxID, int
 
            fdwId);
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerGetLineControlsA(int hmxobj, ref
 
                  MIXERLINECONTROLS pmxlc, int fdwControls);
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerGetLineInfoA(int hmxobj, ref
 
                  MIXERLINE pmxl, int fdwInfo);
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerGetNumDevs();
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerMessage(int hmx, int uMsg, int
 
            dwParam1, int dwParam2);
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerOpen(out int phmx, int uMxId,
 
            int dwCallback, int dwInstance, int fdwOpen);
 
        [DllImport("winmm.dll", CharSet = CharSet.Ansi)]
 
        private static extern int mixerSetControlDetails(int hmxobj, ref
 
                  MIXERCONTROLDETAILS pmxcd, int fdwDetails);
 
 
 
        public struct MIXERCAPS
 
        {
 
            public int wMid;
 
            public int wPid;
 
            public int vDriverVersion;
 
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN)]
 
            public string szPname;
 
            public int fdwSupport;
 
            public int cDestinations;
 
        }
 
 
 
        public struct MIXERCONTROL
 
        {
 
            public int cbStruct;
 
            public int dwControlID;
 
            public int dwControlType;
 
            public int fdwControl;
 
            public int cMultipleItems;
 
            [MarshalAs(UnmanagedType.ByValTStr,
 
                 SizeConst = MIXER_SHORT_NAME_CHARS)]
 
            public string szShortName;
 
            [MarshalAs(UnmanagedType.ByValTStr,
 
                 SizeConst = MIXER_LONG_NAME_CHARS)]
 
            public string szName;
 
            public int lMinimum;
 
            public int lMaximum;
 
            [MarshalAs(UnmanagedType.U4, SizeConst = 10)]
 
            public int reserved;
 
        }
 
 
 
        public struct MIXERCONTROLDETAILS
 
        {
 
            public int cbStruct;
 
            public int dwControlID;
 
            public int cChannels;
 
            public int item;
 
            public int cbDetails;
 
            public IntPtr paDetails;
 
        }
 
 
 
        public struct MIXERCONTROLDETAILS_UNSIGNED
 
        {
 
            public int dwValue;
 
        }
 
 
 
        public struct MIXERLINE
 
        {
 
            public int cbStruct;
 
            public int dwDestination;
 
            public int dwSource;
 
            public int dwLineID;
 
            public int fdwLine;
 
            public int dwUser;
 
            public int dwComponentType;
 
            public int cChannels;
 
            public int cConnections;
 
            public int cControls;
 
            [MarshalAs(UnmanagedType.ByValTStr,
 
                 SizeConst = MIXER_SHORT_NAME_CHARS)]
 
            public string szShortName;
 
            [MarshalAs(UnmanagedType.ByValTStr,
 
                 SizeConst = MIXER_LONG_NAME_CHARS)]
 
            public string szName;
 
            public int dwType;
 
            public int dwDeviceID;
 
            public int wMid;
 
            public int wPid;
 
            public int vDriverVersion;
 
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN)]
 
            public string szPname;
 
        }
 
 
 
        public struct MIXERLINECONTROLS
 
        {
 
            public int cbStruct;
 
            public int dwLineID;
 
 
 
            public int dwControl;
 
            public int cControls;
 
            public int cbmxctrl;
 
            public IntPtr pamxctrl;
 
        }
 
 
 
        private static bool GetVolumeControl(int hmixer, int componentType,
 
            int ctrlType, out MIXERCONTROL mxc, out int vCurrentVol)
 
        {
 
            // This function attempts to obtain a mixer control.
 
            // Returns True if successful.
 
            MIXERLINECONTROLS mxlc = new MIXERLINECONTROLS();
 
            MIXERLINE mxl = new MIXERLINE();
 
            MIXERCONTROLDETAILS pmxcd = new MIXERCONTROLDETAILS();
 
            MIXERCONTROLDETAILS_UNSIGNED du = new
 
                MIXERCONTROLDETAILS_UNSIGNED();
 
            mxc = new MIXERCONTROL();
 
            int rc;
 
            bool retValue;
 
            vCurrentVol = -1;
 
 
 
            mxl.cbStruct = Marshal.SizeOf(mxl);
 
            mxl.dwComponentType = componentType;
 
 
 
            rc = mixerGetLineInfoA(hmixer, ref mxl,
 
                MIXER_GETLINEINFOF_COMPONENTTYPE);
 
 
 
            if (MMSYSERR_NOERROR == rc)
 
            {
 
                int sizeofMIXERCONTROL = 152;
 
                int ctrl = Marshal.SizeOf(typeof(MIXERCONTROL));
 
                mxlc.pamxctrl = Marshal.AllocCoTaskMem(sizeofMIXERCONTROL);
 
                mxlc.cbStruct = Marshal.SizeOf(mxlc);
 
                mxlc.dwLineID = mxl.dwLineID;
 
                mxlc.dwControl = ctrlType;
 
                mxlc.cControls = 1;
 
                mxlc.cbmxctrl = sizeofMIXERCONTROL;
 
 
 
                // Allocate a buffer for the control
 
                mxc.cbStruct = sizeofMIXERCONTROL;
 
 
 
                // Get the control
 
                rc = mixerGetLineControlsA(hmixer, ref mxlc,
 
                    MIXER_GETLINECONTROLSF_ONEBYTYPE);
 
 
 
                if (MMSYSERR_NOERROR == rc)
 
                {
 
                    retValue = true;
 
 
 
                    // Copy the control into the destination structure
 
                    mxc = (MIXERCONTROL)Marshal.PtrToStructure(
 
                        mxlc.pamxctrl, typeof(MIXERCONTROL));
 
                }
 
                else
 
                {
 
                    retValue = false;
 
                }
 
                int sizeofMIXERCONTROLDETAILS =
 
                    Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
 
                int sizeofMIXERCONTROLDETAILS_UNSIGNED =
 
                    Marshal.SizeOf(typeof(MIXERCONTROLDETAILS_UNSIGNED));
 
                pmxcd.cbStruct = sizeofMIXERCONTROLDETAILS;
 
                pmxcd.dwControlID = mxc.dwControlID;
 
                pmxcd.paDetails =
 
 
 
                    Marshal.AllocCoTaskMem(sizeofMIXERCONTROLDETAILS_UNSIGNED);
 
                pmxcd.cChannels = 1;
 
                pmxcd.item = 0;
 
                pmxcd.cbDetails = sizeofMIXERCONTROLDETAILS_UNSIGNED;
 
 
 
                rc = mixerGetControlDetailsA(hmixer, ref pmxcd,
 
                    MIXER_GETCONTROLDETAILSF_VALUE);
 
 
 
                du = (MIXERCONTROLDETAILS_UNSIGNED)Marshal.PtrToStructure(
 
                    pmxcd.paDetails, typeof(MIXERCONTROLDETAILS_UNSIGNED));
 
 
 
                vCurrentVol = du.dwValue;
 
 
 
                return retValue;
 
            }
 
 
 
            retValue = false;
 
            return retValue;
 
        }
 
 
 
        private static bool SetVolumeControl(int hmixer, MIXERCONTROL mxc,
 
            int volume)
 
        {
 
            // This function sets the value for a volume control.
 
            // Returns True if successful
 
 
 
            bool retValue;
 
            int rc;
 
            MIXERCONTROLDETAILS mxcd = new MIXERCONTROLDETAILS();
 
            MIXERCONTROLDETAILS_UNSIGNED vol = new
 
                MIXERCONTROLDETAILS_UNSIGNED();
 
 
 
            mxcd.item = 0;
 
            mxcd.dwControlID = mxc.dwControlID;
 
            mxcd.cbStruct = Marshal.SizeOf(mxcd);
 
            mxcd.cbDetails = Marshal.SizeOf(vol);
 
 
 
            // Allocate a buffer for the control value buffer
 
            mxcd.cChannels = 1;
 
            vol.dwValue = volume;
 
 
 
            // Copy the data into the control value buffer
 
            mxcd.paDetails = Marshal.AllocCoTaskMem(Marshal.SizeOf(
 
                typeof(MIXERCONTROLDETAILS_UNSIGNED)));
 
            Marshal.StructureToPtr(vol, mxcd.paDetails, false);
 
 
 
            // Set the control value
 
            rc = mixerSetControlDetails(hmixer, ref mxcd,
 
                MIXER_SETCONTROLDETAILSF_VALUE);
 
 
 
            if (MMSYSERR_NOERROR == rc)
 
            {
 
                retValue = true;
 
            }
 
            else
 
            {
 
                retValue = false;
 
            } return retValue;
 
        }
 
 
 
        public static int GetVolume()
 
        {
 
            int mixer;
 
            MIXERCONTROL volCtrl = new MIXERCONTROL();
 
            int currentVol;
 
            mixerOpen(out mixer, 0, 0, 0, 0);
 
            int type = MIXERCONTROL_CONTROLTYPE_VOLUME;
 
            GetVolumeControl(mixer,
 
                MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, out volCtrl, out
 
                        currentVol);
 
            mixerClose(mixer);
 
 
 
            return currentVol;
 
        }
 
 
 
        public static void SetVolume(int vVolume)
 
        {
 
            int mixer;
 
            MIXERCONTROL volCtrl = new MIXERCONTROL();
 
            int currentVol;
 
            mixerOpen(out mixer, 0, 0, 0, 0);
 
            int type = MIXERCONTROL_CONTROLTYPE_VOLUME;
 
            GetVolumeControl(mixer,
 
                MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, out volCtrl, out
 
                        currentVol);
 
            if (vVolume > volCtrl.lMaximum) vVolume = volCtrl.lMaximum;
 
            if (vVolume < volCtrl.lMinimum) vVolume = volCtrl.lMinimum;
 
            SetVolumeControl(mixer, volCtrl, vVolume);
 
            GetVolumeControl(mixer,
 
                MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, type, out volCtrl, out
 
                        currentVol);
 
            if (vVolume != currentVol)
 
            {
 
                throw new Exception("Cannot Set Volume");
 
            }
 
            mixerClose(mixer);
 
        }
 
    }
 
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
José PerezAuthor Commented:
perfect!!!! really appreciate your effort.

Oscar
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.