WPF 使用Win32API 让控件置于WebBrowser上方

站长

发表文章数:4342

揉碎HTTP编码过程,从此不乱码

WPF中Webbrowser控件使用HwndHost所以webbrowser会在所有控件的前方。所以webbrowser会覆盖所有同级的控件。

WPF 使用Win32API 让控件置于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事件来不断的设置有效绘图区域。

 

 

我就直接上代码了,

kubectl exec 在kubelet中的处理流程

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:

WPF 使用Win32API 让控件置于WebBrowser上方

 

截图2:

 

WPF 使用Win32API 让控件置于WebBrowser上方

 

并行通信芯片8255A学习总结

未经允许不得转载作者:站长, 转载或复制请以 超链接形式 并注明出处 xss云之家,资源网,娱乐网,网络技术资源分享平台
原文地址:《WPF 使用Win32API 让控件置于WebBrowser上方》 发布于2019-12-08

分享到:
赞(0) 打赏 生成海报

长按图片转发给朋友

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

投稿赚钱
2020年在家赚取零花钱
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册