2

私はラップトップの蓋がいつ開閉するかを検出しようとしていますが、これは本当に簡単なはずです。そのイベントを正しく登録できるようですが、ラップトップのウィンドウを閉じても通知が届きません。

これが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関数に到達しないのですか:[

4

1 に答える 1

2

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 を無条件に呼び出す必要があります

于 2012-06-11T23:36:32.637 に答える