tomlev

OverlayWebBrowser to use a browser on transparent WPF window

Aug 19th, 2011
566
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     public class OverlayWebBrowser : Control
  2.     {
  3.         private Overlay _overlay;
  4.  
  5.         public OverlayWebBrowser()
  6.         {
  7.             this.Loaded += new RoutedEventHandler(OverlayWebBrowser_Loaded);
  8.         }
  9.  
  10.         void OverlayWebBrowser_Loaded(object sender, RoutedEventArgs e)
  11.         {
  12.             if (_overlay == null)
  13.                 _overlay = new Overlay(this);
  14.             _overlay.WebBrowser.Source = this.Source;
  15.         }
  16.  
  17.         public Uri Source
  18.         {
  19.             get { return (Uri)GetValue(SourceProperty); }
  20.             set { SetValue(SourceProperty, value); }
  21.         }
  22.  
  23.         // Using a DependencyProperty as the backing store for Source.  This enables animation, styling, binding, etc...
  24.         public static readonly DependencyProperty SourceProperty =
  25.             DependencyProperty.Register(
  26.                 "Source",
  27.                 typeof(Uri),
  28.                 typeof(OverlayWebBrowser),
  29.                 new UIPropertyMetadata(
  30.                     null,
  31.                     SourceChanged));
  32.  
  33.         private static void SourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  34.         {
  35.             OverlayWebBrowser wb = d as OverlayWebBrowser;
  36.             if (wb != null && wb._overlay != null)
  37.             {
  38.                 wb._overlay.WebBrowser.Source = e.NewValue as Uri;
  39.             }
  40.         }
  41.  
  42.         /// <summary>
  43.         /// Displays a WebBrowser control over a given placement target element in a WPF Window.
  44.         /// The owner window can be transparent, but not this one, due mixing DirectX and GDI drawing.
  45.         /// WebBrowserOverlayWF uses WinForms to avoid this limitation.
  46.         /// </summary>
  47.         private class Overlay : Window
  48.         {
  49.             FrameworkElement _placementTarget;
  50.             WebBrowser _wb;
  51.  
  52.             public WebBrowser WebBrowser { get { return _wb; } }
  53.  
  54.             public Overlay(FrameworkElement placementTarget)
  55.             {
  56.                 WindowStyle = WindowStyle.None;
  57.                 ShowInTaskbar = false;
  58.                 ResizeMode = ResizeMode.NoResize;
  59.  
  60.                 _wb = new WebBrowser();
  61.                 Content = _wb;
  62.  
  63.                 _placementTarget = placementTarget;
  64.                 Window owner = Window.GetWindow(placementTarget);
  65.  
  66.                 owner.LocationChanged += delegate { OnSizeLocationChanged(); };
  67.                 _placementTarget.SizeChanged += delegate { OnSizeLocationChanged(); };
  68.  
  69.                 Action showAction = () =>
  70.                                     {
  71.                                         Owner = owner;
  72.                                         OnSizeLocationChanged();
  73.                                         Show();
  74.                                     };
  75.  
  76.                 if (owner.IsVisible)
  77.                 {
  78.                     showAction();
  79.                 }
  80.                 else
  81.                 {
  82.                     DependencyPropertyChangedEventHandler handler = null;
  83.                     handler = delegate
  84.                     {
  85.                         if (owner.IsVisible)
  86.                         {
  87.                             showAction();
  88.                             owner.IsVisibleChanged -= handler;
  89.                         }
  90.                     };
  91.                     owner.IsVisibleChanged += handler;
  92.                 }
  93.             }
  94.  
  95.  
  96.  
  97.             protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
  98.             {
  99.                 base.OnClosing(e);
  100.                 if (!e.Cancel)
  101.                     // Delayed call to avoid crash due to Window bug.
  102.                     Dispatcher.BeginInvoke(new Action(() => Owner.Close()));
  103.             }
  104.  
  105.             void OnSizeLocationChanged()
  106.             {
  107.                 Point offset = _placementTarget.TranslatePoint(new Point(), Owner);
  108.                 Point size = new Point(_placementTarget.ActualWidth, _placementTarget.ActualHeight);
  109.                 HwndSource hwndSource = (HwndSource)PresentationSource.FromVisual(Owner);
  110.                 CompositionTarget ct = hwndSource.CompositionTarget;
  111.                 offset = ct.TransformToDevice.Transform(offset);
  112.                 size = ct.TransformToDevice.Transform(size);
  113.  
  114.                 POINT screenLocation = new POINT(offset);
  115.                 ClientToScreen(hwndSource.Handle, ref screenLocation);
  116.                 POINT screenSize = new POINT(size);
  117.  
  118.                 if (IsLoaded)
  119.                 {
  120.                     MoveWindow(((HwndSource)PresentationSource.FromVisual(this)).Handle, screenLocation.X, screenLocation.Y, screenSize.X, screenSize.Y, true);
  121.                 }
  122.                 else
  123.                 {
  124.                     this.Left = screenLocation.X;
  125.                     this.Top = screenLocation.Y;
  126.                     this.Width = screenSize.X;
  127.                     this.Height = screenSize.Y;
  128.                 }
  129.             }
  130.  
  131.             [StructLayout(LayoutKind.Sequential)]
  132.             public struct POINT
  133.             {
  134.                 public int X;
  135.                 public int Y;
  136.  
  137.                 public POINT(int x, int y)
  138.                 {
  139.                     this.X = x;
  140.                     this.Y = y;
  141.                 }
  142.                 public POINT(Point pt)
  143.                 {
  144.                     X = Convert.ToInt32(pt.X);
  145.                     Y = Convert.ToInt32(pt.Y);
  146.                 }
  147.             };
  148.  
  149.             [DllImport("user32.dll")]
  150.             internal static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);
  151.  
  152.             [DllImport("user32.dll")]
  153.             internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
  154.         }
  155.     }
RAW Paste Data