Esempio n. 1
0
        private IXProcAddInSite _site; // connection to the host


        /// <summary>
        ///     Initializes a new instance of the <see cref="AddInBase" /> class.
        /// </summary>
        /// <param name="site">The site.</param>
        protected AddInBase()
        {
            /*
            Create a window to host the add-in content. The OS allows a window from one process to be parented
            by a window from another. Essentially, native windows let us stitch UI between the two processes.
            (A WPF element tree is contained within an AppDomain and runs all on a single thread.) 
            We have to run a message loop around this window and help with key forwarding and tabbing into&out. 
        
            Keyboard input handling generally works better if MSGs straight off the Win32 message loop are
            "preprocessed", before passing them to DefWinowProc(). This helps with correct handling of
            various accelerators, in particular with some ActiveX controls (like the one WebBrowser wraps),
            and avoids occasional IME translation mishaps. WPF directly exposes its message loop via the
            ComponentDispatcher.ThreadPreprocessMessage event. When HwndSource owns a top-level window,
            it subscribes itself to ThreadPreprocessMessage and does all the correct routing internally
            (largely via its IKeyboardInputSink implementation). But we need a child window for the add-in.
            The trick is to first initialize the HwndSource as a top-level window, while keeping the window
            invisible, and then immediately convert it to a child one. Fortunately, the native window manager
            supports this well.
            */
            string addinName = AppletName.Replace(".", "");
            Logger.Info("Adding addin {0}", addinName);
            var hwsp = new HwndSourceParameters(addinName) {WindowStyle = 0};
            HwndSource hwndSource = _hwndSource = new HwndSource(hwsp);
            Win32.ConvertToChildWindow(hwndSource.Handle);
            if (hwndSource.CompositionTarget != null)
            {
                hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent;
            }
            hwndSource.SizeToContent = SizeToContent.Manual; // The host will do the sizing, via its HwndHost.


            CompositionHelper.ComposeParts(this, GetType());
            if (AddinControl == null)
            {
                Logger.Error("No AddIn control could be found in the package");
            }
            else
            {
                var control = AddinControl as Control;
                if (control != null)
                {
                    Logger.Info("Adding control [{0}]", control.GetType().Name);
                    hwndSource.RootVisual = control;
                    // Enable tabbing out of the add-in. (It is possible to keep Tab cycle within but let only Ctrl+Tab
                    // move the focus out.)
                    KeyboardNavigation.SetTabNavigation(control, KeyboardNavigationMode.Continue);
                    KeyboardNavigation.SetControlTabNavigation(control, KeyboardNavigationMode.Continue);
                }
                ((IKeyboardInputSink) hwndSource).KeyboardInputSite = this;
                // This message loop hook facilitates "bubbling" unhandled keys to the host. We critically rely
                // on HwndSource having already registered its hook so that this one is invoked last.
                ComponentDispatcher.ThreadPreprocessMessage += ThreadPreprocessMessage;
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AppletDependencyViewModel" /> class.
 /// </summary>
 /// <param name="appletName">Name of the applet.</param>
 public AppletDependencyViewModel(AppletName appletName)
 {
     this.Id      = appletName.Id;
     this.Version = appletName.Version;
 }