//========================================================================
//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()的第一个参数是设备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)();
}
只要更新了注册表,然后调用该函数,则系统会根据键值来进行相应的调整.
那么现在让我们来看看位于"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);