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); } } }