Correctly handle Windows Power events

Source: Internet
Author: User
Tags message queue

Brief introduction
Application preparation steps for system suspend and restore

Once upon a time, when you were about to submit or post some important data through your app, you suddenly had some urgent need to deal with and it was a long delay. When you are done returning to your computer, you find that your computer has automatically entered a suspended state or is completely shut down. You may lose some or all of your important data, just because the app failed to "save" the data before it stopped executing. There are a few people who believe they have similar experiences. Now, application developers have devised a special application to help us avoid this. The app can send messages and events to notify users through the operating system before the system hangs or sleeps.

This article describes the status of the system ready to suspend in the Windows * environment, as well as the suspend operation and resume operation from the suspended state, through the case. We will explain the purpose of sending messages and events, provide some information about usage and timing, and give some useful suggestions to help you avoid potential data loss. In addition, we will delve into what types of applications should be used to send and receive such messages and events. We will focus on messaging on the Windows xp* Professional operating system, and the code examples provided will be used to explain how to prepare and recover from a pending state. In addition, this article puts forward some suggestions to help you avoid hanging or bypassing the current constraints. The discussion in this article is intended for readers who have a certain understanding of Windows messaging.

defines the message that
wm_powerbroadcast– broadcasts to the app through the WindowProc () function, which tells the power management event to be already/running.
pbt_apmquerysuspend– events that require permission to suspend
pbt_apmquerysuspendfailed– notify the event that the pending request failed
pbt_apmresumeautomatic– Event received automatically from resume when resuming from suspended state
pbt_apmresumecritical– notification of events recovered from unknown or unstable state
pbt_apmresumesuspend– notification of events resumed from suspended state
Pbt_ apmsuspend– events received before the system hangs

Drivers
Application development is a highly skilled work. With the advent of the mobile environment, this situation will become increasingly prominent. First, we need to determine which apps may lose data due to system hangs and which apps will not. Applications that need to be considered include any applications that are affected by changes in the operating system environment, such as network connections, USB connections, or firewire* connections, apps that cannot be interrupted before any operations are completed, and any applications that display information on the display without user interaction.

What happens if the system goes into a suspended state when the app is using a file on the network? At this point, even if a recovery operation is performed, the previous network connection is no longer available, unless the app is pre-"aware" that you will be in trouble. What do you do if a CD/DVD disc is burned over a Firewire or USB connection? If so, unfortunately, your platter will only be used as a coaster. If you are presenting to an important customer, pausing for explanations or questions, the system hangs and shows the embarrassing situation of suspension. At this point, you have to spend valuable time restarting your computer, opening the demo and finding your previous location to continue the presentation. This shows how important it is to prevent application hangs.

Many examples attest to the idea that it is necessary to develop an application that relies on system messages to guard against hangs. Applications that respond to power messages are more flexible and reliable when the system is unable to recover from the suspended state and needs to be restarted. By creating backup files, you can more easily retrieve data that is stored before it is suspended, making it easier to implement a pending recovery.

System hangs
The system suspend process is primarily used to save energy on mobile devices or to turn off the hard drive before moving a device. This process is typically associated with user settings that are used to turn off devices that are not in use for a specific period of time. If the power settings are appropriate, you can also call the system suspend process by turning off the laptop top cover. To demonstrate the message patterns associated with system hangs, we connect to the test system remotely and invoke Spy + + on the test system to check and capture Wm_powerbroadcast messages and events broadcast by the test system. Typically, the message pattern sent and received by the app is as follows:

S wm_powerbroadcast (Long) dwpowerevent:pbt_apmquerysuspend
R wm_powerbroadcast fsucceeded:true [lresult:00000001] Swm_powerbroadcast (long) dwpowerevent:pbt_apmsuspend
R wm_powerbroadcast fsucceeded:true [lresult:00000001]

(Note: a command line starting with the letter "S" indicates that the message needs to be sent through the SendMessage () function.) The command line starting with the letter "R" represents the message return value from the app. The above pattern indicates that the system sends an WM_POWERBROADCAST message containing the Pbt_apmquerysuspend event to the app and requests an application license to suspend the system if allowed. This message and event is sent to all applications, threads, and processes that are currently running within the system. In all events, this event usually causes the system to hang first. Once the message is received, the app should be ready to close before returning. These preparations vary depending on the application, but should include tasks such as storing the database tables on the hard disk, saving the files to the hard disk, freeing up memory or sharing resources, disconnecting the network, or shutting down any other task that helps ensure that the application exits safely. In general, the system can extract up to 20 seconds of messages from the app's message queue. Therefore, any necessary shutdown should begin as soon as the event is received. In this case, the application return value is True (true), which means that the suspend execution can continue.

The message sent before the system hangs is a wm_powerbroadcast with the Pbt_spmsuspend event. The return value, True (TRUE), is returned by the app.

Reject Pending Request
If the app does not allow or "does not want" the system to perform a hang, it notifies the system that a request has been rejected by the application in some way. To do this, the app returns the Broadcast_query_deny value when the Pbt_apmquerysuspend event is received. The system then "knows" that an application or process cannot or "does not allow" the pending operation. In the case of application rejection pending, the message pattern is as follows:

S wm_powerbroadcast (long) dwpowerevent:pbt_apmquerysuspend
R wm_powerbroadcast fsucceeded:true [LResult : 424d5144]
S wm_powerbroadcast (long) dwpowerevent:pbt_apmquerysuspendfailed
Note that in this case, the application in LResult returns a value of 424D5144, which is the value of Broadcast_query_deny. The system then issues a pbt_apmquerysuspendfailed event that notifies all apps that the pending request failed and continues to perform normal operations within the app.

In addition, we can use the SetThreadExecutionState () function to prevent the system from suspending. This function is used to send a notification to the system that it is being used and to prevent the system from sending Wm_powerbroadcast messages and events that are used to execute the hang (as our tests indicate). However, the system continues to emit events to handle changes in battery and power state, so these events can still be monitored. There are 3 tags associated with this function: es_system_required--indicates that some operations are in progress, es_display_required--indicates that some operations need to be displayed, and es_continuous--notifies the system to remain in the same state before changes occur. We recommend that applications such as fax servers, answering machines, backup agents, and network management should use es_system_required, while multimedia applications such as video players and demo applications should use es_display_required. If es_continuous is not used, the idle timer is completely reset, so you need to call the function periodically to reset the timer. Note, however, that the function does not prevent system hangs due to shutting down the laptop top cover. The only way to fundamentally prevent the system from suspending is to reject the Pbt_apmquerysuspend event mentioned above. In addition, the function does not always prevent the screensaver from running. There are also many other ways to block hangs, such as defining a good one time value beforehand, and then using the SystemParametersInfo () function to query and reset the screensaver timeout value.

Recovering from a pending state
for the application, leaving the pending state and continuing to perform is as important as the system behavior of entering the pending state, so the application developer should be particularly aware of receiving messages during process execution. Recovering memory, disk status, and database tables These cases represent only a subset of the elements in your app, and the app will need to be refreshed and reconfigured when it leaves the suspended state. If these elements are not in a normal state, even normal application behavior can result in data corruption and loss. During the suspend process, the WM_POWERBROADCAST message is used to send an alert to the app that the recovery operation is/has completed. In general, the following messages and events will be emitted by the operating system:

S Wm_powerbroadcast (long) dwpowerevent:0012
R wm_powerbroadcast fsucceeded:true [lresult:00000001]
S WM_ Powerbroadcast (Long) dwpowerevent:pbt_apmresumesuspend
R wm_powerbroadcast fsucceeded:true [lResult:00000001]
The first event is 0x12, corresponding to pbt_apmresumeautomatic. This event is used only to issue notifications to your app that are performing an automatic recovery operation. Typically, this event does not require a response, but there is one exception--which is described later in this article, which should be noted in the design of the application. The following event is to be emitted as pbt_apmresumesuspend. This event is emitted only if pbt_apmsuspend is sent during the execution of a pending process. This indicates that the system has completed the recovery operation safely and the application can continue to execute. If an app frees memory, database tables, or other important information when it hangs, developers must re-initialize or assign the running elements within those apps. As mentioned above, it is important to keep your application in a normal state of operation.

Other recovery events that can be received include: Pbt_apmquerysuspendfailed and pbt_apmresumecritical. As already mentioned, if some other process has rejected a pending request from the system, the system will receive a pbt_apmquerysuspendfailed event that indicates that the app can continue to perform normal operations. Pbt_apmresumecritical is emitted when some or all of the applications do not receive pbt_apmsuspend events, such as when the battery is exhausted. Messages are important because, if no messages are received, previously available resources or data can become unusable. For an exceptionally vulnerable network connection, the application should save any files or data located on the network in advance. In summary, any application should be restored to its optimal state when this event is received, guaranteeing optimum performance.

Dormancy
When the system shuts down, the hibernation feature completely retains the system state so that the system can revert to the pre-hibernation state when the power is re-connected. However, there is a very interesting anomaly in message mode when the system is put into hibernation by the suspended state and then back to the previous state. The following example describes the exception state in this pattern:

About to hang up
S wm_powerbroadcast (Long) dwpowerevent:pbt_apmquerysuspend
R wm_powerbroadcast fsucceeded:true [lresult:00000001]
S wm_powerbroadcast (Long) dwpowerevent:pbt_apmsuspend
R wm_powerbroadcast fsucceeded:true [lresult:00000001]
Going to sleep
S wm_powerbroadcast (Long) dwpowerevent:0012
S wm_powerbroadcast (Long) dwpowerevent:pbt_apmquerysuspend
R wm_powerbroadcast fsucceeded:true [lresult:00000001]
S wm_powerbroadcast (Long) dwpowerevent:pbt_apmsuspend
R wm_powerbroadcast fsucceeded:true [lresult:00000001]
S wm_powerbroadcast (Long) dwpowerevent:pbt_apmsuspend
R wm_powerbroadcast fsucceeded:true [lresult:00000001]
Press the Start button
S wm_powerbroadcast (Long) dwpowerevent:0012
R wm_powerbroadcast fsucceeded:true [lresult:00000001]
S wm_powerbroadcast (Long) dwpowerevent:0012
When the system goes into hibernation, the sequence of events changes, and when we start the system again, we receive the pbt_apmautomaticresue,0x12 event. In comparison with the normal order we find that the Pbt_apmresumesuspend event is missing, indicating that the system has performed a recovery operation. After the test we concluded that in some cases, only one 0x12 code was received, and in some cases two were received. No matter how it is tested, we do not receive the Pbt_apmresumesuspend event when resuming from hibernation, even if the documentation indicates that the event will be issued in case we did not receive it. Perhaps we need to reconcile between the Pbt_apmresumesuspend and Pbt_apmautomaticresume events to make sure that the app stays healthy after the suspend operation.

Code instance
To facilitate a thorough understanding of how to handle messages and events related to suspend and resume operations, we give the following examples:
LRESULT CALLBACK WndProc (HWND hwnd, UINT message,


WPARAM WPARAM, LPARAM LPARAM)
{
int Wmid, wmevent;
Paintstruct PS;
HDC hdc;

Switch (message)
{
.
.
.
Case WM_POWERBROADCAST:

Switch (wParam)
{
Case pbt_apmquerysuspend:
Preptosuspend (true);
return (true);
Case Pbt_ apmquerysuspendfailed:
Reinitvars ();
Break,
Case pbt_apmresumesuspend:
Reinitvars ();
break;
Case Pbt_apmsuspend:
Break,
Case pbt_apmresumecritical:
reinitvarscritical (),
Break,
Case Pbt_ Apmbatterylow:
MessageBox (hWnd, ' Battery is Critical ', ' low Battery ', MB_OK);
break;
Case Pbt_ Apmpowerstatuschange:
Advisepowerchange ();
break;
Case pbt_apmoemevent:
Break,
Case pbt_apmresumeautomatic:
break;

}
.
.
.
Default:
return DefWindowProc (hWnd, message, WParam, LParam);
}
return 0;
}



This method can handle every event that is associated with a wm_powerbroadcast message, but is definitely not the only method. Note that when you receive the Pbt_apmquerysuspend event and return True (TRUE), the call that applies to preptosuspend (true) also occurs. If the app needs to reject the pending request, simply return a broadcast_query_deny instead of calling the function as in the instance. It is also important to note that each non-critical recovery-related message calls the Reinitvars () function, while the critical recovery event invokes the reinitvarscritical () function. The difference in function content can be reflected in a more powerful initialization process for critical recovery (as mentioned earlier).

The above example also lists 3 events that are not mentioned in this article. Pbt_apmoemevent is not a unified event, and OEMs try to capture their own events based on their own judgment. In most cases, this event does not require a response. If the system has marked this state, the Pbt_apmbatterylow will be received. Other appropriate actions are taken when necessary, not just to inform the user that the battery is low. Pbt_powerstatuschange belongs to the event, which is handled by the application. This event identifies changes in the power state of the machine and reports the battery charge information and important data needed for other applications. There are many details, so let the readers find out for themselves.

Conclusion
Every time you look at the new features of your app and determine whether it's relevant to a particular product, we'll ask "Why do we write apps like this?" "This old question. In addressing this issue, as more and more people choose to buy laptops as the main system in the home and office environment, how to avoid data loss due to hangs becomes an increasingly pressing issue in front of the application developers. The ability to suspend or revert to a running state freely, reduce errors and problems to a historic low, and experience app hangs like art-this is the ideal application in the user's mind. The need to rely on files or content on the network, to ensure long displays and runs without user interaction, requires the ability to capture the information that the user enters for storage or later invocation, the need to store large amounts of data, and so on-only applications that meet these criteria can reliably handle such messages and events. Software architects and strategists can design more reliable and better applications to help people cope with the challenges of mobile work and lifestyle.

Today, to meet the needs of users of mobile computing, software needs must be a major transformation. The operating system can use WM_POWERBROADCAST messages to indicate the changes that will occur during the system's operation. As we all know, hang function can save battery energy consumption, and will definitely bring more far-reaching influence to the application in the future. And the application design should pay more attention to the energy consumption problem, and try to prolong the battery use time. By properly arranging messages and events, we will eventually achieve the goal of reducing the energy consumption of the application.

http://blog.csdn.net/harbinzju/article/details/5844791

Correctly handle Windows Power events

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.