I am trying to detect when the laptop lid opens and closes, should be real simple. I can register that event properly it seems, but then I don’t get notification when I close my laptop window.
Here’s the DLL Import
(DLL code: 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;
}
And then here is how I am registering the GUID_LIDCLOSE_ACTION event:
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());
}
Here’s the output from that:
Registered: 6867560
LastError:0
Looks good to me.
Then where I’m supposed to recieve the message:
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!
So why isn’t it making it to the WndProc function if it is registered :[
I think what you’ve done with the RegisterPowerSettingNotification is cause Windows to include messages for WM_POWERBROADCAST to your WndProc, but you still need to actually hook the WndProc as well.
It looks like you’re using WinForms (because your sample has “this.Handle”), in which case you can just override the protected WndProc method on your Form.
If you’re using WPF, then you can do this by getting an HwndSource for the root Window and then calling AddHook.
You’ll want to read up on the documentation about the WndProc in WinForms (http://msdn.microsoft.com/en-us/library/system.windows.forms.form.wndproc.aspx). It will get called a lot, so you’ll want to only run your code when it’s the message you care about, and unconditionally call base.WndProc.