Windows Mobile - 禁用电源按钮

发布于 2024-07-18 03:40:55 字数 589 浏览 2 评论 0原文

有没有人成功捕获 WM5 设备上的电源/待机按钮,从而使您的代码阻止用户“关闭”甚至屏幕?

我有一个以横向方式使用屏幕的应用程序,我想捕获电源键按下的情况,以便(a)用户可以用双手握住设备,而不会意外关闭屏幕电源并且(作为奖励 - b) 将其用作 UI 按钮。

也许有人有低级黑客? 我正在使用 iPaq RX1950 上提供的 WM5。

请记住,没有不可能的事情 - 尤其是对于 WM5。 如果我同时回答这个问题,我会更新这个问题。


更新!

我发现了三个有效的技巧,按照可用性的相反顺序:

  1. 修补 keybddr.dll(在此设备上),通过您最喜欢的方式重新注入 ROM。 在这个带有工厂 ROM 的设备上 - 它可以工作,但我不想永久禁用它。

  2. 同步到电源管理消息队列,并在设备出现故障时“打开”设备。

    同步
  3. 更改注册表中的“电源状态”,使它们全部(大多数)“打开”。 这样,我可以使用 RAPI 禁用电源按钮,并让设备上的软件在事件 x、y 和 z 上“重置”注册表。

Has anyone successfully trapped the power/standby button on a WM5 device such that your code prevented users "switching off" even the screen?

I have an application that uses the screen in a landscape orientation and I'd like to trap the power key press so that (a) users can hold the device with both hands and not accidentally power-down the screen and (as a bonus - b) use it as a UI button.

Perhaps someone has a low level hack? I'm using WM5 as delivered on iPaq RX1950(s).

Remember, there is no such thing as impossible - especially with WM5. If I answer it myself in the meantime, I'll update the question.


Update!

I discovered three tricks that work, in reverse order of usability:

  1. Patch keybddr.dll (on this device), re-inject into the ROM via your favourite means. On this device with this factory ROM - it works, but I didn't want to permanently disable it.

  2. Sync to the Power Management message queue and turn the device "on" whenever it says it's going down.

  3. Change the "Power States" in the registry so they're all (most of them) "on". This way, I can use RAPI to disable the power button and have the software on the device "reset" the registry on event x, y and z.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怕倦 2024-07-25 03:40:55

电源按钮的实现取决于 OEM,因此一台设备上的解决方案不太可能在另一台设备上工作。 由于 Windows Mobile 设备中的实现存在很大差异,您会发现许多低级功能都是如此。

替代方案涉及多种内容的组合

  • 在无人值守模式下运行应用程序 在
  • 监视电源更改事件
  • 设备更改为无人值守模式时

请求完全开启模式关于电源管理的完整讨论超出了我在此讨论的范围。 你可以在这里读更多关于它的内容:
http://www.codeproject.com/KB/mobile/WiMoPower1.aspx

还有一个示例展示了如何在此处注册电源事件:
http://www.codeproject.com/KB/mobile/WiMoQueue.aspx

The implementation of the power button is OEM dependent, so a solution on one device is not likely to work on another device. Because of the wide variance of implementations in Windows Mobile devices you'll find this is true with many low level features.

The alternative involves a combination of things

  • Run your application in unattended mode
  • Monitor for power change events
  • when the device changes to unattended mode request full on mode

A full discussion of power management is beyond what I can discuss here. You can read more about it here:
http://www.codeproject.com/KB/mobile/WiMoPower1.aspx

There's also a sample that shows how one can register for power events here:
http://www.codeproject.com/KB/mobile/WiMoQueue.aspx

咆哮 2024-07-25 03:40:55

以下代码不会禁用电源按钮,但如果设备关闭,它将在 10 秒内再次打开设备。 它还将禁用任何省电功能。

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;

namespace Core.Mobile
{
    /// <summary>
    /// Allows manipulation the power management i.e. system standby
    /// </summary>
    public static class PowerManipulation
    {
        #region Private variables
        private static System.Threading.Timer _timer = null;
        private const int INTERVAL = 10000; //10 seconds
        #endregion
        #region Public methods
        /// <summary>
        /// Prevents the application from suspending/sleeping
        /// </summary>
        public static void DisableSleep()
        {
            if (_timer == null)
            {
                _timer = new System.Threading.Timer(new System.Threading.TimerCallback(Timer_Tick), null, 0, INTERVAL);
            }
            try
            {
                PowerPolicyNotify(PPN_UNATTENDEDMODE, 1);  //Ensure the application still runs in suspend mode
            }
            catch { }
        }
        /// <summary>
        /// Allows suspend/sleep operations
        /// </summary>
        public static void EnableSleep()
        {
            if (_timer != null)
            {
                _timer.Dispose();
                _timer = null;
            }
            try
            {
                PowerPolicyNotify(PPN_UNATTENDEDMODE, 0);
            }
            catch { }
        }
        #endregion
        #region Private methods
        /// <summary>
        /// Internal timer for preventing standby
        /// </summary>
        private static void Timer_Tick(object state)
        {
            try
            {
                SystemIdleTimerReset();
                SetSystemPowerState(null, POWER_STATE_ON, POWER_FORCE);
            }
            catch { }
        }
        #endregion
        #region PInvoke
        private const int PPN_UNATTENDEDMODE = 0x00000003;
        private const int POWER_STATE_ON = 0x00010000;
        private const int POWER_STATE_OFF = 0x00020000;
        private const int POWER_STATE_SUSPEND = 0x00200000;
        private const int POWER_FORCE = 4096;
        private const int POWER_STATE_RESET = 0x00800000;
        /// <summary>
        /// This function resets a system timer that controls whether or not the
        /// device will automatically go into a suspended state.
        /// </summary>
        [DllImport("CoreDll.dll")]
        private static extern void SystemIdleTimerReset();
        /// <summary>
        /// This function resets a system timer that controls whether or not the
        /// device will automatically go into a suspended state.
        /// </summary>
        [DllImport("CoreDll.dll")]
        private static extern void SHIdleTimerReset();
        /// <summary>
        /// This function allows the current power state to be manipulated, i.e. turn the device on
        /// </summary>
        [DllImport("coredll.dll", SetLastError = true)]
        static extern int SetSystemPowerState(string psState, int StateFlags, int Options);
        /// <summary>
        /// This function sets any power notification options
        /// </summary>
        [DllImport("CoreDll.dll")]
        static extern bool PowerPolicyNotify(int dwMessage, int onOrOff);
        #endregion
    }
}

The following code will not disable the power button, but if the device is turned off, it will turn the device back on again within 10 seconds. It will also disable any power saving functionality.

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;

namespace Core.Mobile
{
    /// <summary>
    /// Allows manipulation the power management i.e. system standby
    /// </summary>
    public static class PowerManipulation
    {
        #region Private variables
        private static System.Threading.Timer _timer = null;
        private const int INTERVAL = 10000; //10 seconds
        #endregion
        #region Public methods
        /// <summary>
        /// Prevents the application from suspending/sleeping
        /// </summary>
        public static void DisableSleep()
        {
            if (_timer == null)
            {
                _timer = new System.Threading.Timer(new System.Threading.TimerCallback(Timer_Tick), null, 0, INTERVAL);
            }
            try
            {
                PowerPolicyNotify(PPN_UNATTENDEDMODE, 1);  //Ensure the application still runs in suspend mode
            }
            catch { }
        }
        /// <summary>
        /// Allows suspend/sleep operations
        /// </summary>
        public static void EnableSleep()
        {
            if (_timer != null)
            {
                _timer.Dispose();
                _timer = null;
            }
            try
            {
                PowerPolicyNotify(PPN_UNATTENDEDMODE, 0);
            }
            catch { }
        }
        #endregion
        #region Private methods
        /// <summary>
        /// Internal timer for preventing standby
        /// </summary>
        private static void Timer_Tick(object state)
        {
            try
            {
                SystemIdleTimerReset();
                SetSystemPowerState(null, POWER_STATE_ON, POWER_FORCE);
            }
            catch { }
        }
        #endregion
        #region PInvoke
        private const int PPN_UNATTENDEDMODE = 0x00000003;
        private const int POWER_STATE_ON = 0x00010000;
        private const int POWER_STATE_OFF = 0x00020000;
        private const int POWER_STATE_SUSPEND = 0x00200000;
        private const int POWER_FORCE = 4096;
        private const int POWER_STATE_RESET = 0x00800000;
        /// <summary>
        /// This function resets a system timer that controls whether or not the
        /// device will automatically go into a suspended state.
        /// </summary>
        [DllImport("CoreDll.dll")]
        private static extern void SystemIdleTimerReset();
        /// <summary>
        /// This function resets a system timer that controls whether or not the
        /// device will automatically go into a suspended state.
        /// </summary>
        [DllImport("CoreDll.dll")]
        private static extern void SHIdleTimerReset();
        /// <summary>
        /// This function allows the current power state to be manipulated, i.e. turn the device on
        /// </summary>
        [DllImport("coredll.dll", SetLastError = true)]
        static extern int SetSystemPowerState(string psState, int StateFlags, int Options);
        /// <summary>
        /// This function sets any power notification options
        /// </summary>
        [DllImport("CoreDll.dll")]
        static extern bool PowerPolicyNotify(int dwMessage, int onOrOff);
        #endregion
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文