AllowsTransparency和WebBrowser兼容性问题解决方案

    AllowsTransparency和System.Windows.Controls.WebBrowser兼容性问题,能看这篇文章,所以原因也不用多说;最根本的就是因为MS对win32底层的WebBrowser简易封装成System.Windows.Controls.WebBrowser

    解决方案也很简单,但是网上的文章大部分都代码缺少和代码陈旧(各种转;各种代码错误,这种错误不是指版本等原因,而是一些简单标点符号;我不相信他是手扣代码,而不是把vs写好的代码复制到文章里,这种不负责任的人的文章还需要看么?),于是我就整理成了一个类方便调用

    现在都讲究的快速开发,如果你的文章不能对别人起到实质性的帮助 就算不上一篇好文章,如果你的文章不但没起到帮助反而是浪费别人的开发时间 那么就没必要把垃圾发出来;

 

    因本文章较为简单,故加入了微量吐槽,为防止身体不适者恶心干呕,忽视以上内容,下来文归正转

1、xaml:

<Window x:Class="AllowsTransparency和webbrowser兼容问题.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:AllowsTransparency和webbrowser兼容问题"
        Title="MainWindow" Height="350" Width="525" AllowsTransparency="True" WindowStyle="None">
    <Grid x:Name="grid"></Grid>
</Window>

2、cs:

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            FormsWebBrowser web = new FormsWebBrowser(this.grid); //或者直接this
            web.WebBrowser.Navigate(new Uri("http://www.baidu.com"));
        }
    }

3、FormWebBrowser类调用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Diagnostics;
using System.ComponentModel;
using System.Windows.Interop;
using System.Windows.Threading;
using System.Windows.Media;
using System.Runtime.InteropServices;

namespace Tools
{
    public class FormsWebBrowser
    {
        Window _owner;
        FrameworkElement _placementTarget;
        Form _form;
        WebBrowser _wb = new WebBrowser();

        public WebBrowser WebBrowser { get { return _wb; } }

        public FormsWebBrowser(FrameworkElement placementTarget) //, Window mainWindow)
        {
            _placementTarget = placementTarget;
            Window owner = Window.GetWindow(placementTarget); 
            //Window owner = mainWindow; //page中传入window
            Debug.Assert(owner != null);
            _owner = owner;

            _form = new Form();
            _form.Opacity = owner.Opacity;
            _form.ShowInTaskbar = false;
            _form.FormBorderStyle = FormBorderStyle.None;
            _wb.Dock = DockStyle.Fill;
            _form.Controls.Add(_wb);

            owner.LocationChanged += delegate { OnSizeLocationChanged(); };
            _placementTarget.SizeChanged += delegate { OnSizeLocationChanged(); };

            if (owner.IsVisible)
                InitialShow();
            else
                owner.SourceInitialized += delegate
                {
                    InitialShow();
                };

            DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(UIElement.OpacityProperty, typeof(Window));
            dpd.AddValueChanged(owner, delegate { _form.Opacity = _owner.Opacity; });

            _form.FormClosing += delegate { _owner.Close(); };
        }

        void InitialShow()
        {
            NativeWindow owner = new NativeWindow();
            owner.AssignHandle(((HwndSource)HwndSource.FromVisual(_owner)).Handle);
            _form.Show(owner);
            owner.ReleaseHandle();
        }

        DispatcherOperation _repositionCallback;

        void OnSizeLocationChanged()
        {
            if (_repositionCallback == null)
                _repositionCallback = _owner.Dispatcher.BeginInvoke(new Action(Reposition), DispatcherPriority.Input);
        }

        void Reposition()
        {
            _repositionCallback = null;

            Point offset = _placementTarget.TranslatePoint(new Point(), _owner);
            Point size = new Point(_placementTarget.ActualWidth, _placementTarget.ActualHeight);
            HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(_owner);
            CompositionTarget ct = hwndSource.CompositionTarget;
            offset = ct.TransformToDevice.Transform(offset);
            size = ct.TransformToDevice.Transform(size);

            Win32.POINT screenLocation = new Win32.POINT(offset);
            Win32.ClientToScreen(hwndSource.Handle, ref screenLocation);
            Win32.POINT screenSize = new Win32.POINT(size);

            Win32.MoveWindow(_form.Handle, screenLocation.X, screenLocation.Y, screenSize.X, screenSize.Y, true);
        }
    }

    static class Win32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;

            public POINT(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }
            public POINT(Point pt)
            {
                X = Convert.ToInt32(pt.X);
                Y = Convert.ToInt32(pt.Y);
            }
        };

        [DllImport("user32.dll")]
        internal static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);

        [DllImport("user32.dll")]
        internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

    }
}

  

   源码:https://files.cnblogs.com/NotAnEmpty/wpf_WebBorwser.rar

posted @ 2014-11-11 10:38  rick'li  阅读(1430)  评论(0编辑  收藏  举报