Отключите режим ожидания в Windows Mobile 6

После некоторых исследований и испытаний я нашел решение, приведенное ниже. Ключевым моментом здесь является использование boost::move (или, возможно, std :: move, не знаю, будет ли здесь разница). Поскольку мы используем boost::move, не будет копий объектов IPCString и, следовательно, не нужно умножать на 2. Помните, из-за того, как мы определили IPCString, он будет размещен внутри сегмента разделяемой памяти.

Необходимы дополнительные издержки (возможно, из-за выравнивания или других добавленных накладных расходов, или обоих), но всегда остается некоторое пространство. Поскольку я мог посылать несколько мегабайт, служебные данные 500 байтов довольно малы.

Я использую метод std::string size(), потому что он возвращает размер строки в байтах .

Код выглядит следующим образом:

shared_memory.h:

#pragma once

#include 
#include 
#include 

#include 
#include 

#include 
#include 
#include 

namespace apl_shared_memory
{
  typedef boost::interprocess::allocator CharAllocator;
  typedef boost::interprocess::basic_string, CharAllocator> IPCString;
  typedef boost::interprocess::allocator StringAllocator;
  typedef boost::interprocess::vector ShmVector;

  bool write_to_memory(std::string wsuid, std::string loop_val, std::string should_intercept, std::string post_data) ;


  const std::string shm_prefix = "shm_";
  const std::string mutex_prefix = "mtx_";
}

shared_memory.cpp:

#include "shared_memory.h"

#include "logger.h"



namespace apl_shared_memory

{
    bool write_to_memory(std::string wsuid, std::string loop_val, std::string should_intercept, std::string post_data)
    {
        bool ret_val;
        std::string shm_name = shm_prefix + wsuid;
        std::string mtx_name = mutex_prefix + wsuid;

        boost::interprocess::named_mutex named_mtx{ boost::interprocess::open_or_create, mtx_name.c_str() };

        // Add the size of all the structures we're putting in the shared memory region and add some for the overhead.
        size_t size = (3*sizeof(IPCString) + loop_val.size() + should_intercept.size() + post_data.size() + sizeof(ShmVector)) + 500;

        try
        {
            named_mtx.lock();
            boost::interprocess::shared_memory_object::remove(shm_name.c_str());
            boost::interprocess::managed_shared_memory segment(boost::interprocess::create_only, shm_name.c_str(), size);

            CharAllocator     charallocator(segment.get_segment_manager());
            StringAllocator   stringallocator(segment.get_segment_manager());

            IPCString shm_loop_val(charallocator);
            IPCString shm_should_intercept(charallocator);
            IPCString shm_intercepted_data(charallocator);

            shm_loop_val = loop_val.c_str();
            shm_should_intercept = should_intercept.c_str();
            shm_intercepted_data = post_data.c_str();

            segment.destroy("ShmVector");
            ShmVector *shmVector = segment.construct("ShmVector")(stringallocator);
            shmVector->clear();
            shmVector->reserve(3);

            // push_back will call a copy-constructor. But, if we send a rvalue reference (i.e. if we move it), there will be no copying.
            shmVector->push_back(boost::move(shm_loop_val));
            shmVector->push_back(boost::move(shm_should_intercept));
            shmVector->push_back(boost::move(shm_intercepted_data));

            ret_val = true;
        }

        catch (const std::exception& ex)

        {
            ret_val = false;
            boost::interprocess::shared_memory_object::remove(shm_name.c_str());
        }

        named_mtx.unlock();

        return ret_val;
    }
}

[1117 ] Если кто-то считает, что я сделал что-то не так, пожалуйста, прокомментируйте.

7
задан Niko Gamulin 29 October 2008 в 10:59
поделиться

3 ответа

Если Вы хотите, чтобы Ваша программа не была помещена в сон, в то время как это работает, лучший способ состоит в том, чтобы создать функцию типа KeepAlive, которая называет SystemIdleTimerReset, SHIdleTimerReset и моделирует ключевое касание. Затем необходимо назвать его много, в основном везде.

#include <windows.h>
#include <commctrl.h>

extern "C"
{
    void WINAPI SHIdleTimerReset();
};

void KeepAlive()
{
    static DWORD LastCallTime = 0;
    DWORD TickCount = GetTickCount();
    if ((TickCount - LastCallTime) > 1000 || TickCount < LastCallTime) // watch for wraparound
    {
        SystemIdleTimerReset();
        SHIdleTimerReset();
        keybd_event(VK_LBUTTON, 0, KEYEVENTF_SILENT, 0);
        keybd_event(VK_LBUTTON, 0, KEYEVENTF_KEYUP | KEYEVENTF_SILENT, 0);
        LastCallTime = TickCount;
    }
}

Этот метод только работает, когда пользователь запускает приложение вручную.

Если Ваше приложение запущено уведомлением (т.е. в то время как устройство приостановлено), то необходимо сделать больше, или иначе приложение будет приостановлено после очень короткого промежутка времени, пока пользователь не приводит в действие устройство из приостановленного режима. Для обработки этого, необходимо поместить устройство в необслуживаемый режим питания.

if(!::PowerPolicyNotify (PPN_UNATTENDEDMODE, TRUE))
{
    // handle error
}

// do long running process

if(!::PowerPolicyNotify (PPN_UNATTENDEDMODE, FALSE))
{
    // handle error
}

Во время необслуживаемого использования режима все еще необходимо назвать KeepAlive много, можно использовать отдельный поток, который спит для x миллисекунд и называет поддержание funcation.

Обратите внимание на то, что необслуживаемый режим не выводит его из режима ожидания, это помещает устройство в странное полусонное состояние.

Таким образом, если Вы запускаете необслуживаемый режим, в то время как устройство в приостановленном режиме, он не разбудит экран или что-либо. Весь необслуживаемый режим делает, мешают WM приостановить Ваше приложение. Также другая проблема состоит в том, что это не работает над всеми устройствами, некоторое управление питанием устройств не очень хорошо, и это временно отстранит Вас так или иначе независимо от того, что Вы делаете.

8
ответ дан 6 December 2019 в 14:11
поделиться

Вероятно, путем изменения "состояний Питания системы", как описано здесь (но в c#)

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

1
ответ дан 6 December 2019 в 14:11
поделиться

Измените реестр Диспетчера электропитания, устанавливающий, который влияет на определенное условие сна, Вы хотите (тайм-аут, жидкое тесто, питание переменным током, и т.д.) и SetEvent на именованном системном событии под названием "PowerManager/ReloadActivityTimeouts" сказать ОС перезагружать настройки.

6
ответ дан 6 December 2019 в 14:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: