RegisterPowerSettingsNotification C# pinvoke

本文关键字:pinvoke RegisterPowerSettingsNotification | 更新日期: 2023-09-27 18:36:47

我正在尝试检测笔记本电脑盖何时打开和关闭,应该非常简单。 我似乎可以正确注册该事件,但是当我关闭笔记本电脑窗口时,我没有收到通知。

这是 DLL 导入

(DLL 代码: http://www.pinvoke.net/default.aspx/user32/registerpowersettingnotification.html )(GUID_LIDCLOSE_ACTION: http://social.msdn.microsoft.com/Forums/en-US/tabletandtouch/thread/0bbf90be-9322-47fb-bfa4-016b57211b3a )

[DllImport(@"User32", SetLastError = true, 
  EntryPoint = "RegisterPowerSettingNotification",
  CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr RegisterPowerSettingNotification(
    IntPtr hRecipient,
    ref Guid PowerSettingGuid,
    Int32 Flags);
static Guid GUID_LIDCLOSE_ACTION =
    new Guid(0xBA3E0F4D, 0xB817, 0x4094, 0xA2, 0xD1, 
             0xD5, 0x63, 0x79, 0xE6, 0xA0, 0xF3);
private const int WM_POWERBROADCAST = 0x0218;
private const int DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000;
const int PBT_POWERSETTINGCHANGE = 0x8013; // DPPE
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct POWERBROADCAST_SETTING
{
    public Guid PowerSetting;
    public uint DataLength;
    public byte Data;
}

然后这是我注册GUID_LIDCLOSE_ACTION事件的方式:

private void registerLidClosedNotification()
{
    IntPtr hWnd = this.Handle;
    IntPtr ret = RegisterPowerSettingNotification(hWnd, 
                           ref GUID_LIDCLOSE_ACTION,
                           DEVICE_NOTIFY_WINDOW_HANDLE);
    Debug.WriteLine("Registered: " + ret.ToString());
    Debug.WriteLIne("LastError:" + Marshal.GetLastWin32Error().ToString());
}

这是它的输出:

已注册: 6867560

上一个错误:0

对我来说看起来不错。

然后我应该在哪里收到消息:

private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            Debug.WriteLine("Entered: WndProc");  // we never make it even this far!

那么,如果它已注册,为什么它不进入 WndProc 函数:[

RegisterPowerSettingsNotification C# pinvoke

我认为您使用RegisterPowerSettingNotification所做的是导致Windows包含WM_POWERBROADCAST到WndProc的消息,但您仍然需要实际挂钩WndProc。

看起来您正在使用 WinForms(因为您的示例具有"this.句柄"),在这种情况下,您可以覆盖窗体上受保护的 WndProc 方法。

如果您使用的是 WPF,则可以通过获取根窗口的 HwndSource,然后调用 AddHook 来执行此操作。

您需要阅读有关WinForms (http://msdn.microsoft.com/en-us/library/system.windows.forms.form.wndproc.aspx)中WndProc的文档。 它会被调用很多,所以你只希望只在你关心的消息时运行你的代码,并无条件地调用base。文德普罗克。