using System;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
public static partial class User32
{
/// The following are the power management events:
// https://docs.microsoft.com/en-us/windows/win32/power/power-management-events
[PInvokeData("winuser.h", MSDNShortId = "2315e17f-f0c1-409c-b1c0-b3735c25c4c1")]
public enum PowerBroadcastType
{
///
///
/// [PBT_APMQUERYSUSPEND is available for use in the operating systems specified in the Requirements section. Support for this
/// event was removed in Windows Vista. Use SetThreadExecutionState instead.]
///
///
/// Requests permission to suspend the computer. An application that grants permission should carry out preparations for the
/// suspension before returning.
///
///
/// A window receives this event through the WM_POWERBROADCAST message. The wParam and lParam parameters are set as
/// described following.
///
///
///
///
/// lParam: The action flags. If bit 0 is 1, the application can prompt the user for directions on how to prepare for the
/// suspension; otherwise, the application must prepare without user interaction. All other bit values are reserved.
///
/// Return: TRUE to grant the request to suspend. To deny the request, return BROADCAST_QUERY_DENY.
///
/// An application should process this event as quickly as possible. The application can prompt the user for directions on how
/// to prepare for suspension only if bit 0 in the Flags parameter is set. However, if this message is issued because the user
/// is closing the laptop lid, it will not be possible to prompt the user. Applications should respect that the user expects a
/// certain behavior when they close the laptop lid or press the power button and allow the transition to succeed.
///
///
/// The system allows approximately 20 seconds for an application to remove the WM_POWERBROADCAST message that is sending
/// the PBT_APMQUERYSUSPEND event from the application's message queue. If an application does not remove the message from its
/// queue in less than 20 seconds, the system will assume that the application is in a non-responsive state, and that the
/// application agrees to the sleep request. Applications that do not process their message queues may have their operations
/// interrupted. After it removes the message from the message queue, an application can take as much time as needed to perform
/// any required operations before entering the sleep state. Any operations that could take longer then 20 seconds should be
/// performed at this time, since the system allows only 20 seconds for operations to complete during PBT_APMSUSPEND processing.
///
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-apmquerysuspend
PBT_APMQUERYSUSPEND = 0x0000,
///
/// The PBT_APMQUERYSUSPEND message is sent to request permission to suspend the computer. An application that grants permission
/// should carry out preparations for the suspension before returning. Return TRUE to grant the request to suspend. To deny the
/// request, return BROADCAST_QUERY_DENY.
///
PBT_APMQUERYSTANDBY = 0x0001,
///
///
/// [PBT_APMQUERYSUSPENDFAILED is available for use in the operating systems specified in the Requirements section. Support for
/// this event was removed in Windows Vista. Use SetThreadExecutionState instead.]
///
///
/// Notifies applications that permission to suspend the computer was denied. This event is broadcast if any application or
/// driver returned BROADCAST_QUERY_DENY to a previous PBT_APMQUERYSUSPEND event.
///
///
/// A window receives this event through the WM_POWERBROADCAST message. The wParam and lParam parameters are set as
/// described following.
///
///
///
/// lParam: Reserved; must be zero.
/// No return value.
/// Applications typically respond to this event by resuming normal operation.
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-apmquerysuspendfailed
PBT_APMQUERYSUSPENDFAILED = 0x0002,
///
/// The PBT_APMQUERYSUSPENDFAILED message is sent to notify the application that suspension was denied by some other
/// application. However, this message is only sent when we receive PBT_APMQUERY* before.
///
PBT_APMQUERYSTANDBYFAILED = 0x0003,
///
///
/// Notifies applications that the computer is about to enter a suspended state. This event is typically broadcast when all
/// applications and installable drivers have returned TRUE to a previous PBT_APMQUERYSUSPEND event.
///
///
/// A window receives this event through the WM_POWERBROADCAST message. The wParam and lParam parameters are set as
/// described following.
///
///
///
/// lParam: Reserved; must be zero.
/// No return value.
/// An application should process this event by completing all tasks necessary to save data.
///
/// The system allows approximately two seconds for an application to handle this notification. If an application is still
/// performing operations after its time allotment has expired, the system may interrupt the application.
///
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-apmsuspend
PBT_APMSUSPEND = 0x0004,
/// Undocumented.
PBT_APMSTANDBY = 0x0005,
///
///
/// [PBT_APMRESUMECRITICAL is available for use in the operating systems specified in the Requirements section. Support for this
/// event was removed in Windows Vista. Use PBT_APMRESUMEAUTOMATIC instead.]
///
///
/// Notifies applications that the system has resumed operation. This event can indicate that some or all applications did not
/// receive a PBT_APMSUSPEND event. For example, this event can be broadcast after a critical suspension caused by a failing battery.
///
///
/// A window receives this event through the WM_POWERBROADCAST message. The wParam and lParam parameters are set as
/// described following.
///
///
///
/// lParam: Reserved; must be zero.
/// No return value.
///
/// Because a critical suspension occurs without prior notification, resources and data previously available may not be present
/// when the application receives this event. The application should attempt to restore its state to the best of its ability.
/// While in a critical suspension, the system maintains the state of the DRAM and local hard disks, but may not maintain net
/// connections. An application may need to take action with respect to files that were open on the network before critical suspension.
///
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-apmresumecritical
PBT_APMRESUMECRITICAL = 0x0006,
///
/// Notifies applications that the system has resumed operation after being suspended.
///
/// A window receives this event through the WM_POWERBROADCAST message. The wParam and lParam parameters are set as
/// described following.
///
///
///
/// lParam: Reserved; must be zero.
/// No return value.
///
/// An application can receive this event only if it received the PBT_APMSUSPEND event before the computer was suspended.
/// Otherwise, the application will receive a PBT_APMRESUMECRITICAL event.
///
///
/// If the system wakes due to user activity (such as pressing the power button) or if the system detects user interaction at
/// the physical console (such as mouse or keyboard input) after waking unattended, the system first broadcasts the
/// PBT_APMRESUMEAUTOMATIC event, then it broadcasts the PBT_APMRESUMESUSPEND event. In addition, the system turns on the
/// display. Your application should reopen files that it closed when the system entered sleep and prepare for user input.
///
///
/// If the system wakes due to an external wake signal (remote wake), the system broadcasts only the PBT_APMRESUMEAUTOMATIC
/// event. The PBT_APMRESUMESUSPEND event is not sent.
///
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-apmresumesuspend
PBT_APMRESUMESUSPEND = 0x0007,
///
/// The PBT_APMRESUMESTANDBY event is broadcast as a notification that the system has resumed operation after being standby.
///
PBT_APMRESUMESTANDBY = 0x0008,
///
///
/// [PBT_APMBATTERYLOW is available for use in the operating systems specified in the Requirements section. Support for this
/// event was removed in Windows Vista. Use PBT_APMPOWERSTATUSCHANGE instead.]
///
/// Notifies applications that the battery power is low.
///
/// A window receives this event through the WM_POWERBROADCAST message. The wParam and lParam parameters are set as
/// described following.
///
///
///
/// lParam: Reserved, must be zero.
/// No return value.
///
/// This event is broadcast when a system's APM BIOS signals an APM battery low notification. Because some APM BIOS
/// implementations do not provide notifications when batteries are low, this event may never be broadcast on some computers.
///
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-apmbatterylow
PBT_APMBATTERYLOW = 0x0009,
///
///
/// Notifies applications of a change in the power status of the computer, such as a switch from battery power to A/C. The
/// system also broadcasts this event when remaining battery power slips below the threshold specified by the user or if the
/// battery power changes by a specified percentage.
///
///
/// A window receives this event through the WM_POWERBROADCAST message. The wParam and lParam parameters are set as
/// described following.
///
///
///
/// lParam: Reserved; must be zero.
/// No return value.
///
/// An application should process this event by calling the GetSystemPowerStatus function to retrieve the current power
/// status of the computer. In particular, the application should check the ACLineStatus, BatteryFlag,
/// BatteryLifeTime, and BatteryLifePercent members of the SYSTEM_POWER_STATUS structure for any changes.
/// This event can occur when battery life drops to less than 5 minutes, or when the percentage of battery life drops below 10
/// percent, or if the battery life changes by 3 percent.
///
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-apmpowerstatuschange
PBT_APMPOWERSTATUSCHANGE = 0x000A,
///
///
/// [PBT_APMOEMEVENT is available for use in the operating systems specified in the Requirements section. Support for this event
/// was removed in Windows Vista.]
///
/// Notifies applications that the APM BIOS has signaled an APM OEM event.
///
/// A window receives this event through the WM_POWERBROADCAST message. The wParam and lParam parameters are set as
/// described following.
///
///
///
///
/// lParam: The OEM-defined event code that was signaled by the system's APM BIOS. OEM event codes are in the range 0200h - 02FFh.
///
/// No return value.
///
/// Because not all APM BIOS implementations provide OEM event notifications, this event may never be broadcast on some computers.
///
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-apmoemevent
PBT_APMOEMEVENT = 0x000B,
///
///
/// Notifies applications that the system is resuming from sleep or hibernation. This event is delivered every time the system
/// resumes and does not indicate whether a user is present.
///
///
/// A window receives this event through the WM_POWERBROADCAST message. The wParam and lParam parameters are set as
/// described following.
///
///
///
/// lParam: Reserved; must be zero.
/// No return value.
///
/// If the system detects any user activity after broadcasting PBT_APMRESUMEAUTOMATIC, it will broadcast a PBT_APMRESUMESUSPEND
/// event to let applications know they can resume full interaction with the user.
///
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-apmresumeautomatic
PBT_APMRESUMEAUTOMATIC = 0x0012,
///
/// Power setting change event sent with a WM_POWERBROADCAST window message or in a HandlerEx notification
/// callback for services.
///
///
/// lParam: Pointer to a POWERBROADCAST_SETTING structure.
/// No return value.
///
// https://docs.microsoft.com/en-us/windows/win32/power/pbt-powersettingchange
PBT_POWERSETTINGCHANGE = 0x8013,
}
/// Registers the application to receive power setting notifications for the specific power setting event.
///
/// Handle indicating where the power setting notifications are to be sent. For interactive applications, the Flags parameter should
/// be zero, and the hRecipient parameter should be a window handle. For services, the Flags parameter should be one, and the
/// hRecipient parameter should be a SERVICE_STATUS_HANDLE as returned from RegisterServiceCtrlHandlerEx.
///
///
/// The GUID of the power setting for which notifications are to be sent. For more information see Registering for Power Events.
///
///
///
///
/// Value
/// Meaning
///
/// -
/// DEVICE_NOTIFY_WINDOW_HANDLE 0
/// Notifications are sent using WM_POWERBROADCAST messages with a wParam parameter of PBT_POWERSETTINGCHANGE.
///
/// -
/// DEVICE_NOTIFY_SERVICE_HANDLE 1
///
/// Notifications are sent to the HandlerEx callback function with a dwControl parameter of SERVICE_CONTROL_POWEREVENT and a
/// dwEventType of PBT_POWERSETTINGCHANGE.
///
///
///
///
///
/// Returns a notification handle for unregistering for power notifications. If the function fails, the return value is NULL. To get
/// extended error information, call GetLastError.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registerpowersettingnotification HPOWERNOTIFY
// RegisterPowerSettingNotification( IN HANDLE hRecipient, IN LPCGUID PowerSettingGuid, IN DWORD Flags );
[DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "e072222e-da66-4b36-a38f-f4b618eaa391")]
public static extern SafeHPOWERSETTINGNOTIFY RegisterPowerSettingNotification([In] HANDLE hRecipient, in Guid PowerSettingGuid, [In] DEVICE_NOTIFY Flags);
///
/// Registers to receive notification when the system is suspended or resumed. Similar to PowerRegisterSuspendResumeNotification,
/// but operates in user mode and can take a window handle.
///
///
///
/// This parameter contains parameters for subscribing to a power notification or a window handle representing the subscribing process.
///
///
/// If Flags is DEVICE_NOTIFY_CALLBACK, hRecipient is interpreted as a pointer to a DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS
/// structure. In this case, the callback function is DeviceNotifyCallbackRoutine. When the Callback function executes, the
/// Type parameter is set indicating the type of event that occurred. Possible values include PBT_APMSUSPEND,
/// PBT_APMRESUMESUSPEND, and PBT_APMRESUMEAUTOMATIC - see Power Management Events for more info. The Setting
/// parameter is not used with suspend/resume notifications.
///
/// If Flags is DEVICE_NOTIFY_WINDOW_HANDLE, hRecipient is a handle to the window to deliver events to.
///
/// This parameter can be DEVICE_NOTIFY_WINDOW_HANDLE or DEVICE_NOTIFY_CALLBACK.
///
/// A handle to the registration. Use this handle to unregister for notifications.
/// If the function fails, the return value is NULL. To get extended error information call GetLastError.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registersuspendresumenotification HPOWERNOTIFY
// RegisterSuspendResumeNotification( IN HANDLE hRecipient, IN DWORD Flags );
[DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "6cd42d32-07e9-4cbd-83f9-6146b1cb54db")]
public static extern SafeHSUSPRESUMENOTIFY RegisterSuspendResumeNotification([In] HANDLE hRecipient, [In] DEVICE_NOTIFY Flags);
/// Unregisters the power setting notification.
/// The handle returned from the RegisterPowerSettingNotification function.
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unregisterpowersettingnotification BOOL
// UnregisterPowerSettingNotification( IN HPOWERNOTIFY Handle );
[DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "de1509f5-cf4c-448e-bb3b-08da6be53bfa")]
[return: MarshalAs(UnmanagedType.Bool)] public static extern bool UnregisterPowerSettingNotification([In] HANDLE Handle);
///
/// Cancels a registration to receive notification when the system is suspended or resumed. Similar to
/// PowerUnregisterSuspendResumeNotification but operates in user mode.
///
/// A handle to a registration obtained by calling the RegisterSuspendResumeNotification function.
///
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unregistersuspendresumenotification BOOL
// UnregisterSuspendResumeNotification( IN HPOWERNOTIFY Handle );
[DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("winuser.h", MSDNShortId = "d9307452-9670-4e9c-9df8-6a3b41d0bd2e")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UnregisterSuspendResumeNotification([In] HANDLE Handle);
///
/// Sent with a power setting event and contains data about the specific change. For more information, see Registering for Power
/// Events and Power Setting GUIDs.
///
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-powerbroadcast_setting typedef struct { GUID PowerSetting;
// DWORD DataLength; UCHAR Data[1]; } POWERBROADCAST_SETTING, *PPOWERBROADCAST_SETTING;
[PInvokeData("winuser.h", MSDNShortId = "13fa8220-bad2-4bb6-b652-38fc11a31215")]
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(DataLength))]
[StructLayout(LayoutKind.Sequential)]
public struct POWERBROADCAST_SETTING
{
///
/// Indicates the power setting for which this notification is being delivered. For more info, see Power Setting GUIDs.
///
public Guid PowerSetting;
/// The size in bytes of the data in the Data member.
public uint DataLength;
/// The new value of the power setting. The type and possible values for this member depend on PowerSettng.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public byte[] Data;
}
/// Provides a for HPOWERNOTIFY that is disposed using .
public class SafeHPOWERSETTINGNOTIFY : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHPOWERSETTINGNOTIFY(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHPOWERSETTINGNOTIFY() : base() { }
///
protected override bool InternalReleaseHandle() => UnregisterPowerSettingNotification(handle);
}
/// Provides a for HPOWERNOTIFY that is disposed using .
public class SafeHSUSPRESUMENOTIFY : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHSUSPRESUMENOTIFY(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHSUSPRESUMENOTIFY() : base() { }
///
protected override bool InternalReleaseHandle() => UnregisterSuspendResumeNotification(handle);
}
}
}