Windows Mobile应用开发(1):使用Win32 SDK 开发屏幕手电程序

updated at 2009.04.14 10:36 am

最近刚入手BenQ Siemens P51, 2007年的老智能机了. 既然是智能机了, 总要好玩才行. 作为程序员, 当然是编程来玩. 这就让我开始踏上windows mobile开发的漫漫之路了.

在一个漆黑的夜晚, 当我象往常一样想用手机当手电时, 让我有了写个屏幕手电筒程序的冲动.

作为第一个wm应用, 当然要简单, 否则我也弄不出来啊. 屏幕手电筒程序真该算最简单的应用了, 给个背景为白的窗口就结了, 这要是搞不出来, 我从此洗手不干了. 不过事实说明, 前途是光明的, 道路是曲折的. 这么个简单的程序硬是耗费了一天的有大好青春. 我把开发的过程和大家分享, 希望对一些人有些帮助.

首先要做的事, 当然是了解一下windows mobile的开发基础. 看了一下资料, 总的分两大块, .net cf和native. 发现ms现在是力推.net cf, 有关native的文章不是很容易找.

由于.net的简单性, 我毫不犹豫的选择了.net cf. 接下来分析程序功能. 需要实现以下功能
1. 背景为白色的窗口
2. 保持屏幕亮度
3. 调节屏幕亮度
4. 防止待机

查了资料, 除了1, 其他2, 3, 4都需要p/invoke. 天哪, 看来.net还真是适合企业级开发. 虽然win32编程十分不熟悉, 但这结果只能让我使用win32了.

接下去的事就是一一解决以上问题了. 万事开头难啊, 看似简单的问题, 总会出问题. 经过艰苦研究, 终于完成. 以下分析一些重点.

 

功能1:

就不用细说了, 使用vc++创建智能设备项目, 选win32, 结果就是了. 这里有个小插曲, 装了ie8正式版后, vs2008的几个向导就不能用了, 很不幸, vc++的win32智能设备向导就是其中之一. 解决该问题也花了我不少时间, 解决方案见: http://www.cnblogs.com/andywu/archive/2009/04/08/1431653.html .

 

功能2:

需要使用以下代码

在WM_CREAT中
hPowerRequireMent = SetPowerRequirement(_T("BKL1:"), D0, 1, NULL, 0);
1. "BKL1:"指的是背光
2. D0指示需要的电量级别为FULL, 就是指不关电源

在WM_DESTORY中
if (hPowerRequireMent != NULL)
                ReleasePowerRequirement(hPowerRequireMent);


说明: 这一对函数一定要成对调用. 这样做可以保持屏幕亮度一直保持, 但不会防止系统待机, 所以在功能4中需要防止待机

 

功能3

这个功能让我查了好长时间, 但实现却是最顺利的. 基本上的结论是背光亮度的调节和具体的设备有关系, 没有统一的api. 我的p51刚好可以使用网上所说的一种方法, 改变注册表"HKEY_CURRENT_USER\ControlPanel\Backlight"中Brightness的值即可, Brightness是个DWORD值, 范围是0-9. 注册表改动后, 需要通知系统才能立即生效, 代码如下:

        HANDLE hBackLightEvent = CreateEvent(NULL, false, true, _T("BackLightChangeEvent"));
        if (hBackLightEvent != NULL)
        {
            SetEvent(hBackLightEvent);
            CloseHandle(hBackLightEvent);
        }

我使用上下键用于增加/减小亮度.

功能4

需要用到SystemIdleTimerReset()函数, 原理是通过计时器, 定时复位空闲时间, 达到防止待机的目的. 这里的小技巧是如何设置计时器的间隔. 系统待机的时间是可以设置的, 因此计时器的间隔必须小于系统设置的间隔, 这样就需要先得到系统的设置间隔A, 再将计时器的间隔设置为小于A的值即可. 我坦白我偷懒了, 我只是简单的将间隔设为3秒了.

 

下一步的打算

  1. c很生疏了, 难免有错, 仔细检查第1版的代码, 防止错误, 改进代码质量
  2. 增加一个最长时间设置, 在超过最长时间后让设备进入待机, 以防止过长时间将电池耗光.
  3. 记住上一次的亮度
  4. 实现mfc的版本
  5. 实现atl的版本

 

后记:

回头看看, 很多时间花在如何使用c++, win32 api 和 wince api上面了. 程序的确简单. 真是术业有专攻, 任何领域要想有所为, 都需要时间的积累.

 

代码下载

http://files.cnblogs.com/andywu/MyFlashLight.rar

项目是使用vs2008的,另外还需要windows mobile sdk

参考:

 

  1. Windows Mobile Power Management , http://www.codeproject.com/KB/mobile/WiMoPower1.aspx .

  2. A Flashlight App for Your Smartphone or PocketPC , http://www.codeproject.com/KB/mobile/Flashlight.aspx . 我主要是参考这篇文章, 要是早点看到这篇文章, 一个上午就搞定了. 可惜相见恨晚.

posted @ 2009-04-13 20:41 andy.wu 阅读(2463) 评论(11) 编辑 收藏

 回复 引用 查看   
#1楼 2009-04-13 22:36 马宁      
这个软件的创意……还真够无聊的。不过从技术实现上还是很有技术含量的。
欢迎加入Windows Mobile的开发者行列!

 回复 引用 查看   
#2楼 2009-04-14 06:57 Jake.NET      
不错的想法,想起以前出差,房子的保险丝老是断,也是用手机照面修的。有机会多交流。
 回复 引用   
#3楼 2009-04-14 07:47 supermfc[未注册用户]
上传的代码不对,希望博主及早更正。
 回复 引用 查看   
#4楼 2009-04-14 08:10 gray.dai      
增加空仓挂机功能(这是枪械上的说法),获知电量少于某值时,自动调整亮度.或者发出提示.

xtern "C" API BOOL WINAPI CheckBatteryLifePercent(BYTE byLifePercent)
{
SYSTEM_POWER_STATUS_EX pstatus;
BOOL bRet = GetSystemPowerStatusEx(&pstatus,TRUE);
if(bRet)
{
//if(pstatus.BatteryLifePercent <= byLifePercent || pstatus.BatteryFlag == BATTERY_FLAG_CRITICAL)
if(pstatus.BatteryLifePercent <= byLifePercent)
bRet = FALSE;
}
return bRet;
}

 回复 引用   
#5楼 2009-04-14 08:46 未来战士土[未注册用户]
好,学习了
 回复 引用 查看   
#6楼 2009-04-14 09:34 Edwin Liu      
手电不应该是使用屏幕背光吧,打开闪光灯才是王道,并在程序运行时定义手机上的按钮做为开关使用。
 回复 引用 查看   
#7楼[楼主] 2009-04-14 10:32 andy.wu      
@3#
代码应该没错。刚才可能是博客园自己出问题了,现在就可以了。

 回复 引用 查看   
#8楼[楼主] 2009-04-14 10:39 andy.wu      
@gray.dai

感谢您的代码,我去试试。

 回复 引用 查看   
#9楼 2009-04-14 10:48 AlexLiu      
nokia 很多低端手机还都具有手电功能啊。
 回复 引用 查看   
#10楼[楼主] 2009-04-14 11:01 andy.wu      
@Edwin Liu

确实如此,虽然有很多实例证明这么做有害于手机。不过打开闪光灯和设备更加相关了,相关的资料更少了。我目前还没有这样的编程能力,呵呵。

 回复 引用   
#11楼 2009-04-14 11:46 ZOK[未注册用户]
最麻烦的互操作漫延到手机开好,这是微软的败笔啊,唉 ....