Basic Volume Control
Microsoft Windows allows the system audio volume to be changed or muted with on-screen controls. This software control can be exploited in .NET applications to increase or decrease the volume or to mute the computer's sound altogether.
SendMessage API Function
It can be useful to add a volume control to some projects. In the simplest cases, it may be necessary to allow the user to increase or decrease the volume in stages, or to mute the computer's sound entirely. When this level of control is ample, you can incorporate it into your software with the use of a single Windows API function, named "SendMessage".
SendMessage allows you to send simple messages to specific windows synchronously. The function has a wide variety of disparate uses. For example, in an earlier article I explained how it can be used to create an elevated button control. In this article we will use it to change the master volume for the operating system. As it is a Windows API function, it must be accessed using Platform Invocation Services (P/Invoke). To simplify access to P/Invoke attributes, add the following using directive to your code:
With the using directive in place, we can add a reference to the external function by adding the code below.
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
The SendMessage function has four parameters and returns an IntPtr value. The return value holds the handle of a window when appropriate. When changing the volume the return value is not needed. The parameters are:
- hWnd. Specifies the handle of the window that you wish to send a message to. When changing the volume this can be set to the handle of the current window.
- Msg. Defines the type of message that is to be sent.
- wParam / lParam. The final two parameters allow further information to be sent with the message. We will use the lParam argument to specify the type of volume change that we wish to make. We do not need to use wParam so will pass it a dummy value.
The message that we need to provide to SendMessage and the additional information values are predefined integer codes. To make the source code more readable, you should define named constants for these values. The message for increasing, decreasing or muting the volume is always the same. It is named WM_APPCOMMAND and should be defined as follows:
const int WM_APPCOMMAND = 0x319;
Three further constants define the additional information for the message. These determine which volume control action will be performed:
const int APPCOMMAND_VOLUME_MUTE = 0x80000;
const int APPCOMMAND_VOLUME_DOWN = 0x90000;
const int APPCOMMAND_VOLUME_UP = 0xA0000;
Changing the Volume
With the function and constants defined we can call SendMessage. The first sample code mutes the volume, or restores it to its previous level if it is already muted. Note that the first argument is passed the Handle property of the current window. This assumes that the code is being called from the code behind a window. If you incorporate the function in a library you should provide a means to supply a suitable handle. Note also the use of a dummy zero value for the wParam argument.
SendMessage(this.Handle, WM_APPCOMMAND, IntPtr.Zero, (IntPtr)APPCOMMAND_VOLUME_MUTE);
To increase the volume, make the following call. The volume will be increased by a small amount with each invocation until the maximum level is reached.
SendMessage(this.Handle, WM_APPCOMMAND, IntPtr.Zero, (IntPtr)APPCOMMAND_VOLUME_UP);
Finally, to decrease the volume use the code below:
SendMessage(this.Handle, WM_APPCOMMAND, IntPtr.Zero, (IntPtr)APPCOMMAND_VOLUME_DOWN);
11 January 2012