public ForeignWpfHook <T> HookWpfWindow <T>(IntPtr hWnd, Type tHandler, object oParam = null)
            where T : class
        {
            Contract.Requires(tHandler != null);
            Contract.Requires(typeof(IWpfWindowHook).IsAssignableFrom(tHandler));

            var source = new DcsMarshalledSource <T>();
            var record = WpfHookRegistrationRecord.Create(hWnd, tHandler, typeof(T), oParam);
            var rh     = Hook.RegisterWpfHook(record, source.ComProxy);

            return(new ForeignWpfHook <T>(rh, source));
        }
        public static IWpfWindowHook Hook(WpfHookRegistrationRecord record, IDcsMarshalledObserver observer)
        {
            // get visual
            var hwndSource = HwndSource.FromHwnd(record.HWnd);

            if (hwndSource == null)
            {
                throw new InvalidOperationException($"HwndSource 0x{record.HWnd.ToInt32():x8} not found");
            }
            var rootVisual = hwndSource.RootVisual;

            if (rootVisual == null)
            {
                throw new InvalidOperationException("RootVisual is null");
            }

            // get result source
            var resultType   = record.ResultType;
            var tObserver    = typeof(IObserver <>).MakeGenericType(resultType);
            var tSource      = typeof(DcsMarshalledProxy <>).MakeGenericType(resultType);
            var tSourceCtor  = tSource.GetConstructor(new[] { typeof(IDcsMarshalledObserver) });
            var resultSource = tSourceCtor.Invoke(new object[] { observer });

            // instantiate hook
            var tHandler = record.HookType;
            var tParam   = record.ParameterType;

            if (tParam == null)
            {
                var ctor = tHandler.GetConstructor(new[] { typeof(Visual), tObserver });
                if (ctor != null)
                {
                    return((IWpfWindowHook)ctor.Invoke(new object[] { rootVisual, resultSource }));
                }
            }
            else
            {
                var ctor = tHandler.GetConstructor(new[] { typeof(Visual), tObserver, tParam });
                if (ctor != null)
                {
                    return((IWpfWindowHook)ctor.Invoke(new object[] { rootVisual, resultSource, record.Parameter }));
                }
            }

            throw new NotSupportedException($"No suitable constructor found.  Should be .ctor(System.Windows.Media.Visual, {tObserver.FullName}, {tParam.FullName})");
        }
 public IWpfWindowHook RegisterWpfHook(WpfHookRegistrationRecord hook, IDcsMarshalledObserver observer)
 {
     return(WpfHookManager.Hook(hook, observer));
 }