浏览器扩展系列————透明浏览器窗口的实现

原文:浏览器扩展系列————透明浏览器窗口的实现

首先先看一下效果图:

    本实现是基于WPF,VS版本2008 SP1。

    先说一下在Winform中的实现方法:很简单通过设置窗体的opacity来实现,或者还可以设置TransparentKey来实现某种颜色透明。但是在WPF中则如何实现呢?

通过设置窗体的opacity,那么得到结果就是webbrowser整体消失了。因为这里面涉及到WPF中“空域”的问题,相关的文章如下:

http://blogs.msdn.com/changov/archive/2009/01/19/webbrowser-control-on-transparent-wpf-window.aspx

    由此看来通过直接设置透明度的方法是不行了,那么回到原来的问题,“将浏览器窗体背景成透明”,其实这里的透明只是一个视觉上的感觉,就是浏览器中网页的背景和整个窗体的背景想融合就可以。看到这里,各位看官可能已经想到了,将浏览器中页面的背景绘制成被浏览器控件所覆盖出的背景就可以了。确实,我的实现也是依照这种思路走的。

    这里主要用到了两个技术:

l Mshtml操作网页中元素,通过给body标签添加行为来实现背景的绘制。

 

Code
[ComVisible(true), Guid("0015EC28-C85F-49a8-9B1A-DC91E6345274"),
    ClassInterface(ClassInterfaceType.AutoDispatch)]
    public class MyGadgetBodyBehavior : IElementBehavior, IHTMLPainter
    {
        public delegate void SizeChangedEventHandler(SizeChangedEventArgs e);
        public event SizeChangedEventHandler onSizeChangedEvent;
        private AppScreenSnapHelper snapHelper;

 

下面是绘制部分的代码

Code
 public void Draw(RECT rcBounds, RECT rcUpdates, int lDrawFlags, IntPtr hdc, IntPtr pvDrawObject)
        {
            Graphics g = Graphics.FromHdc(hdc);
            Bitmap buffer = new Bitmap(width, height);
            Graphics gBuffer = Graphics.FromImage(buffer);

            AppScreenSnapHelper.Image image = snapHelper.GetScreenSnap();
            gBuffer.DrawImage(image.Bitmap, 0, 0);
            image.Dispose();

            string imageSrc = ((IHTMLElement2)body).currentStyle.backgroundImage;
            if (!string.IsNullOrEmpty(imageSrc))
            {
                Match match = Regex.Match(imageSrc, @"url\(""file:///(?<path>.*)""\)");
                if (match.Success)
                {
                    imageSrc = match.Groups["path"].Value;
                    using (Bitmap bitmap = new Bitmap(imageSrc))
                    {
                        object obj = ((IHTMLElement2)body).currentStyle.marginLeft;
                        gBuffer.DrawImage(bitmap, new Rectangle(0, 0, width, height));
                    }
                }
            }
            g.DrawImage(buffer, rcUpdates.left, rcUpdates.top,
                      new Rectangle(rcUpdates.left - rcBounds.left,
                      rcUpdates.top - rcBounds.top, rcUpdates.right - rcUpdates.left,
                      rcUpdates.bottom - rcUpdates.top), GraphicsUnit.Pixel);
            buffer.Dispose();
            gBuffer.Dispose();
            g.Dispose();
            
        }

 

l RenderTargetBitmap类用来给应用程序截图:

 

 

Code
internal Image GetScreenSnap(bool isForceRefresh)
        {
            if (CheckPositionAndSize() && !isForceRefresh)
            {
                return screenImage;
            }

            control.Visibility = Visibility.Hidden;
            RenderTargetBitmap bitmap = new RenderTargetBitmap((int)parentWindow.Width,
               (int)parentWindow.Width, 96, 96, PixelFormats.Pbgra32);
            bitmap.Render(parentWindow);
            BitmapSource bitmapSource = bitmap.CloneCurrentValue();
            Bitmap newBitmap = ConvertSourceImageToBitmap(bitmapSource);
            newBitmap = ClipBitmap(newBitmap, new System.Drawing.Rectangle((int)oldPoint.X, (int)oldPoint.Y,
                ((int)control.Width == 0 ? 1 : (int)control.Width), ((int)control.Height) == 0 ? 1 : (int)control.Height));

            control.Visibility = Visibility.Visible;
            screenImage = new Image(newBitmap, imagePtr);
            return screenImage;
        }

在截图的时候这里使用了一个技巧就是,先将控件隐藏,然后截图,最后恢复控件的显示。 

最后说一下本实现的一些缺陷:

  1.  如果将应用程序的背景设置为透明,则浏览器的背景将呈现白色,因为本实现使用的是应用程序的背景来进行截图,如果应用程序背景被透明,则截图得到的也是一张透明的图片,绘制到页面上后并不能达到透明的效果。如果想在这种情况下实现透明,可以考虑对桌面背景进行截图。
  2. 如果网页过大出现滚动条,那么网页中未呈现的部分并不能透明,因为截图只能作用于已经显示的部分。所以本实现用于显示本地控制好大小的html页面有比较好的效果。

具体项目下载如下:

/Files/chinese-zmm/TransportWebBrowserDemo.rar 

 

时间: 2024-12-31 12:56:07

浏览器扩展系列————透明浏览器窗口的实现的相关文章

浏览器扩展系列————给MSTHML添加内置脚本对象【包括自定义事件】

原文:浏览器扩展系列----给MSTHML添加内置脚本对象[包括自定义事件] 使用场合:          在程序中使用WebBrowser或相关的控件如:axWebBrowser等.打开本地的html文件时,可以在html的脚本中使用自己在.net中定义的类,实现与Internet Explorer server的互操作.此外也可以在充分利用html在设计界面方面高效,简单的同时,也可以实现一些复杂的特性. 实现: Codepublic class ScriptEvent     {     

浏览器扩展系列————在WPF中定制WebBrowser快捷菜单

原文:浏览器扩展系列----在WPF中定制WebBrowser快捷菜单 关于如何定制菜单可以参考codeproject上的这篇文章:http://www.codeproject.com/KB/books/0764549146_8.aspx?fid=13574&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26#xx0xx 本文主要讲述如何在这篇文章中的ShowContextMenu方法中弹出自己的Conte

JavaScript开发Chrome浏览器扩展程序UI的教程_javascript技巧

基本知识 1.插件文件结构 1.1.manifest.json每一个扩展.可安装的WebApp.皮肤,都有一个JSON格式的manifest文件,里面存放重要的插件相关信息. 一个最基本的配置例子: { "name": "browser action demo", "version": "1.0", "permissions": [ "tabs", "http://*/*&qu

JavaScript编写Chrome扩展实现与浏览器的交互及时间通知_javascript技巧

和浏览器的交互 1.书签使用chrome.bookmarks模块来创建.组织和管理书签.也可参看 Override Pages,来创建一个可定制的书签管理器页面. 1.1.manifest.json 中配置 { "name": "My extension", ... "permissions": [ "bookmarks" ], ... } 对象和属性: 签是按照树状结构组织的,每个节点都是一个书签或者一组节点(每个书签夹可包

谷歌Chrome浏览器扩展程序开发小记_javascript技巧

根据公司的规定,每月八小时,弹性工作制.所以大家平时来的不太准时,如果有事,下班也就早些回去了.所以一个月下来工作时间可能不够,但是公司的考勤日历是这样的: 除了请假和法定节假日外,其他样式显示都是一样的,每次都要一个个估算这个月的大概工作时间,十分不方便.后来看到公司有人在用一个Chrome扩展程序,可以计算出一个月的工作时间,但是我觉得还是没有看到我想看的东西,因为除了每个月的累计工作时间外,我还想看到:平均每天工作时长.每一天的工作时长.20点以后的天数(20点以后下班的可以报销晚饭的,哈

创建您自己的浏览器扩展:将您的触角延伸至Chrome

开始之前 对于本文,您需要下载和安装 Google Chrome V19 或更高版本(本文示例是基于 V19 的 ).您也需要一些可以编辑 HTML.CSS 和 JavaScript 的工具.如果您有使用 Chrome 或者 Chrome 扩展的 经验将会很有帮助的.花一点时间浏览 Chrome Web Store.看看提供的扩展并先行试用一番,这将为本文提 供一些相关背景. 为什么构建浏览器扩展? 您想要构建一个浏览器扩展有几个原因,浏览器扩 展的常见应用是在一个浏览器和另一应用程序或服务之间

浏览器扩展如何备份还原

  Chrome扩展的备份还原 谷歌浏览器作为现在非常常见的一款浏览器,在其应用商店里面拥有大量的功能扩展可以选择,所以首先我们就来看看它是如何进行扩展的备份和还原的. 启动运行安装的谷歌浏览器,在地址栏输入"chrome://version/"参数命令后按下回车键,就可以看到当前浏览器的相关信息.在出现的信息窗口中找到"个人资料路径"这个选项,它后面可以看到一个完整的路径信息(图1).接着将这个路径信息复制下来后,粘贴到资源管理器的地址栏中,按下回车键就可以打开存

IE(微软)浏览器扩展开发初探

         最近开发浏览器插件有点上瘾,先开发了一个FF(火狐)浏览器插件,后来又开发了一个谷歌浏览器的插件,还是不觉得不过瘾,这次要尝试开发一个粗糙的IE浏览器插件,最终实现在一键实现订餐,一键取消订餐操作.          凡事知道就好做了,只是这次走了些弯路.网上只要提到IE插件开发的无不提到Com,BHO等等概念,为此我还下载了vs2010,安装platform sdk,并到codeproject下载N个例子进行研究,虽然已经好几年不用vs2010了,也不曾在写com了,还好有点

Firefox(火狐)浏览器扩展开发初探

        最近开发一个FF的扩展,自动完成公司的订餐操作,主要完成的功能很简单:登陆网站,执行一个特定操作,并在ff的状态栏内显示执行的成功或者失败的状态.以前没有写过FF扩展,需要从头学习,在完成这个扩展过程中,有些收获记录下来,一方面自己记录,另一方面也方便有此需求的同学.在整个开发过程中碰到一些问题,也走了一些弯路,希望对其他同学有所帮助.         由于是第一开发FF扩展,没什么经验,所以,第一步先去搜索些关于FF插件开发的文档.先几乎把所有关于FF插件开发的中文文档看个边,