65.9K
CodeProject 正在变化。 阅读更多。
Home

适用于智能手机或 Pocket PC 的手电筒应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.57/5 (8投票s)

2008年8月2日

CPOL

3分钟阅读

viewsIcon

158195

downloadIcon

550

一个简单的、功能齐全的手电筒,帮助你在黑暗中看清东西。

FlashLight Screenshot

引言

本文是关于我在一个黑暗多风的夜晚编写的一个有点傻的 Windows Mobile 应用程序。

背景

明尼苏达州今年的天气非常不稳定,雷暴天气是我很久没见过的。第一次袭击,以及之后的一些雷暴,在半夜中断了我的电力,因为我喜欢尽可能地打开窗户,所以我发现自己在黑暗中从一个房间摸索到另一个房间,用我的 Pocket PC 提供一些照明。

不用说,我的小腿都伤痕累累。

“为什么不把一个真正的电筒放在床边呢?”你问。“呸!我将编写一个 .NET Compact Framework 应用程序来代替。这样更有趣!” 这是我的答案。

Using the Code

禁用屏幕超时

全白的全屏表单很容易,但它的第一个真正要求是手电筒必须在运行时禁用背光超时(第一个晚上我一直在点击屏幕,只是为了让它尽可能亮)。

这是使用 *coredll.dll* 上的 SetPowerRequirement 函数完成的(我喜欢他们将 DLL 命名为 *CoreDll.dll*,以防 DLL 扩展名不够具有描述性)。SetPowerRequirement 允许应用程序指定它在运行时需要来自特定设备的特定功率级别。背光设备的名称是 BKL1:。告诉操作系统你需要来自背光的全部功率将防止其超时。

此方法的唯一诀窍是你需要确保在完成后调用 ReleasePowerRequirement 。我将所有这些都包装在一个实现 IDisposablePowerRequirement 类中,以便可以轻松管理。

protected override void OnLoad(EventArgs e)
{
    ...
    m_powerRequirement = new PowerRequirement("BKL1:", PowerState.FULL);
    ...
}

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        if (m_powerRequirement != null)
            m_powerRequirement.Dispose();
    }
    base.Dispose(disposing);
} 

设置和释放电源要求的 **CE** API 的原型如下所示

[DllImport("coredll.dll")]
private static extern IntPtr SetPowerRequirement(string pvDevice, 
     PowerState DeviceState, int DeviceFlags, IntPtr pvSystemState, int StateFlags);

[DllImport("coredll.Dll")]
private static extern int ReleasePowerRequirement(IntPtr hPowerReq);

控制屏幕亮度

接下来,我想要一种调整背光亮度的方法。这需要在 **InterWebs** 上进行一些挖掘,但我最终找到了足够的提示来找到有效的东西。也就是说,它在运行 **Windows Mobile 6** 的我的 **HTC Touch** 上运行。听起来背光管理可能非常特定于设备和供应商,因此这可能有效或无效。

在 **Touch** 上,背光亮度由注册表设置 *HKCU\ControlPanel\Backlight\Brightness* 管理,这非常简单。一旦你知道了这一点,就只需要让操作系统知道你已经更改了该值。这是使用 event (Win32 风味,而不是 .NET 风味)完成的。哦,关于亮度调整的一个警告:它在模拟器上不起作用;无论你将其设置为多少,它都保持全亮度。

public int Brightness
{
     ...
     set
     {
         PowerStatus power = new PowerStatus();
         if (power.PowerLineStatus == PowerLineStatus.Online)
             SetBacklightValue("ACBrightness", value);
         else
             SetBacklightValue("Brightness", value);

         RaiseBackLightChangeEvent();
     }
}

private void SetBacklightValue(string name, int v)
{
     RegistryKey key = 
        Registry.CurrentUser.OpenSubKey(@"ControlPanel\Backlight", true);
     if (key != null)
     {
         key.SetValue(name, v);
         key.Close();
     }
}

private static void RaiseBackLightChangeEvent()
{
     IntPtr hBackLightEvent = 
	CreateEvent(IntPtr.Zero, false, true, "BackLightChangeEvent")
     if (hBackLightEvent != IntPtr.Zero)
     {
         SetEvent(hBackLightEvent);
         CloseHandle(hBackLightEvent);
     }
}

真正的全屏

你可能会认为将 Form 设置为最大化、去掉控件框、删除边框并使其成为最顶层窗口会提供一个真正的全屏窗口。这有时有效,但并非每次都有效。通常标题栏和开始菜单仍然会显示在手电筒窗口之上。要有效地获得真正的全屏模式,必须再次使用 CE API。

protected override void OnLoad(EventArgs e)
{
    ...

    SHFullScreen(this.Handle, SHFS_HIDETASKBAR | 
		SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);

    base.OnLoad(e);
}

private const int SHFS_SHOWTASKBAR = 0x0001;
private const int SHFS_HIDETASKBAR = 0x0002;
private const int SHFS_SHOWSIPBUTTON = 0x0004;
private const int SHFS_HIDESIPBUTTON = 0x0008;
private const int SHFS_SHOWSTARTICON = 0x0010;
private const int SHFS_HIDESTARTICON = 0x0020;

[DllImport("aygshell")]
static extern bool SHFullScreen(IntPtr hwnd, int dwState);

关注点

我一直无法弄清楚的这个应用程序的唯一真正的难题是电池续航时间指标。我希望能够显示估计的剩余电池寿命(你知道,对于那些“紧急情况,被困在电梯里”的情况,你可能需要节省电池)。我从 OpenNETCF.org 获得了一些代码,该代码使用 GetSystemPowerStatusEx 函数,但它永远只会在我的 **Touch** 和 **Windows Mobile 设备模拟器**上返回空数据。

如果有人知道如何从该方法中获取有意义的数据,请告诉我。我已将代码和功能包含在应用程序中,以防它在其他设备上运行。

历史

  • 2008-08-02 - 首次发布
  • 2008-08-04 - 添加了 SHFullScreen 调用
© . All rights reserved.