RegisterPowerSettingsNotification C#pinvoke

我试图检测笔记本电脑盖打开和closures,应该是真正简单。 我可以正确地注册这个事件,但是当我closures我的笔记本电脑窗口时我没有收到通知。

这里是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

LastError: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函数:[

Solutions Collecting From Web of "RegisterPowerSettingsNotification C#pinvoke"

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

它看起来像你使用的WinForms(因为你的示例有“this.Handle”),在这种情况下,你可以重写您的窗体上的受保护的WndProc方法。

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

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