Process the event when windows system is resuming from sleep or hibernation

187 views
Skip to first unread message

krishnaLee

unread,
Aug 31, 2018, 4:17:45 AM8/31/18
to wx-u...@googlegroups.com
Hi, everyone,
my app need process windows system wake events at system wakeup, it is ----> wake on sleep(S3) and  wake on hibernation(S4).

I find wxWidget currently not support this kind of event:
C:\wxWidgets-3.1.1\src\msw\window.cpp,line 4429.

I have no experience about modify the source code and I'm not very familiar with event,
so if I want wxWidgets can process this event,what's the right steps should I do?

thank you,
krishna.

Vadim Zeitlin

unread,
Aug 31, 2018, 1:22:49 PM8/31/18
to wx-u...@googlegroups.com
On Fri, 31 Aug 2018 16:17:41 +0800 (CST) krishnaLee wrote:

k> my app need process windows system wake events at system wakeup, it is
k> ----> wake on sleep(S3) and wake on hibernation(S4).
k> I find the callback here:https://docs.microsoft.com/zh-cn/windows/desktop/Power/pbt-apmresumeautomatic
k>
k>
k> I find wxWidget currently not support this kind of event:
k> C:\wxWidgets-3.1.1\src\msw\window.cpp,line 4429.

So do you mean that on your system (which version of Windows is it using
exactly?) you don't get PBT_APMRESUMESUSPEND but do receive
PBT_APMRESUMEAUTOMATIC?

k> I have no experience about modify the source code and I'm not very
k> familiar with event, so if I want wxWidgets can process this
k> event,what's the right steps should I do?

If it's really just another version of PBT_APMRESUMESUSPEND, you need to
move its case label to be near it. This will probably result in generating
2 wxEVT_POWER_RESUME events in some circumstances, however, as according to
https://docs.microsoft.com/en-US/windows/desktop/Power/pbt-apmresumesuspend
both messages are sent for a user-initiated resume.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

krishnaLee

unread,
Sep 1, 2018, 10:00:10 AM9/1/18
to wx-u...@googlegroups.com, va...@wxwidgets.org
VZ,
my system is win10 x64 RS4, I think this event is compatible to win7/win8(it is better to support it). 
As microsoft said,PBT_APMRESUMESUSPEND is emit by windws if the system wakes due to user activity,
but if the system wake on other signals,this event will not emit.
I need process wake-event, no matter of the system is wake by user or other signals,
process PBT_APMRESUMEAUTOMATIC event seems a better choice.
> If it's really just another version of PBT_APMRESUMESUSPEND, you need to
>move its case label to be near it. This will probably result in generating...
To be clear,I think I should define a new event,I should add a lots of MACRO code to define that...seems difficulty to me currently,
I don't know the steps to define it ,may be I need learn more before I change something to the code.

thank you,
krishna.

Vadim Zeitlin

unread,
Sep 1, 2018, 10:16:44 AM9/1/18
to wx-u...@googlegroups.com
[Please don't cc me the messages sent to the list, thank you]

On Sat, 1 Sep 2018 21:59:44 +0800 (CST) krishnaLee wrote:

k> I need process wake-event, no matter of the system is wake by user or
k> other signals, process PBT_APMRESUMEAUTOMATIC event seems a better
k> choice.

If we can rely on getting PBT_APMRESUMEAUTOMATIC under all supported MSW
versions, then it would seem to be better to send wxEVT_POWER_RESUME when
we get it *instead* of doing it when we get PBT_APMRESUMESUSPEND, as we do
now. Can you confirm that this is really the case, i.e. that you get
PBT_APMRESUMEAUTOMATIC message whenever the system is resumed for any
reason?

k> > If it's really just another version of PBT_APMRESUMESUSPEND, you need to
k> >move its case label to be near it. This will probably result in generating...
k> To be clear,I think I should define a new event,

I don't think we need a new event, it wouldn't be very useful to have it
as it would be very MSW-specific and I have trouble understanding when
would you want to handle wxEVT_POWER_RESUME and when would you need this
new wxEVT_POWER_RESUME_AUTOMATIC. If it's really useful to distinguish
between them, we should add a method to wxPowerEvent, e.g. IsDueToUser() or
something like that, that would return a boolean value allow to determine
the reason for resuming.

k> I should add a lots of MACRO code to define that...seems difficulty to
k> me currently, I don't know the steps to define it ,may be I need learn
k> more before I change something to the code.

You just need to use 2 macros, wxDECLARE_EVENT and wxDEFINE_EVENT as shown
at http://docs.wxwidgets.org/trunk/group__group__funcmacro__events.html#ga767b12d37f7370bc5f6b3d62340f3ef8
(there is something wrong with the formatting there, but the example shows
all you need to know).

krishnaLee

unread,
Sep 3, 2018, 1:28:10 AM9/3/18
to wx-u...@googlegroups.com
VZ,
I had learned and  tried wrote an win32 power-test-app.exe(the source code I will add to this mail end) to test that,
I had used another tool pwrtest.exe here:

In windows 10 x64 RS4:
1,remote lan wake this machine, the power-test-app.exe will get 3 files: power_suspend.txt + power_resume_suspend.txt + power_resume_automatic.txt
2,using pwrtest.exe to do one-time sleep and auto-awake the machine, I also get the three files.
In windows 7 x86:
the  power-test-app.exe will breakdown at machine awake,so I can't make sure I had got all the logs,I just get two log: power_suspend.txt + power_resume_suspend.txt.

it seems the win10 result is not the same as microsoft said.
it seems using PBT_APMRESUMESUSPEND is no problem at auto-awake.

//source of power-test-app-------------------------start--------------------------------------------
#include <windows.h>
#include<string>

void WINAPI SaveToFile(const wchar_t* fileName)
{
HANDLE hFile = CreateFile(fileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SYSTEMTIME sys;
char buffer[256];
ZeroMemory(buffer, sizeof(buffer));
GetLocalTime(&sys);
sprintf_s(buffer, sizeof(buffer), "curren_time_is [%4d-%02d-%02d][%02d:%02d:%02d].[%03d]", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);

if (INVALID_HANDLE_VALUE != hFile)
{
WriteFile(hFile, buffer, sizeof(buffer), NULL, NULL);
FlushFileBuffers(hFile);
CloseHandle(hFile);
}
}

void WINAPI PowerEvent(WPARAM wParam)
{
switch (wParam)
{
case PBT_APMPOWERSTATUSCHANGE:
SaveToFile(L"power_status_change.txt");
break;
case PBT_APMRESUMEAUTOMATIC:
SaveToFile(L"power_resume_automatic.txt");
break;
case PBT_APMRESUMESUSPEND:
SaveToFile(L"power_resume_suspend.txt");
break;
case PBT_APMSUSPEND:
SaveToFile(L"power_suspend.txt");
break;
case PBT_POWERSETTINGCHANGE:
SaveToFile(L"power_setting_change.txt");
break;
default:
break;
}
}


const wchar_t myClassName[] = L"MyClassName";

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case  WM_POWERBROADCAST:
PowerEvent(wParam);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;

//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = myClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

// Step 2: Creating the Window
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
myClassName,
L"Power Event Test 1.0",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 200,
NULL, NULL, hInstance, NULL);

if (hwnd == NULL)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

// Step 3: The Message Loop
while (GetMessage(&Msg, NULL, 0, 0) > 0)    //block function,get messages from the message loop,return-0 means WM_QUIT,return negative means error happened.
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}

//source of power-test-app-------------------------end--------------------------------------------

thank you,
by krishna.


Vadim Zeitlin

unread,
Sep 3, 2018, 5:46:25 PM9/3/18
to wx-u...@googlegroups.com
On Mon, 3 Sep 2018 13:28:05 +0800 (CST) krishnaLee wrote:

k> I had learned and tried wrote an win32 power-test-app.exe(the source
k> code I will add to this mail end) to test that,

Have you tried running the power sample as well? Does it show the expected
"System resumed" message for you and if it doesn't, in which case does it
happen?

k> In windows 10 x64 RS4:
k> 1,remote lan wake this machine, the power-test-app.exe will get 3 files:
k> power_suspend.txt + power_resume_suspend.txt +
k> power_resume_automatic.txt
k> 2,using pwrtest.exe to do one-time sleep and auto-awake the machine, I
k> also get the three files.
k> In windows 7 x86:
k> the power-test-app.exe will breakdown at machine awake,so I can't make
k> sure I had got all the logs,I just get two log: power_suspend.txt +
k> power_resume_suspend.txt.
k>
k> it seems the win10 result is not the same as microsoft said.
k> it seems using PBT_APMRESUMESUSPEND is no problem at auto-awake.

So do I understand this correctly as meaning that the existing code in
wxMSW already works correctly and we should be getting wxEVT_POWER_RESUME
on resume already or am I missing something?

krishnaLee

unread,
Sep 3, 2018, 10:42:24 PM9/3/18
to wx-u...@googlegroups.com
VZ,
wxWidget's code works  ok,only one of the event needs to be processed as the two event both happened when machine-awake,and if anyone try process both of the events,it may be confusing,
nothing need to change.

thank you,
krishna.
Reply all
Reply to author
Forward
0 new messages