C#实现PDA电源/背光管理

        一直把这里的密码忘了,今天在一个文本里发现我记录的一些网站的密码, 试了几个终于登陆进来了,本来打算 www.sharping.net和这里同步更新的, 因为忘记密码也懒得去找回, 现在可以更新了(废话).         一般的嵌入式项目通常采用sometimes offline的设计思想, 这样的设计必将有数据同步的功能, 然而数据同步时如果本地没有数据库,加之项目数据的复杂性和无线通讯的带宽等方面的制约,  常常使得同步时间非常漫长, 数据同步这样的操作往往又不能采用单独的线程在后台完成, 恰巧我正在开发的项目就是具备了这些特点.          通过我们版本发布后对用户使用的调查发现, 同步失败的原因有一半以上是由于PDA在常时间闲置时会自动关闭电源, 以导致网络连接断开, 而由于用户对PDA的使用并不熟悉, 我们没理由要求用户到控制面板中去进行电源设置. 程序中解决掉电问题成为必然. 到微软查找了相关的资料找到了一些解决办法. 要防止PDA闲置时电源自动关闭,可以从两种角度去思考, 常规做法是更改WinCE配置, 也就是修改电源闲置关闭时间的注册表键值, 然后激发一个事件重新加载这些配置, 这样做存在一个恢复的问题, 当我们的工作(同步)完成后需要恢复用户原来的配置, 那么我们换一角度去思考, 既然WinCE允许设置自动关闭时间, 那么WinCE系统中必然存在一个线程在指定时间后挂起系统(关闭电源), 这个线程一定有一个定时器, 那么我们是否可以不断的刷新这个定时器,让永远到达不到用户设置的自动关闭时间呢? 事实证明这个思路是可行的.         查阅相关资料可以知道在WinCE核心API库(coredll.dll)中存在一个函数SystemIdleTimerReset, 正是这个函数实现了系统自动挂起的定时功能. 系统在设置了自动关闭时间会调用这个函数开始记时, 这样我们只要在系统尚未达到关闭时间之前调用他就OK, 通过控制面板查看电源管理中的自动关闭设置发现, 最短关闭时间为一分钟.那么就是说只要我们每59秒调用一次SystemIdleTimerReset即可实现电源永不关闭. 有了思路就很简单了:
 1 None.gif [DllImport( " CoreDll.dll " )]
 2 None.gif         private   static   extern   void  SystemIdleTimerReset();
 3 None.gif
 4 None.gif         private   static   int  nDisableSleepCalls  =   0 ;
 5 None.gif         private   static  System.Threading.Timer preventSleepTimer  =   null ;
 6 None.gif
 7 None.gif         private   static   void  PokeDeviceToKeepAwake( object  extra)
 8 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
 9InBlock.gif            try
10ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
11InBlock.gif                SystemIdleTimerReset();
12ExpandedSubBlockEnd.gif            }

13InBlock.gif            catch (Exception e)
14ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
15InBlock.gif                // TODO
16ExpandedSubBlockEnd.gif            }

17ExpandedBlockEnd.gif        }

18 None.gif        
19 ExpandedBlockStart.gifContractedBlock.gif         /**/ /// <summary>
20InBlock.gif        /// 禁止设备自动关闭电源
21ExpandedBlockEnd.gif        /// </summary>

22 None.gif          public   static   void  DisableDeviceSleep()
23 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
24InBlock.gif            nDisableSleepCalls++;
25InBlock.gif            if (nDisableSleepCalls == 1)
26ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
27InBlock.gif                //Debug.Assert(preventSleepTimer == null);
28InBlock.gif                // 没隔30秒刷新一次计时器
29InBlock.gif                preventSleepTimer = new System.Threading.Timer(new System.Threading.TimerCallback(PokeDeviceToKeepAwake),
30InBlock.gif                    null030 * 1000);
31ExpandedSubBlockEnd.gif            }

32ExpandedBlockEnd.gif        }

33 ExpandedBlockStart.gifContractedBlock.gif         /**/ /// <summary>
34InBlock.gif        /// 允许设备自动关闭电源
35ExpandedBlockEnd.gif        /// </summary>

36 None.gif          public   static   void  EnableDeviceSleep()
37 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
38InBlock.gif            nDisableSleepCalls--;
39InBlock.gif            if (nDisableSleepCalls == 0)
40ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
41InBlock.gif                //Debug.Assert(preventSleepTimer != null);
42InBlock.gif                if (preventSleepTimer != null)
43ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
44InBlock.gif                    preventSleepTimer.Dispose();
45InBlock.gif                    preventSleepTimer = null;
46ExpandedSubBlockEnd.gif                }

47ExpandedSubBlockEnd.gif            }

48ExpandedBlockEnd.gif        }

49 None.gif

        这样我们只要在同步前调用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] 禁止使用外接电源自动关闭时为选中的时间

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

ExpandedBlockStart.gif ContractedBlock.gif /**/ /// <summary>
InBlock.gif        
/// 指示背光是否被设置
ExpandedBlockEnd.gif        
/// </summary>

None.gif          private   static   int  nBatteryTimeoutCalls  =   0 ;
None.gif        
private   static   int  nACTimeoutCalls  =   0 ;
ExpandedBlockStart.gifContractedBlock.gif        
/**/ /// <summary>
InBlock.gif        
/// 禁止背光自动关闭
ExpandedBlockEnd.gif        
/// </summary>

None.gif          public   static   bool  DisableBacklightOff() 
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            OpenNETCF.Win32.RegistryKey key 
= null;
InBlock.gif            
bool bIsSet = false;
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                key 
= OpenNETCF.Win32.Registry.CurrentUser.OpenSubKey(@"ControlPanel\Backlight\"true);
InBlock.gif                
if(key != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
string oldValue1 = String.Empty;
InBlock.gif                    
string oldValue2 = String.Empty;
InBlock.gif                    oldValue1 
= key.GetValue("BatteryTimeout").ToString();
InBlock.gif                    oldValue2 
= key.GetValue("ACTimeout").ToString();
InBlock.gif                    
if(oldValue1.Trim() != "0")
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        nBatteryTimeoutCalls
++;
InBlock.gif                        
if(nBatteryTimeoutCalls == 1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            key.SetValue(
"BatteryTimeout"0);
InBlock.gif                            key.SetValue(
"BatteryTimeoutUnchecked"int.Parse(oldValue1));
InBlock.gif                            bIsSet 
= true;
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            nBatteryTimeoutCalls
--;
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
if(oldValue2.Trim() != "0")
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        nACTimeoutCalls
++;
InBlock.gif                        
if(nACTimeoutCalls == 1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            key.SetValue(
"ACTimeout"0);
InBlock.gif                            key.SetValue(
"ACTimeoutUnchecked"int.Parse(oldValue2));
InBlock.gif                            bIsSet 
= true;
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            nACTimeoutCalls
--;
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
if(bIsSet)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        IntPtr hBackLightEvent 
= CreateEvent(IntPtr.Zero, falsetrue"BackLightChangeEvent"); 
InBlock.gif                        
if (hBackLightEvent != IntPtr.Zero) 
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif
InBlock.gif                            EventModify(hBackLightEvent,
3); 
InBlock.gif                            CloseHandle(hBackLightEvent); 
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif                
return true;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return false;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if(key != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    key.Dispose();
InBlock.gif                    key 
= null;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

None.gif        
ExpandedBlockStart.gifContractedBlock.gif        
/**/ /// <summary>
InBlock.gif        
/// 允许背光自动关闭
ExpandedBlockEnd.gif        
/// </summary>

None.gif          public   static   bool  EnableBacklightOff()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            OpenNETCF.Win32.RegistryKey key 
= null;
InBlock.gif            
bool bIsSet = false;
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                key 
= OpenNETCF.Win32.Registry.CurrentUser.OpenSubKey(@"ControlPanel\Backlight\"true);
InBlock.gif                
if(key != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
string oldValue1 = String.Empty;
InBlock.gif                    
string oldValue2 = String.Empty;
InBlock.gif                    oldValue1 
= key.GetValue("BatteryTimeoutUnchecked").ToString();
InBlock.gif                    oldValue2 
= key.GetValue("ACTimeoutUnchecked").ToString();
InBlock.gif                    
if(oldValue1.Trim() != "0")
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        nBatteryTimeoutCalls
--;
InBlock.gif                        
if(nBatteryTimeoutCalls == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            key.SetValue(
"BatteryTimeoutUnchecked"0);
InBlock.gif                            key.SetValue(
"BatteryTimeout"int.Parse(oldValue1));
InBlock.gif                            bIsSet 
= true;
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            nBatteryTimeoutCalls
++;
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
if(oldValue2.Trim() != "0")
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        nACTimeoutCalls
--;
InBlock.gif                        
if(nACTimeoutCalls == 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            key.SetValue(
"ACTimeoutUnchecked"0);
InBlock.gif                            key.SetValue(
"ACTimeout"int.Parse(oldValue2));
InBlock.gif                            bIsSet 
= true;
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            nACTimeoutCalls
++;
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
if(bIsSet)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        IntPtr hBackLightEvent 
= CreateEvent(IntPtr.Zero, falsetrue"BackLightChangeEvent"); 
InBlock.gif                        
if (hBackLightEvent != IntPtr.Zero) 
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif
InBlock.gif                            EventModify(hBackLightEvent,
3); 
InBlock.gif                            CloseHandle(hBackLightEvent); 
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif                
return true;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return false;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if(key != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    key.Dispose();
InBlock.gif                    key 
= null;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

None.gif
None.gif 
None.gif
None.gif

        OK! 问题解决.

转载于:https://www.cnblogs.com/Endink/archive/2006/07/18/sharping.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值