zoukankan      html  css  js  c++  java
  • WPF 使用Win32API 让控件置于WebBrowser上方

    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:

  • 相关阅读:
    IronRuby:元编程特性【method_missing】的使用
    DNN(DotNetNuke) 3.0感官刺激零距x接触!!! :)
    (MS SQL)如何实现相关文章功能(多关键字匹配)改进版
    谁有微软认证,如MCSD,MCDBA,MCXX等等,马上告诉我
    开源代码2004/12/25 codeproject
    开源代码2004/1220-PDF格式/文件相关
    强烈推荐一个超酷的跨平台、支持多数据库的数据库管理工具
    (MS SQL)如何实现相关文章功能(多关键字匹配)
    DotNetNuke(DNN)从入门到进阶(1)-怎样写自己的模块
    推荐开源代码2004/12/17
  • 原文地址:https://www.cnblogs.com/T-ARF/p/12004980.html
Copyright © 2011-2022 走看看