Windows Mobile - Отключить кнопку питания

Кто-нибудь успешно перехватил кнопку питания / ожидания на устройстве WM5 таким образом, чтобы ваш код не позволял пользователям "выключать" даже экран?

У меня есть приложение, которое использует экран в альбомной ориентации, и я хотел бы заблокировать нажатие клавиши питания, чтобы (а) пользователи могли держать устройство обеими руками и случайно не выключать экран и (в качестве бонуса - б) использовать его как кнопку пользовательского интерфейса.

Может, у кого-то есть хак низкого уровня? Я использую WM5, поставляемый с iPaq RX1950 (а).

Помните, что невозможного не бывает - особенно с WM5. Если я тем временем отвечу на него сам, то обновлю вопрос.


Обновлять!

Я обнаружил три уловки, которые работают в обратном порядке для удобства использования:

  1. Патчите keybddr.dll (на этом устройстве), повторно закиньте его в ПЗУ любым удобным для вас способом. На этом устройстве с заводским ПЗУ - он работает, но я не хотел отключать его навсегда.

  2. Синхронизируйте с очередью сообщений управления питанием и включайте устройство, когда оно сообщает о выходе из строя.

  3. Измените «Состояния питания» в реестре, чтобы они все (большинство из них) были «включены». Таким образом, я могу использовать RAPI для отключения кнопки питания и заставить программное обеспечение на устройстве «сбрасывать» реестр при наступлении события x, y и z.


person Community    schedule 29.04.2009    source источник
comment
Однако это сильно нарушает принцип наименьшего удивления. Не надо.   -  person dkretz    schedule 29.04.2009
comment
Я также полностью согласен с le dorfier в том, что использовать кнопку питания в качестве дополнительной кнопки - ОЧЕНЬ плохая идея. Вы перегружаете самую важную кнопку на всем устройстве, и, что еще хуже, вы отключаете ее единственную функцию.   -  person DevinB    schedule 29.04.2009
comment
Во-первых, это плохая, плохая идея, и обычно это провода напрямую для прерывания нуля. Если драйвер питания не имеет для этого крючка (я не знаю ни одного устройства WinMo), его невозможно перехватить.   -  person ctacke    schedule 30.04.2009
comment
Клиент этого хочет, значит, клиент это получает. ;-)   -  person Billy Back Bedroom    schedule 01.05.2009
comment
Я должен согласиться с Беном - это клиентское устройство (или мое устройство) - это всего лишь кнопка - не самое святое из святых мест ... Хотя с учетом сказанного - делать это в общедоступном приложении не следует. быть сделано.   -  person Joe Ruder    schedule 02.05.2009


Ответы (2)


Реализация кнопки питания зависит от производителя оборудования, поэтому решение на одном устройстве вряд ли будет работать на другом устройстве. Из-за большого разнообразия реализаций в устройствах Windows Mobile вы обнаружите, что это верно для многих низкоуровневых функций.

Альтернатива предполагает сочетание вещей

  • Запустите ваше приложение в автоматическом режиме
  • Мониторинг событий изменения мощности
  • когда устройство переходит в автоматический режим запрашивает полный режим

Полное обсуждение управления питанием выходит за рамки того, что я могу здесь обсудить. Подробнее об этом можно прочитать здесь: http://www.codeproject.com/KB/mobile/WiMoPower1.aspx

Также есть образец, который показывает, как можно зарегистрироваться для событий питания здесь: http://www.codeproject.com/KB/mobile/WiMoQueue.aspx

person Community    schedule 29.04.2009
comment
Спасибо, Джоэл. Вторая ссылка позволила одним способом отключить ее! - person Billy Back Bedroom; 01.05.2009

Следующий код не отключит кнопку питания, но если устройство выключено, он снова включит его в течение 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
    }
}
person Community    schedule 05.02.2013