首 页文章中心下载中心繁體中文
设为首页
加入收藏
联系我们
您当前的位置:开源盛世-源代码下载网 -> 文章中心 -> PDA 专区 -> 文章内容 退出登录 用户管理
栏目导航
· VC++专区 · V B 专区
· GIS 专区 · PDA 专区
· 其他编程 · 网站开发类
· 数据库类 · 软件应用
· 网络安全 · 论文专区
· 综合资讯
热门文章
· Tab Control控件使用...
· 学生档案管理系统
· [图文] 排列组合公式
· UTF-8与GB2312之间的...
· DirectShow下载安装...
· Virtual PC 在PAE模...
· Windows2000终端服务...
· MapInfo上的GIS系统...
· Mapbasic参考手册索...
· MapX应用开发中文讲...
相关文章
C#实现PDA电源/背光管理
作者:不详  来源:vscodes.com整理  发布时间:2007-8-23 15:29:29  发布人:Polaris

减小字体 增大字体

        一般的嵌入式项目通常采用sometimes offline的设计思想, 这样的设计必将有数据同步的功能, 然而数据同步时如果本地没有数据库,加之项目数据的复杂性和无线通讯的带宽等方面的制约,  常常使得同步时间非常漫长, 数据同步这样的操作往往又不能采用单独的线程在后台完成, 恰巧我正在开发的项目就是具备了这些特点.
         通过我们版本发布后对用户使用的调查发现, 同步失败的原因有一半以上是由于PDA在常时间闲置时会自动关闭电源, 以导致网络连接断开, 而由于用户对PDA的使用并不熟悉, 我们没理由要求用户到控制面板中去进行电源设置. 程序中解决掉电问题成为必然. 到微软查找了相关的资料找到了一些解决办法. 要防止PDA闲置时电源自动关闭,可以从两种角度去思考, 常规做法是更改WinCE配置, 也就是修改电源闲置关闭时间的注册表键值, 然后激发一个事件重新加载这些配置, 这样做存在一个恢复的问题, 当我们的工作(同步)完成后需要恢复用户原来的配置, 那么我们换一角度去思考, 既然WinCE允许设置自动关闭时间, 那么WinCE系统中必然存在一个线程在指定时间后挂起系统(关闭电源), 这个线程一定有一个定时器, 那么我们是否可以不断的刷新这个定时器,让永远到达不到用户设置的自动关闭时间呢? 事实证明这个思路是可行的.
        查阅相关资料可以知道在WinCE核心API库(coredll.dll)中存在一个函数SystemIdleTimerReset, 正是这个函数实现了系统自动挂起的定时功能.
系统在设置了自动关闭时间会调用这个函数开始记时, 这样我们只要在系统尚未达到关闭时间之前调用他就OK, 通过控制面板查看电源管理中的自动关闭设置发现, 最短关闭时间为一分钟.那么就是说只要我们每59秒调用一次SystemIdleTimerReset即可实现电源永不关闭. 有了思路就很简单了:
 1[DllImport("CoreDll.dll")]
 2        private static extern void SystemIdleTimerReset();
 3
 4        private static int nDisableSleepCalls = 0;
 5        private static System.Threading.Timer preventSleepTimer = null;
 6
 7        private static void PokeDeviceToKeepAwake(object extra)
 8        {
 9            try
10            {
11                SystemIdleTimerReset();
12            }
13            catch (Exception e)
14            {
15                // TODO
16            }
17        }
18        
19        /**//// <summary>
20        /// 禁止设备自动关闭电源
21        /// </summary>
22        public static void DisableDeviceSleep()
23        {
24            nDisableSleepCalls++;
25            if (nDisableSleepCalls == 1)
26            {
27                //Debug.Assert(preventSleepTimer == null);
28                // 没隔30秒刷新一次计时器
29                preventSleepTimer = new System.Threading.Timer(new System.Threading.TimerCallback(PokeDeviceToKeepAwake),
30                    null, 0, 30 * 1000);
31            }
32        }
33        /**//// <summary>
34        /// 允许设备自动关闭电源
35        /// </summary>
36        public static void EnableDeviceSleep()
37        {
38            nDisableSleepCalls--;
39            if (nDisableSleepCalls == 0)
40            {
41                //Debug.Assert(preventSleepTimer != null);
42                if (preventSleepTimer != null)
43                {
44                    preventSleepTimer.Dispose();
45                    preventSleepTimer = null;
46                }
47            }
48        }
49

        这样我们只要在同步前调用DisableDeviceSleep方法,在同步后调用EnableDeviceSleep就OK了, 在也不用担心用户PDA电源自动关闭引起同步失败了.

       可是事情远比我们想象的要复杂, 大家都PDA的背光也会自动关闭, 你可以想象一用户在同步时候的情形, 他在等待漫长的同步过程时背光突然关闭了, 可是我们让他电源不断, 这时候他以为电源关闭了, 结果按下了电源键盘, 结果不用我说了吧.

       背光我们同样要处理, 是否也是有个线程作为背光定时器内, 答案是肯定的, 不过为了强调我们研究的技术性, 背光我用修改WinCE注册表方式搞定. 通过查阅资料我找到了这四个注册表键:

     [HKEY_CURRENT_USER\ControlPanel\Backlight\BatteryTimeout]  使用电池时PDA自动关闭背光时间

     [HKEY_CURRENT_USER\ControlPanel\Backlight\BatteryTimeout]  使用外接电源时PDA自动关闭背光时间

     [HKEY_CURRENT_USER\ControlPanel\Backlight\BatteryTimeoutUnchecked]  禁止使用电池自动关闭时为选中的时间

     [HKEY_CURRENT_USER\ControlPanel\Backlight\ACTimeoutUnchecked] 禁止使用外接电源自动关闭时为选中的时间

       我们要做就是修改这些键值, 然后激发一个能让这些新值生效的事件。 思路很简单,直接看代码了:

/**//// <summary>
        /// 指示背光是否被设置
        /// </summary>
        private static int nBatteryTimeoutCalls = 0;
        private static int nACTimeoutCalls = 0;
        /**//// <summary>
        /// 禁止背光自动关闭
        /// </summary>
        public static bool DisableBacklightOff() 
        {
            OpenNETCF.Win32.RegistryKey key = null;
            bool bIsSet = false;
            try
            {
                key = OpenNETCF.Win32.Registry.CurrentUser.OpenSubKey(@"ControlPanel\Backlight\", true);
                if(key != null)
                {
                    string oldValue1 = String.Empty;
                    string oldValue2 = String.Empty;
                    oldValue1 = key.GetValue("BatteryTimeout").ToString();
                    oldValue2 = key.GetValue("ACTimeout").ToString();
                    if(oldValue1.Trim() != "0")
                    {
                        nBatteryTimeoutCalls++;
                        if(nBatteryTimeoutCalls == 1)
                        {
                            key.SetValue("BatteryTimeout", 0);
                            key.SetValue("BatteryTimeoutUnchecked", int.Parse(oldValue1));
                            bIsSet = true;
                        }
                        else
                        {
                            nBatteryTimeoutCalls--;
                        }
                    }
                    if(oldValue2.Trim() != "0")
                    {
                        nACTimeoutCalls++;
                        if(nACTimeoutCalls == 1)
                        {
                            key.SetValue("ACTimeout", 0);
                            key.SetValue("ACTimeoutUnchecked", int.Parse(oldValue2));
                            bIsSet = true;
                        }
                        else
                        {
                            nACTimeoutCalls--;
                        }
                    }
                    if(bIsSet)
                    {
                        IntPtr hBackLightEvent = CreateEvent(IntPtr.Zero, false, true, "BackLightChangeEvent"); 
                        if (hBackLightEvent != IntPtr.Zero) 
                        
                            EventModify(hBackLightEvent,3); 
                            CloseHandle(hBackLightEvent); 
                        }
                    }
                }
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                if(key != null)
                {
                    key.Dispose();
                    key = null;
                }
            }
        }
        
        /**//// <summary>
        /// 允许背光自动关闭
        /// </summary>
        public static bool EnableBacklightOff()
        {
            OpenNETCF.Win32.RegistryKey key = null;
            bool bIsSet = false;
            try
            {
                key = OpenNETCF.Win32.Registry.CurrentUser.OpenSubKey(@"ControlPanel\Backlight\", true);
                if(key != null)
                {
                    string oldValue1 = String.Empty;
                    string oldValue2 = String.Empty;
                    oldValue1 = key.GetValue("BatteryTimeoutUnchecked").ToString();
                    oldValue2 = key.GetValue("ACTimeoutUnchecked").ToString();
                    if(oldValue1.Trim() != "0")
                    {
                        nBatteryTimeoutCalls--;
                        if(nBatteryTimeoutCalls == 0)
                        {
                            key.SetValue("BatteryTimeoutUnchecked", 0);
                            key.SetValue("BatteryTimeout", int.Parse(oldValue1));
                            bIsSet = true;
                        }
                        else
                        {
                            nBatteryTimeoutCalls++;
                        }
                    }
                    if(oldValue2.Trim() != "0")
                    {
                        nACTimeoutCalls--;
                        if(nACTimeoutCalls == 0)
                        {
                            key.SetValue("ACTimeoutUnchecked", 0);
                            key.SetValue("ACTimeout", int.Parse(oldValue2));
                            bIsSet = true;
                        }
                        else
                        {
                            nACTimeoutCalls++;
                        }
                    }
                    if(bIsSet)
                    {
                        IntPtr hBackLightEvent = CreateEvent(IntPtr.Zero, false, true, "BackLightChangeEvent"); 
                        if (hBackLightEvent != IntPtr.Zero) 
                        
                            EventModify(hBackLightEvent,3); 
                            CloseHandle(hBackLightEvent); 
                        }
                    }
                }
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                if(key != null)
                {
                    key.Dispose();
                    key = null;
                }
            }
        }

 

        OK! 问题解决.

End of《C#实现PDA电源/背光管理》

[] [返回上一页] [打 印] [收 藏]
下一篇文章:控制PDA的背光和电源
 
∷相关“C#实现PDA电源/背光管理”文章评论∷
(评论内容只代表网友观点,与本站立场无关!) [更多评论...]
关于本站 - 网站帮助 - 广告合作 - 下载声明 - 友情连接 - 网站地图 网站目录 鄂ICP备06007162
开源盛世 版权所有Copyright © 2003-2005 VSCodes.Com. All Rights Reserved.