WinCE系统音量的设置
//========================================================================
//TITLE:
// WinCE系统音量的设置
//AUTHOR:
// norains
//DATE:
// Sunday 8-April-2007
//Environment:
// EVC4.0 + Standard SDK 4.2
// EVC4.0 + Standard SDK 5.0
//========================================================================
首先我们来看一段最简单的改变音量的代码:
waveOutSetVolume()的第一个参数是设备ID,因为需要更改的是整个系统音量,所以在这里直接取0值即可;第二个参数是需要设置的音量数值,范围是从 0x0 ~ 0xFFFFFFFF.
但这个函数的功能却也是非常有限的,也就是说,它只能更改系统的主音量;如果想修改屏幕点击声,则就无能为力.
有些细心的朋友会从"控制面板"的"声音"入手,发现每次在控制面板调节声音,相应的"ControlPanel/Volume"下的键值数值都会变更.但如果是直接修其下的改注册表,却是无论如何都达不到相应的功能的----因为没有通知系统,注册表已经被修改.
如果需要告知系统,注册表已经修改,并请系统依照修改的数值来更改音量,则需要调用微软一个未公开的函数:AudioUpdateFromRegistry().
这个函数在文档中是无法搜索到,如果需要调用这个函数,可以有两种方法.
一是直接包含"pwinuser.h"文件,然后直接调用.
二是调用coredll.dll库,引出该函数并使用.
这里展示一个调用的例子:
只要更新了注册表,然后调用该函数,则系统会根据键值来进行相应的调整.
那么现在让我们来看看位于"ControlPanel/Volume"注册表中各键值的意义:
Volume: 系统的主音量,范围是0x0 ~ 0xFFFFFFFF.
Screen: 屏幕敲击声. 当数值为0时即为无声,1为柔和,65538为洪亮
Key: 键盘敲击声,数值的意义和Screen相同.
Mute: 控制其它静音的选项. 置0x04位为1时允许事件声音,0x02允许应用程序声音,0x01允许警告声.需要注意的是,如果不允许应用程序声音,则警告声位也将被忽略.
如果每次更改音量都要改写注册表,调用动态链接库,会显得比较麻烦.为了写代码的便利,在此封装了这个声音的操作:
(注:CReg 请参见此篇文章:http://blog.csdn.net/norains/archive/2007/04/08/1556296.aspx)
//////////////////////////////////////////////////////////////////////
// SysVolume.h: interface for the CSysVolume class.
//
//Version:
// 1.0.0
//Date:
// 2007.04.08
//////////////////////////////////////////////////////////////////////
#ifndef SYSVOLUME_H
#define SYSVOLUME_H
#include "Reg.h"
//-------------------------------------------------------------------------
//Macro define
#define MIN_VOLUME 0
#define MAX_VOLUME 0xFFFFFFFF
//-------------------------------------------------------------------------
//Enum value
enum VolumeModeType
{
VOL_SOFT,
VOL_LOUD,
VOL_MUTE
};
//------------------------------------------------------------------------
class CSysVolume
{
public:
BOOL SetVolumeScreenTap(VolumeModeType volMode);
BOOL SetVolumeKeyClick(VolumeModeType volMode);
BOOL EnableSoundNotification(BOOL bEnable);
BOOL EnableSoundApplication(BOOL bEnable);
BOOL EnableSoundEvent(BOOL bEnable);
BOOL SetVolume(DWORD dwVol);
CSysVolume();
virtual ~CSysVolume();
protected:
BOOL Apply();
CReg m_Reg;
};
#endif //#ifndef SYSVOLUME_H
//////////////////////////////////////////////////////////////////////
// SysVolume.cpp: implementation of the CSysVolume class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SysVolume.h"
//======================================================================
//Macro define
//Registry KEY
#define BASE_KEY HKEY_CURRENT_USER
#define SUB_KEY TEXT("ControlPanel/Volume")
#define VALUE_VOLUME TEXT("Volume")
#define VALUE_SCREEN TEXT("Screen")
#define VALUE_KEY TEXT("key")
#define VALUE_MUTE TEXT("Mute")
//For the screen tap and the key click
#define VOL_VALUE_MUTE 0
#define VOL_VALUE_LOUD 65538
#define VOL_VALUE_SOFT 1
//The bit for sound
#define BIT_EVENT 0x4
#define BIT_APPLICATION 0x2
#define BIT_NOTIFICATION 0x1
//======================================================================
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSysVolume::CSysVolume()
{
m_Reg.Create(BASE_KEY, SUB_KEY);
}
CSysVolume::~CSysVolume()
{
}
//---------------------------------------------------------------------
//Description:
// Apply the volume
//---------------------------------------------------------------------
BOOL CSysVolume::Apply()
{
typedef void (WINAPI *DLL_AUDIOUPDATEFROMREGISTRY)();
DLL_AUDIOUPDATEFROMREGISTRY Dll_AudioUpdateFromRegistry = NULL;
HINSTANCE hCoreDll = LoadLibrary(TEXT("coredll.dll"));
if (hCoreDll)
{
Dll_AudioUpdateFromRegistry = (DLL_AUDIOUPDATEFROMREGISTRY)GetProcAddress(hCoreDll, _T("AudioUpdateFromRegistry"));
if (Dll_AudioUpdateFromRegistry)
{
(Dll_AudioUpdateFromRegistry)();
}
else
{
return FALSE;
}
FreeLibrary(hCoreDll);
}
else
{
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------
//Description:
// Enable the sound for events
//---------------------------------------------------------------------
BOOL CSysVolume::EnableSoundEvent(BOOL bEnable)
{
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
DWORD dwVal = m_Reg.GetValueDW(VALUE_MUTE);
if(bEnable == TRUE)
{
dwVal |= BIT_EVENT;
}
else
{
dwVal &= ~BIT_EVENT;
}
m_Reg.SetDW(VALUE_MUTE,dwVal);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Enable the sound for application
//---------------------------------------------------------------------
BOOL CSysVolume::EnableSoundApplication(BOOL bEnable)
{
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
DWORD dwVal = m_Reg.GetValueDW(VALUE_MUTE);
if(bEnable == TRUE)
{
dwVal |= BIT_APPLICATION;
}
else
{
dwVal &= ~BIT_APPLICATION;
}
m_Reg.SetDW(VALUE_MUTE,dwVal);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Enable the sound for notifications. If the sound of application is
//mute, the sound of notification is mute too.
//---------------------------------------------------------------------
BOOL CSysVolume::EnableSoundNotification(BOOL bEnable)
{
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
DWORD dwVal = m_Reg.GetValueDW(VALUE_MUTE);
if(bEnable == TRUE)
{
dwVal |= BIT_NOTIFICATION;
}
else
{
dwVal &= ~BIT_NOTIFICATION;
}
m_Reg.SetDW(VALUE_MUTE,dwVal);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Set the key click volume
//---------------------------------------------------------------------
BOOL CSysVolume::SetVolumeKeyClick(VolumeModeType volMode)
{
DWORD dwVol = 0;
switch(volMode)
{
case VOL_SOFT:
dwVol = VOL_VALUE_SOFT;
break;
case VOL_LOUD:
dwVol = VOL_VALUE_LOUD;
break;
case VOL_MUTE:
dwVol = VOL_VALUE_MUTE;
break;
}
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
m_Reg.SetDW(VALUE_KEY,dwVol);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Set the screen tap volume
//---------------------------------------------------------------------
BOOL CSysVolume::SetVolumeScreenTap(VolumeModeType volMode)
{
DWORD dwVol = 0;
switch(volMode)
{
case VOL_SOFT:
dwVol = VOL_VALUE_SOFT;
break;
case VOL_LOUD:
dwVol = VOL_VALUE_LOUD;
break;
case VOL_MUTE:
dwVol = VOL_VALUE_MUTE;
break;
}
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
m_Reg.SetDW(VALUE_SCREEN,dwVol);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Set the volume.
//
//Parameters:
// dwVol: The volume to set. And the range is MIN_VOLUME ~ MAX_VOLUME
//---------------------------------------------------------------------
BOOL CSysVolume::SetVolume(DWORD dwVol)
{
if(dwVol < MIN_VOLUME || dwVol > MAX_VOLUME)
{
return FALSE;
}
m_Reg.SetDW(VALUE_VOLUME,dwVol);
return Apply();
}
由于CSysVolume类将复杂的操作封装在内部,因此设置音量的非常简单.
以更改屏幕敲击声为洪亮为例:
//TITLE:
// WinCE系统音量的设置
//AUTHOR:
// norains
//DATE:
// Sunday 8-April-2007
//Environment:
// EVC4.0 + Standard SDK 4.2
// EVC4.0 + Standard SDK 5.0
//========================================================================
首先我们来看一段最简单的改变音量的代码:
DWORD dwVolume = 0xAAAAAAAA;
waveOutSetVolume(0,dwVolume);
waveOutSetVolume(0,dwVolume);
waveOutSetVolume()的第一个参数是设备ID,因为需要更改的是整个系统音量,所以在这里直接取0值即可;第二个参数是需要设置的音量数值,范围是从 0x0 ~ 0xFFFFFFFF.
但这个函数的功能却也是非常有限的,也就是说,它只能更改系统的主音量;如果想修改屏幕点击声,则就无能为力.
有些细心的朋友会从"控制面板"的"声音"入手,发现每次在控制面板调节声音,相应的"ControlPanel/Volume"下的键值数值都会变更.但如果是直接修其下的改注册表,却是无论如何都达不到相应的功能的----因为没有通知系统,注册表已经被修改.
如果需要告知系统,注册表已经修改,并请系统依照修改的数值来更改音量,则需要调用微软一个未公开的函数:AudioUpdateFromRegistry().
这个函数在文档中是无法搜索到,如果需要调用这个函数,可以有两种方法.
一是直接包含"pwinuser.h"文件,然后直接调用.
二是调用coredll.dll库,引出该函数并使用.
这里展示一个调用的例子:
typedef void (WINAPI *DLL_AUDIOUPDATEFROMREGISTRY)();
DLL_AUDIOUPDATEFROMREGISTRY Dll_AudioUpdateFromRegistry = NULL;
HINSTANCE hCoreDll = LoadLibrary(TEXT("coredll.dll"));
if (hCoreDll)
{
Dll_AudioUpdateFromRegistry = (DLL_AUDIOUPDATEFROMREGISTRY)GetProcAddress(hCoreDll, _T("AudioUpdateFromRegistry"));
if (Dll_AudioUpdateFromRegistry)
{
(Dll_AudioUpdateFromRegistry)();
}
DLL_AUDIOUPDATEFROMREGISTRY Dll_AudioUpdateFromRegistry = NULL;
HINSTANCE hCoreDll = LoadLibrary(TEXT("coredll.dll"));
if (hCoreDll)
{
Dll_AudioUpdateFromRegistry = (DLL_AUDIOUPDATEFROMREGISTRY)GetProcAddress(hCoreDll, _T("AudioUpdateFromRegistry"));
if (Dll_AudioUpdateFromRegistry)
{
(Dll_AudioUpdateFromRegistry)();
}
只要更新了注册表,然后调用该函数,则系统会根据键值来进行相应的调整.
那么现在让我们来看看位于"ControlPanel/Volume"注册表中各键值的意义:
Volume: 系统的主音量,范围是0x0 ~ 0xFFFFFFFF.
Screen: 屏幕敲击声. 当数值为0时即为无声,1为柔和,65538为洪亮
Key: 键盘敲击声,数值的意义和Screen相同.
Mute: 控制其它静音的选项. 置0x04位为1时允许事件声音,0x02允许应用程序声音,0x01允许警告声.需要注意的是,如果不允许应用程序声音,则警告声位也将被忽略.
如果每次更改音量都要改写注册表,调用动态链接库,会显得比较麻烦.为了写代码的便利,在此封装了这个声音的操作:
(注:CReg 请参见此篇文章:http://blog.csdn.net/norains/archive/2007/04/08/1556296.aspx)
//////////////////////////////////////////////////////////////////////
// SysVolume.h: interface for the CSysVolume class.
//
//Version:
// 1.0.0
//Date:
// 2007.04.08
//////////////////////////////////////////////////////////////////////
#ifndef SYSVOLUME_H
#define SYSVOLUME_H
#include "Reg.h"
//-------------------------------------------------------------------------
//Macro define
#define MIN_VOLUME 0
#define MAX_VOLUME 0xFFFFFFFF
//-------------------------------------------------------------------------
//Enum value
enum VolumeModeType
{
VOL_SOFT,
VOL_LOUD,
VOL_MUTE
};
//------------------------------------------------------------------------
class CSysVolume
{
public:
BOOL SetVolumeScreenTap(VolumeModeType volMode);
BOOL SetVolumeKeyClick(VolumeModeType volMode);
BOOL EnableSoundNotification(BOOL bEnable);
BOOL EnableSoundApplication(BOOL bEnable);
BOOL EnableSoundEvent(BOOL bEnable);
BOOL SetVolume(DWORD dwVol);
CSysVolume();
virtual ~CSysVolume();
protected:
BOOL Apply();
CReg m_Reg;
};
#endif //#ifndef SYSVOLUME_H
//////////////////////////////////////////////////////////////////////
// SysVolume.cpp: implementation of the CSysVolume class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SysVolume.h"
//======================================================================
//Macro define
//Registry KEY
#define BASE_KEY HKEY_CURRENT_USER
#define SUB_KEY TEXT("ControlPanel/Volume")
#define VALUE_VOLUME TEXT("Volume")
#define VALUE_SCREEN TEXT("Screen")
#define VALUE_KEY TEXT("key")
#define VALUE_MUTE TEXT("Mute")
//For the screen tap and the key click
#define VOL_VALUE_MUTE 0
#define VOL_VALUE_LOUD 65538
#define VOL_VALUE_SOFT 1
//The bit for sound
#define BIT_EVENT 0x4
#define BIT_APPLICATION 0x2
#define BIT_NOTIFICATION 0x1
//======================================================================
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSysVolume::CSysVolume()
{
m_Reg.Create(BASE_KEY, SUB_KEY);
}
CSysVolume::~CSysVolume()
{
}
//---------------------------------------------------------------------
//Description:
// Apply the volume
//---------------------------------------------------------------------
BOOL CSysVolume::Apply()
{
typedef void (WINAPI *DLL_AUDIOUPDATEFROMREGISTRY)();
DLL_AUDIOUPDATEFROMREGISTRY Dll_AudioUpdateFromRegistry = NULL;
HINSTANCE hCoreDll = LoadLibrary(TEXT("coredll.dll"));
if (hCoreDll)
{
Dll_AudioUpdateFromRegistry = (DLL_AUDIOUPDATEFROMREGISTRY)GetProcAddress(hCoreDll, _T("AudioUpdateFromRegistry"));
if (Dll_AudioUpdateFromRegistry)
{
(Dll_AudioUpdateFromRegistry)();
}
else
{
return FALSE;
}
FreeLibrary(hCoreDll);
}
else
{
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------
//Description:
// Enable the sound for events
//---------------------------------------------------------------------
BOOL CSysVolume::EnableSoundEvent(BOOL bEnable)
{
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
DWORD dwVal = m_Reg.GetValueDW(VALUE_MUTE);
if(bEnable == TRUE)
{
dwVal |= BIT_EVENT;
}
else
{
dwVal &= ~BIT_EVENT;
}
m_Reg.SetDW(VALUE_MUTE,dwVal);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Enable the sound for application
//---------------------------------------------------------------------
BOOL CSysVolume::EnableSoundApplication(BOOL bEnable)
{
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
DWORD dwVal = m_Reg.GetValueDW(VALUE_MUTE);
if(bEnable == TRUE)
{
dwVal |= BIT_APPLICATION;
}
else
{
dwVal &= ~BIT_APPLICATION;
}
m_Reg.SetDW(VALUE_MUTE,dwVal);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Enable the sound for notifications. If the sound of application is
//mute, the sound of notification is mute too.
//---------------------------------------------------------------------
BOOL CSysVolume::EnableSoundNotification(BOOL bEnable)
{
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
DWORD dwVal = m_Reg.GetValueDW(VALUE_MUTE);
if(bEnable == TRUE)
{
dwVal |= BIT_NOTIFICATION;
}
else
{
dwVal &= ~BIT_NOTIFICATION;
}
m_Reg.SetDW(VALUE_MUTE,dwVal);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Set the key click volume
//---------------------------------------------------------------------
BOOL CSysVolume::SetVolumeKeyClick(VolumeModeType volMode)
{
DWORD dwVol = 0;
switch(volMode)
{
case VOL_SOFT:
dwVol = VOL_VALUE_SOFT;
break;
case VOL_LOUD:
dwVol = VOL_VALUE_LOUD;
break;
case VOL_MUTE:
dwVol = VOL_VALUE_MUTE;
break;
}
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
m_Reg.SetDW(VALUE_KEY,dwVol);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Set the screen tap volume
//---------------------------------------------------------------------
BOOL CSysVolume::SetVolumeScreenTap(VolumeModeType volMode)
{
DWORD dwVol = 0;
switch(volMode)
{
case VOL_SOFT:
dwVol = VOL_VALUE_SOFT;
break;
case VOL_LOUD:
dwVol = VOL_VALUE_LOUD;
break;
case VOL_MUTE:
dwVol = VOL_VALUE_MUTE;
break;
}
if(m_Reg.IsOK() != TRUE)
{
return FALSE;
}
m_Reg.SetDW(VALUE_SCREEN,dwVol);
return Apply();
}
//---------------------------------------------------------------------
//Description:
// Set the volume.
//
//Parameters:
// dwVol: The volume to set. And the range is MIN_VOLUME ~ MAX_VOLUME
//---------------------------------------------------------------------
BOOL CSysVolume::SetVolume(DWORD dwVol)
{
if(dwVol < MIN_VOLUME || dwVol > MAX_VOLUME)
{
return FALSE;
}
m_Reg.SetDW(VALUE_VOLUME,dwVol);
return Apply();
}
由于CSysVolume类将复杂的操作封装在内部,因此设置音量的非常简单.
以更改屏幕敲击声为洪亮为例:
CSysVolume sysVol;
sysVol.SetVolumeScreenTap(VOL_LOUD);
sysVol.SetVolumeScreenTap(VOL_LOUD);