LoginSignup
11
16

More than 5 years have passed since last update.

WPFアプリケーションでウィンドウプロシージャをフックする

Last updated at Posted at 2015-01-21

WPFアプリケーションでウィンドウプロシージャをフックしたい場合、HwndSource.FromHwndメソッドを呼び出して、HwndSourceオブジェクトを取得し、そのオブジェクトに対してHwndSource.AddHookメソッドを呼び出すことで行います。

MSDN : HwndSource クラス (System.Windows.Interop)

以下のコードは、WPFでは通常取得できない、ALT+F4キーの押下を検知して無効化するサンプルです。
当たり前ですがフックをWindowの生成が終わった後でないとエラーになります。サンプルでは、MainWindowクラスのLoadedイベント内でフックを実行しています。

WindowHookSample.xaml

<Window x:Class="WindowHookSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Name="CloseButton" Content="Close" VerticalAlignment="Center" HorizontalAlignment="Center" Width="100" Height="40" />
    </Grid>
</Window>

WindowHookSample.xaml.cs

using System;
using System.Windows;
using System.Windows.Interop;

namespace WindowHookSample
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private static readonly int WM_SYSKEYDOWN = 0x0104;
        private static readonly int VK_F4 = 0x73;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            Loaded += (o, e) =>
            {
                var source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
                source.AddHook(new HwndSourceHook(WndProc));
            };

            CloseButton.Click += (o, e) => { Close(); };
        }

        /// <summary>
        /// ウィンドウプロシージャ
        /// </summary>
        /// <param name="hwnd">IntPtr : ウィンドウハンドル</param>
        /// <param name="msg">int : メッセージ</param>
        /// <param name="wParam">IntPtr : パラメータ</param>
        /// <param name="lParam">IntPtr : パラメータ</param>
        /// <param name="handled">ref book : ハンドルフラグ</param>
        /// <returns>IntPtr</returns>
        private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            // ALT+F4キーを無効化する
            if ((msg == WM_SYSKEYDOWN) && (wParam.ToInt32() == VK_F4))
                handled = true;
            return IntPtr.Zero;
        }
    }
}

11
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
16