WPF 中 webbrowser 控件使用 HwndHost 所以 webbrowser 会在所有控件的前方. 所以 webbrowser 会覆盖所有同级的控件.
现在通过使用 Win32API 可以避免这个情况.
最主要的就是这几个 Win32API:
- [DllImport("user32.dll")]
- public static extern bool SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool redraw);
- [DllImport("gdi32.dll")]
- public static extern IntPtr CreateRectRgn(int Left, int Top, int RectRightBottom_X, int RectRightBottom_Y);
- [DllImport("gdi32.dll")]
- public static extern int CombineRgn(IntPtr hrgnDst, IntPtr hrgnSrc1, IntPtr hrgnSrc2, int iMode);
- [DllImport("GDI32.dll")]
- public static extern bool DeleteObject(IntPtr objectHandle);
适当说一下:
setwindowrgn 就是设置有效绘图区域.
createrectrgn 是创建矩形
combinergn 这个就是融合两个矩形, 可以并集, 交集以及 Src1 中不包括 Src2 的部分, 最终结果会在 hrgnDst 中.
总的来说就是利用 webbrowser 的父级控件的 sizechanged 事件来不断的设置有效绘图区域.
我就直接上代码了,
Win32API 类
- [DllImport("user32.dll")]
- public static extern bool SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool redraw);
- /// <summary>
- /// 创建一个矩形, 本来四个参数均为 x1 y1 x2 y2 意思为左上角 X1,Y1 坐标, 右下角 X2,Y2 坐标, 但是为了方便 WPF 使用我则是改了
- /// left 意味矩形和左边的距离
- /// top 意味着矩形和顶边距离
- /// rectrightbottom_x 意味着矩形右下角的 X 坐标
- /// rectrightbottom_y 意味着矩形右下角的 Y 坐标
- /// </summary>
- /// <param name="Left"></param>
- /// <param name="Top"></param>
- /// <param name="RectRightBottom_X"></param>
- /// <param name="RectRightBottom_Y"></param>
- /// <returns></returns>
- [DllImport("gdi32.dll")]
- public static extern IntPtr CreateRectRgn(int Left, int Top, int RectRightBottom_X, int RectRightBottom_Y);
- [DllImport("GDI32.dll")]
- public static extern bool DeleteObject(IntPtr objectHandle);
- [DllImport("gdi32.dll")]
- public static extern int CombineRgn(IntPtr hrgnDst, IntPtr hrgnSrc1, IntPtr hrgnSrc2, int iMode);
- // 合并选项:
- //RGN_AND = 1;
- //RGN_OR = 2;
- //RGN_XOR = 3;
- //RGN_DIFF = 4;
- //RGN_COPY = 5; {复制第一个区域}
附加属性类:
- class ATCH
- {
- public static readonly DependencyProperty PanelProperty = DependencyProperty.RegisterAttached("Panel", typeof(Panel), typeof(ATCH), new PropertyMetadata(null));
- public static void SetPanel(DependencyObject d, Panel value) => d.SetValue(PanelProperty, value);
- public static Panel GetPanel(DependencyObject d) => (Panel)d.GetValue(PanelProperty);
- public static readonly DependencyProperty NameProperty = DependencyProperty.RegisterAttached("Name", typeof(FrameworkElement), typeof(ATCH), new PropertyMetadata(null, new PropertyChangedCallback(OnNamePropertyChanged)));
- public static void SetName(DependencyObject d, FrameworkElement value) => d.SetValue(NameProperty, value);
- public static FrameworkElement GetName(DependencyObject d) => (FrameworkElement)d.GetValue(NameProperty);
- private static void OnNamePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var b = d.GetValue(PanelProperty);
- if (b is null||! (b is Panel)||e.NewValue is null)
- return;
- var panel = b as Panel;
- var Web = d as WebBrowser;
- var ui = e.NewValue as FrameworkElement;
- SetRect(panel, Web, ui);
- panel.SizeChanged += (sender, args) =>
- {
- SetRect(panel, Web, ui);
- };
- }
- private static IntPtr C1;
- private static void SetRect(Panel panel, WebBrowser Web, FrameworkElement ui)
- {
- IntPtr handle = Web.Handle;
- Win32API.DeleteObject(C1);
- Win32API.SetWindowRgn(handle, IntPtr.Zero, true);
- Rect PanelRect = new Rect(new Size(panel.ActualWidth, panel.ActualHeight));
- C1 = Win32API.CreateRectRgn((int)0, (int)0, (int)PanelRect.BottomRight.X, (int)PanelRect.BottomRight.Y);
- Rect UIRect = new Rect(new Size(ui.ActualWidth, ui.ActualHeight));
- var D1 = (int)ui.TransformToAncestor(panel).Transform(new Point(0, 0)).X;
- var D2 = (int)ui.TransformToAncestor(panel).Transform(new Point(0, 0)).Y;
- var D3 = (int)(D1 + UIRect.Width);
- var D4 = (int)(D2 + UIRect.Height);
- var C2 = Win32API.CreateRectRgn(D1, D2, D3, D4);
- Win32API.CombineRgn(C1, C1, C2, 4);
- Win32API.SetWindowRgn(handle, C1, true);
- }
- }
xaml 代码
- <Grid>
- <WebBrowser Source="http://www.baidu.com" local:ATCH.Panel="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=Grid}}" local:ATCH.Name="{Binding ElementName=btn}"/>
- <Button x:Name="btn" Height="50" Width="100" Content="覆盖测试" />
- </Grid>
截图 1:
截图 2:
来源: https://www.cnblogs.com/T-ARF/p/12004980.html