0

I have a method as follows:

public static void RegisterForMessage(System.Windows.Window window, Action action)
        {
            HwndSource hWndSource;
            WindowInteropHelper wih = new WindowInteropHelper(window);
            hWndSource = HwndSource.FromHwnd(wih.Handle);
            hWndSource.AddHook(hwndSourceHook);
        }

i want to take action from user and pass into hwndSourceHook method:

private static IntPtr hwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            // Action must be run here
            return IntPtr.Zero;
        }

but i dont know how to do this

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
hadi khodabandeh
  • 585
  • 2
  • 7
  • 20

1 Answers1

2

hwndSourceHook has a specific signature that you can't change, which means you can't add a parameter to its signature. You can only pass an event handler to hWndSource.AddHook that matches the signature

public delegate IntPtr HwndSourceHook(
    IntPtr hwnd, 
    int msg, 
    IntPtr wParam, 
    IntPtr lParam, 
    ref bool handled);

One option is to use an anonymous function instead of declaring a separate method for your handler, like this:

public static void RegisterForMessage(System.Windows.Window window, Action action)
{
    HwndSource hWndSource;
    WindowInteropHelper wih = new WindowInteropHelper(window);
    hWndSource = HwndSource.FromHwnd(wih.Handle);
    HwndSourceHook eventHandler = (IntPtr hwnd, 
                                   int msg, 
                                   IntPtr param, 
                                   IntPtr lParam, 
                                   ref bool handled) =>
    {
        action.Invoke();
        return IntPtr.Zero;
    };
    hWndSource.AddHook(eventHandler);
}

Instead of putting the event handler in a separately declared method we're declaring it inline within RegisterToMethod. That allows us to include the parameter passed to the outer method.

This is called a closure.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62