[c++] Monitoring the Computer's Power Status and Lid status
来源:互联网 发布:儿童绘画软件 绿色 编辑:程序博客网 时间:2024/05/21 15:42
http://msdn.microsoft.com/en-us/library/aa373196.aspx
In Vista you can register for a callback for when the Lid Close Action changes. This is done by calling RegisterPowerSettingNotification (seehttp://msdn2.microsoft.com/en-us/library/aa373196.aspx for details). The GUID for this power setting you're interested in is GUID_LIDCLOSE_ACTION. This is defined in wdm.h in the Platform SDK.
code of C++ builder, below code is to define system message that this app wanna get @Unit1.h.
#ifndef Unit1H#define Unit1H//---------------------------------------------------------------------------#include <System.Classes.hpp>#include <Vcl.Controls.hpp>#include <Vcl.StdCtrls.hpp>#include <Vcl.Forms.hpp>//---------------------------------------------------------------------------class TForm1 : public TForm{__published:// IDE-managed ComponentsTLabel *Label1;private:// User declarationsvoid __fastcall OnPowerChangeHandle(TMessage &Msg);public:// User declarations__fastcall TForm1(TComponent* Owner);BEGIN_MESSAGE_MAPMESSAGE_HANDLER(WM_POWERBROADCAST,TMessage,OnPowerChangeHandle)END_MESSAGE_MAP(TForm)};//---------------------------------------------------------------------------extern PACKAGE TForm1 *Form1;//---------------------------------------------------------------------------#endif
below code is to capture system message to come it out.
//---------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include "Unit1.h"//---------------------------------------------------------------------------#pragma package(smart_init)#pragma resource "*.dfm"TForm1 *Form1;HPOWERNOTIFY m_hPowerSchemeNotify;int i = 0;//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){m_hPowerSchemeNotify = RegisterPowerSettingNotification(Form1->Handle, &GUID_LIDSWITCH_STATE_CHANGE,DEVICE_NOTIFY_WINDOW_HANDLE); if(NULL == m_hPowerSchemeNotify)MessageBox(Form1->Handle, L"RegisterPowerSettingNotification error", L"Error", 48);}void __fastcall TForm1::OnPowerChangeHandle(TMessage &Msg){i++;//Memo1->Lines->Add(Msg.WParam);if (i>=2) {Label1->SetTextBuf(L"Lid closed!");exit(0);}}//---------------------------------------------------------------------------
above code you can built it under C++ builder XE5 & Windows 7...
Contents
- Introduction
- Power Schemes and Power Sources in Vista
- Registering for Power Notifications
- How the Sample App Registers
- Handling Power Notifications
- How the Sample App Handles Notifications
- Conclusion
- References
- Copyright and License
- Revision History
Introduction
In this Vista Goodies article, I'll demonstrate how to monitor the computer's power status using new notifications that were added to Vista. For apps that may be CPU- or graphics-intensive — such as audio encoders, games, and media players — the ability to monitor the power status lets them be intelligent about power consumption when running on laptops. For example, a media player might automatically stop playing when the battery level falls below 15%, so the user will have plenty of time to attach a power cord, and won't have to scramble to close or stop the player to preserve what little power is left.
This article is written for the RTM version of Vista, using Visual Studio 2005,WTL 7.5, andthe Windows SDK. See the introduction in the first Vista Goodies article for more information on where you can download those components.
This article's sample project is a dialog-based app that shows some simple animation. It monitors the computer's power status, updates the display to reflect the current status, and turns off the animation in situations where power conservation is important. For example, here is the dialog showing that the computer is running on AC power:
The "Hello, Bob!" text changes color every second in this case, since the computer isn't in a low-power situation and it's OK to use animation.
Power Schemes and Power Sources in Vista
Vista defines three default power schemes, named Power saver,Balanced, andHigh performance. Each scheme is a pre-set group of settings that control things like hard disk spin-down time, the maximum CPU speed to use, and so on. You can choose a power scheme using the battery tray icon or the Power Options control panel applet. Here is the tray selector with thePower saver scheme selected:
Vista also has some settings that can be different when the computer is using differentpower sources: batteries versus AC power. You can, for example, set the monitor to turn off after 3 minutes on batteries, or 15 minutes on AC power. Vista also monitors thebattery power remaining, which is expressed as a percentage from 1 to 100.
Registering for Power Notifications
Apps can register to be notified of changes to the power scheme, power source, or battery power. The two APIs involved areRegisterPowerSettingNotification()
andUnregisterPowerSettingNotification()
. The prototype forRegisterPowerSettingNotification()
is:
HPOWERNOTIFY RegisterPowerSettingNotification( HANDLE hRecipient, LPCGUID PowerSettingGuid, DWORD Flags);
hRecipient
is a handle to the object that wants to receive notifications; in our case it's our dialog'sHWND
.PowerSettingGuid
is a GUID that indicates which event we want to be notified of.Flags
indicates what type of handlehRecipient
is; in this sample code, the handle will always be anHWND
, so we'll passDEVICE_NOTIFY_WINDOW_HANDLE
forFlags
.
The relevant GUIDs for PowerSettingGuid
are:
GUID_POWERSCHEME_PERSONALITY
: register for changes in the power schemeGUID_ACDC_POWER_SOURCE
: register for changes in the power sourceGUID_BATTERY_PERCENTAGE_REMAINING
: register for changes in the battery power
RegisterPowerSettingNotification()
returns an HPOWERNOTIFY
, orNULL
if an invalid parameter was passed. TheHPOWERNOTIFY
is only used when unregistering; the actual notifications occur through window messages.
How the Sample App Registers
CMainDlg
has three HPOWERNOTIFY
members:
HPOWERNOTIFY m_hPowerSchemeNotify, m_hPowerSourceNotify, m_hBatteryPowerNotify;
OnInitDialog()
calls RegisterPowerSettingNotification()
once for each type of notification. For example, this code registers for notifications about power scheme changes:
m_hPowerSchemeNotify = RegisterPowerSettingNotification ( m_hWnd, &GUID_POWERSCHEME_PERSONALITY, DEVICE_NOTIFY_WINDOW_HANDLE ); if ( NULL == m_hPowerSchemeNotify ) ATLTRACE("Failed to register for notification of power scheme changes!\n");
If RegisterPowerSettingNotification()
fails, it's not a critical error; the app just won't be notified about that particular event.
Handling Power Notifications
When an app needs to be notified of a power change, the system sends it a WM_POWERBROADCAST
message. WM_POWERBROADCAST
is not a new message, but in Vista there is a new event codePBT_POWERSETTINGCHANGE
and an associated data structurePOWERBROADCAST_SETTING
. When aPBT_POWERSETTINGCHANGE
notification is sent, the message'slParam
points to aPOWERBROADCAST_SETTING
struct, which looks like this:
typedef struct { GUID PowerSetting; DWORD DataLength; UCHAR Data[1];} POWERBROADCAST_SETTING;
PowerSetting
is a GUID that indicates what type of event occurred. The possible values for this member are the same GUIDs that are passed toRegisterPowerSettingNotification()
. The rest of the struct is a variable-length chunk of data that contains the details of the event. This data varies among the different events:
PowerSetting
value
Data
description
GUID_POWERSCHEME_PERSONALITY
A GUID that indicates the active power scheme:
GUID_MAX_POWER_SAVINGS
: the Power saver schemeGUID_MIN_POWER_SAVINGS
: the High performance schemeGUID_TYPICAL_POWER_SAVINGS
: the Balanced scheme
GUID_ACDC_POWER_SOURCE
An int
that indicates the power source: 0 for AC power, 1 for batteries, or 2 for short-term batteries (for example, batteries in a UPS).
GUID_BATTERY_PERCENTAGE_REMAINING
An int
that indicates the battery power remaining: 1 to 100.
How the Sample App Handles Notifications
CMainDlg
has a few members that keep track of the current power situation:
enum EPowerScheme { pwrPowerSaver, pwrMaxPerf, pwrBalanced }; EPowerScheme m_eCurrPowerScheme; bool m_bOnBattery; int m_nBatteryPower; bool m_bUseAnimation;
These members are set to reasonable defaults (balanced scheme, not on batteries, animation on) and are changed in theWM_POWERBROADCAST
handler.OnPowerBroadcast()
starts by checking the event type, and returning if it's notPBT_POWERSETTINGCHANGE
:
LRESULT CMainDlg::OnPowerBroadcast ( DWORD dwEvent, DWORD dwData ){ // We only care about Vista power setting notifications. if ( PBT_POWERSETTINGCHANGE != dwEvent ) { SetMsgHandled(false); return 0; }
Next, we get a pointer to the POWERBROADCAST_SETTING
struct sent with the message, and look at itsPowerSetting
member to see what event this notification is for. If it'sGUID_POWERSCHEME_PERSONALITY
, we determine what the new scheme is. If the scheme isn't one of the three predefined GUIDs, then we'll assume the scheme isBalanced.
POWERBROADCAST_SETTING* pps = (POWERBROADCAST_SETTING*) dwData; if ( sizeof(GUID) == pps->DataLength && pps->PowerSetting == GUID_POWERSCHEME_PERSONALITY ) { // This is a power scheme change notification GUID newScheme = *(GUID*)(DWORD_PTR) pps->Data; if ( GUID_MAX_POWER_SAVINGS == newScheme ) { // New scheme: max power savings m_eCurrPowerScheme = pwrPowerSaver; m_cPowerScheme.SetWindowText ( _T("Power saver") ); } else if ( GUID_MIN_POWER_SAVINGS == newScheme ) { // New scheme: min power savings (max perf) m_eCurrPowerScheme = pwrMaxPerf; m_cPowerScheme.SetWindowText ( _T("Max performance") ); } else if ( GUID_TYPICAL_POWER_SAVINGS == newScheme ) { // New scheme: balanced m_eCurrPowerScheme = pwrBalanced; m_cPowerScheme.SetWindowText ( _T("Balanced") ); } else { // Unrecognized scheme, we'll treat this like balanced m_eCurrPowerScheme = pwrBalanced; m_cPowerScheme.SetWindowText ( _T("Balanced") ); } }
For power source notifications, we determine whether the new source is batteries or AC power:
else if ( sizeof(int) == pps->DataLength && pps->PowerSetting == GUID_ACDC_POWER_SOURCE ) { // This is a power source change notification int nPowerSrc = *(int*)(DWORD_PTR) pps->Data; m_bOnBattery = (0 != nPowerSrc); m_cPowerSource.SetWindowText ( m_bOnBattery ? _T("Battery") : _T("AC power") ); }
Finally, for battery power notifications, we save the new percentage:
else if ( sizeof(int) == pps->DataLength && pps->PowerSetting == GUID_BATTERY_PERCENTAGE_REMAINING ) { // This is a battery power notification int nPercentLeft = *(int*)(DWORD_PTR) pps->Data; CString sPercentLeft; sPercentLeft.Format ( _T("%d"), nPercentLeft ); m_cBatteryPower.SetWindowText ( sPercentLeft ); m_nBatteryPower = nPercentLeft; }
Now that we've updated the static text controls to reflect the new power state, we determine whether to turn the animation on or off. The app's logic is this:
- Turn animation on if:
- The current scheme is High performance, or
- The current scheme is Balanced and the computer is not on batteries.
- Turn animation off if:
- The current scheme is Balanced and the computer is on batteries, or
- The current scheme is Power saver, or
- The computer is on batteries and the battery power is 20% or less (no matter what the current scheme is).
bool bUseAnimation = (pwrMaxPerf == m_eCurrPowerScheme) || (pwrBalanced == m_eCurrPowerScheme && !m_bOnBattery); if ( m_bOnBattery && m_cBatteryPower <= 20 ) bUseAnimation = false; // If the animation setting has changed, save the new setting // and redraw the message area. if ( bUseAnimation != m_bUseAnimation ) { m_bUseAnimation = bUseAnimation; m_cMessage.RedrawWindow(); } return TRUE; // allow all power actions}
The m_bAnimation
flag is then used elsewhere to determine how to draw the "Hello, Bob!" message. Here's how the dialog looks with animation on and off, respectively:
Conclusion
For CPU-intensive apps, being aware of the computer's power status can be really nice for your users. For example, a CD burning app could warn the user if the battery is too low, or a download manager could stop downloading in low-power situations to prevent the wireless network card from using up power. Little touches like that can give your apps a nice edge over others when running on Vista.
References
- Channel 9 screencast: How To: Use Vista's Power Management APIs to Be A Good Laptop Citizen
- MSDN topic: The Power-Aware Application
- [c++] Monitoring the Computer's Power Status and Lid status
- Determining and Monitoring the Connectivity Status 根据网络连接状况去省电
- android开发省电之--Determining and Monitoring the Connectivity Status(根据网络连接状况去省电)
- Monitoring battery status with CTelephony
- S 7 - Status bar overlaps the view
- Android navigation bar and the status bar
- status
- status
- Status
- status
- status
- <s:iterator> status属性
- Post a transaction and the appropriate status to the IDoc.
- Post a transaction and the appropriate status to the IDoc.
- Post a transaction and the appropriate status to the IDoc.
- Developer’s Guide to the iOS 7 Status Bar
- THE HANDLER_READ_* STATUS VARIABLES
- IOS7 The Status Bar
- [DS&A]二分法查找
- poj1753(BFS+位存储)
- STL list链表的用法详解
- EasyUI——combobox级联
- 重建控制文件
- [c++] Monitoring the Computer's Power Status and Lid status
- boot read
- 2014找工作----扎实的基础和开阔的视野是企业最看重的因素
- Java中的多线程(二)之多线程同步
- 2014找工作总结-机会往往留给有准备的人
- 地方分类信息站几种推广方式
- GStreamer基础教程07——多线程和Pad的有效性
- cdecl、stdcall、fastcall函数调用约定区别
- VMware中三种网络连接的区别