How To: Use Vista's Power Management APIs to Be A Good Laptop Citizen
- Posted: Jun 26, 2006 at 2:24 PM
- 21,274 Views
- 1 Comment
Download
How do I download the videos?
- To download, right click the file type you would like and pick “Save target as…” or “Save link as…”
Why should I download videos from Channel9?
- It's an easy way to save the videos you like locally.
- You can save the videos in order to watch them offline.
- If all you want is to hear the audio, you can download the MP3!
Which version should I choose?
- If you want to view the video on your PC, Xbox or Media Center, download the High Quality WMV file (this is the highest quality version we have available).
- If you'd like a lower bitrate version, to reduce the download time or cost, then choose the Medium Quality WMV file.
- If you have a Zune, WP7, iPhone, iPad, or iPod device, choose the low or medium MP4 file.
- If you just want to hear the audio of the video, choose the MP3 file.
Right click “Save as…”
- Mid Quality WMV (Lo-band, Mobile)
Is your application the reason why my laptop only gets two hours of battery life? That's not a question you want to hear from your paying customers. Windows Vista provides an
enhanced power management API
and control panel which lets the user express their desired power usage profile, and lets applications query and respond to changes in power state.
In the second of our Vista How To series,
Ian Griffiths shows how to listen to power change events in a WPF app, and respond to low power or power saver modes by reducing the amount of animation in the app (thus saving GPU and CPU cycles)
Comments Closed
Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation,
please create a new thread in our Forums,
or
Contact Us and let us know.
Follow the Discussion
Here are some relevant sections of the code from Ian's sample app. I've added the interop definitions to PInvoke.net for easy reference.
void Window1_Loaded(object sender, RoutedEventArgs e)
{
source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
source.AddHook(new HwndSourceHook(WndProc));
RegisterForPowerNotifications(source.Handle);
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
UnregisterForPowerNotifications();
}
private IntPtr hBattCapacity;
private IntPtr hMonitorOn;
private IntPtr hPowerScheme;
private IntPtr hPowerSrc;
private void RegisterForPowerNotifications(IntPtr hwnd)
{
hPowerSrc = RegisterPowerSettingNotification(hwnd,
ref GUID_ACDC_POWER_SOURCE,
DEVICE_NOTIFY_WINDOW_HANDLE);
hBattCapacity = RegisterPowerSettingNotification(hwnd,
ref GUID_BATTERY_PERCENTAGE_REMAINING,
DEVICE_NOTIFY_WINDOW_HANDLE);
hMonitorOn = RegisterPowerSettingNotification(hwnd,
ref GUID_MONITOR_POWER_ON,
DEVICE_NOTIFY_WINDOW_HANDLE);
hPowerScheme = RegisterPowerSettingNotification(hwnd,
ref GUID_POWERSCHEME_PERSONALITY,
DEVICE_NOTIFY_WINDOW_HANDLE);
}
private void UnregisterForPowerNotifications()
{
UnregisterPowerSettingNotification(hBattCapacity);
UnregisterPowerSettingNotification(hMonitorOn);
UnregisterPowerSettingNotification(hPowerScheme);
UnregisterPowerSettingNotification(hPowerSrc);
}
static bool onBattery;
enum PowerPersonality { Savings, Performance, Mixed };
static PowerPersonality personality;
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_POWERBROADCAST && wParam.ToInt32() == PBT_POWERSETTINGCHANGE)
{
// Extract data from message
POWERBROADCAST_SETTING ps =
(POWERBROADCAST_SETTING)Marshal.PtrToStructure(
lParam, typeof(POWERBROADCAST_SETTING));
IntPtr pData = (IntPtr)(lParam.ToInt32() + Marshal.SizeOf(ps));
// Examine notification
if (ps.PowerSetting == GUID_POWERSCHEME_PERSONALITY &&
ps.DataLength == Marshal.SizeOf(typeof(Guid)))
{
// New power scheme selected.
Guid newPersonality =
(Guid)Marshal.PtrToStructure(pData, typeof(Guid));
if (newPersonality == GUID_MAX_POWER_SAVINGS)
{
personality = PowerPersonality.Savings;
}
else if (newPersonality == GUID_MIN_POWER_SAVINGS)
{
personality = PowerPersonality.Performance;
}
else if (newPersonality == GUID_TYPICAL_POWER_SAVINGS)
{
personality = PowerPersonality.Mixed;
}
else
{
Debug.WriteLine("switched to unknown Power savings");
personality = PowerPersonality.Mixed;
}
}
else if (ps.PowerSetting == GUID_ACDC_POWER_SOURCE &&
ps.DataLength == Marshal.SizeOf(typeof(Int32)))
{
Int32 iData = (Int32)Marshal.PtrToStructure(pData, typeof(Int32));
Debug.WriteLine("ACDC: " + iData);
onBattery = iData != 0;
}
// Select the best resources for the current
// power state.
if (personality == PowerPersonality.Performance
|| (personality == PowerPersonality.Mixed && !onBattery))
{
Application.Current.Resources = fullPowerResources;
}
else
{
Application.Current.Resources = lowPowerResources;
}
}
return IntPtr.Zero;
}
Remove this comment
Remove this thread
close