norains的专栏

只专注于WINCE开发

用户操作
[即时聊天] [发私信] [加为好友]
norainsID:norains
142878次访问,排名598,好友0人,关注者53人。
代码其实是一种乐趣
norains的文章
原创 189 篇
翻译 0 篇
转载 10 篇
评论 274 篇
norains的公告
联系方式请看置顶文章
最近评论
dfdf:讨厌MFC!我觉得MFC就是太乱了!看似无用的代码不要不行,MD微软啥都给我们做完了,原理性的东西我们却永远没法搞懂了!
ironox:有个地方 我觉得很别扭,不知道怎么办好

比如说 CReg reg(HKEY_CURRENT_USER,TEXT("ControlPanel\Volume"));
ControlPanel\Volume 有可能不存在呀,这个该怎么处理哦?对象虽然创建了,出错了也没提示
szterry:呵呵,果然工作狂技术狂,同感,一样的感觉……不过我才刚毕业一年……搞IT就是玩……
jinlking:这个botton的实现只是在主窗口画了一块区域,对于事件的处理还要放在主窗口的窗口处理函数之中,在对应的消息处理上调用CheckTap来判断是否是此“按钮”,问一下,这种方法与把按钮封装在子窗口中有什么区别,二者使用那个更好?
KUODY:博主真是好人
文章分类
收藏
    相册
    动漫
    文章图片
    程序交流
    xumercury的BLOG
    狗友们的博客
    清蒸石斑鱼
    美女如刀锋
    茁茁的BLOG
    魅力老姐的窝
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 WinCE系统音量的设置收藏

    新一篇: WinCE圆圈消息 | 旧一篇: CReg类轻松读取注册表

    //========================================================================
    //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);

    发表于 @ 2007年04月08日 21:27:00|评论(loading...)|编辑

    新一篇: WinCE圆圈消息 | 旧一篇: CReg类轻松读取注册表

    评论

    #张挺 发表于2008-01-10 09:05:57  IP: 218.18.86.*
    您的文章很有价值,您个人也很乐于助人,非常感谢您的帮助!
    #SuperManZeng 发表于2008-03-18 10:44:09  IP: 220.166.9.*
    不错,终于在你这里的到了解决方法,谢谢!
    #zhongweiwin 发表于2008-05-28 20:26:15  IP: 116.28.32.*
    没有您我很多问题都没有办法解决。
    #qiuqiu 发表于2008-07-25 16:52:52  IP: 58.251.87.*
    引用了这两个类后不起作用
    如:
    void CSoundDlg::OnSoft()
    {
    SysVolume sysVol;
    sysVol.EnableSoundEvent(TRUE);
    sysVol.SetVolumeScreenTap(VOL_SOFT);
    }
    #bulrush 发表于2008-09-18 17:45:34  IP: 220.249.46.*
    你好,首先先感谢一下。我看了你的音量控制,自己也去实现了一下,但是我个人感觉“AudioUpdateFromRegistry”没有依据注册表的设置来更新控制面板的音量。没有马上更新,我重启系统后才看到更新的结果。也就是说这种方法是可行,但是必须要重启,显然这不合理。上面的兄弟说:引用了这两个类后不起作用
    如:
    void CSoundDlg::OnSoft()
    {
    SysVolume sysVol;
    sysVol.EnableSoundEvent(TRUE);
    sysVol.SetVolumeScreenTap(VOL_SOFT);
    }
    和我遇到的问题是一样的,重启后就起作用了。想和楼主探讨一下。究竟怎样才能让它马上依据注册表来更新?
    谢谢!
    2008-09-19 09:10:24作者回复
    你可以断点调试,看看这个Dll_AudioUpdateFromRegistry 函数是否被调用。qiuqiu的是因为没有调用这个函数所以才没设置成功。
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © norains