WM5,WM6背景灯及电源管理补充说明

在WM5中以前使用背景灯及电源管理的注册表修改方式,曾经实现了手机背景灯及电源长亮的功能。但是,最近在一些WM6.1的系统上,背景灯功能正常,但是电源仍会在不久后关闭。看来修改注册表的方法,仍然不能完全解决问题。

 

只好使用另外的方法,重置电源关闭时钟,来阻止电源关闭。

 

        一直把这里的密码忘了,今天在一个文本里发现我记录的一些网站的密码, 试了几个终于登陆进来了,本来打算 www.sharping.net和这里同步更新的, 因为忘记密码也懒得去找回, 现在可以更新了(废话).         一般的嵌入式项目通常采用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                    null030 * 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, falsetrue"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, falsetrue"BackLightChangeEvent"); 
                        
if (hBackLightEvent != IntPtr.Zero) 
                        

                            EventModify(hBackLightEvent,
3); 
                            CloseHandle(hBackLightEvent); 
                        }

                    }

                }

                
return true;
            }

            
catch
            
{
                
return false;
            }

            
finally
            
{
                
if(key != null)
                
{
                    key.Dispose();
                    key 
= null;
                }

            }

        }


 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值