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

简介: 原文:浏览器扩展系列————透明浏览器窗口的实现首先先看一下效果图:     本实现是基于WPF,VS版本2008 SP1。     先说一下在Winform中的实现方法:很简单通过设置窗体的opacity来实现,或者还可以设置TransparentKey来实现某种颜色透明。
原文: 浏览器扩展系列————透明浏览器窗口的实现

首先先看一下效果图:

    本实现是基于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

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

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

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

 

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

 

下面是绘制部分的代码

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
 public void Draw(RECT rcBounds, RECT rcUpdates, int lDrawFlags, IntPtr hdc, IntPtr pvDrawObject)
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif        
{
            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, 
00);
            image.Dispose();

            
string imageSrc = ((IHTMLElement2)body).currentStyle.backgroundImage;
            
if (!string.IsNullOrEmpty(imageSrc))
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
{
                Match match 
= Regex.Match(imageSrc, @"url\(""file:///(?<path>.*)""\)");
                
if (match.Success)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                
{
                    imageSrc 
= match.Groups["path"].Value;
                    
using (Bitmap bitmap = new Bitmap(imageSrc))
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                    
{
                        
object obj = ((IHTMLElement2)body).currentStyle.marginLeft;
                        gBuffer.DrawImage(bitmap, 
new Rectangle(00, 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();
            
        }

 

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

 

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
internal Image GetScreenSnap(bool isForceRefresh)
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif        
{
            
if (CheckPositionAndSize() && !isForceRefresh)
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            
{
                
return screenImage;
            }


            control.Visibility 
= Visibility.Hidden;
            RenderTargetBitmap bitmap 
= new RenderTargetBitmap((int)parentWindow.Width,
               (
int)parentWindow.Width, 9696, 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 

 

目录
相关文章
|
1月前
|
JavaScript 前端开发 UED
JS:如何获取浏览器窗口尺寸?
JS:如何获取浏览器窗口尺寸?
45 1
|
6月前
谷歌浏览器常用的扩展
谷歌浏览器常用的扩展
48 0
|
9月前
|
Web App开发 人工智能 安全
LemurBrowser狐猴浏览器:支持插件扩展的移动端浏览器
狐猴浏览器是浏览器新标签页插件Wetab提供的支持在移动端安装插件,内置免费AI工具助手的新一代移动端浏览器,像Infinity/Wetab 一样简洁优雅好用的Tab浏览器。
200 0
LemurBrowser狐猴浏览器:支持插件扩展的移动端浏览器
|
25天前
|
Java 测试技术 定位技术
《手把手教你》系列技巧篇(二十三)-java+ selenium自动化测试-webdriver处理浏览器多窗口切换下卷(详细教程)
【4月更文挑战第15天】本文介绍了如何使用Selenium进行浏览器窗口切换以操作不同页面元素。首先,获取浏览器窗口句柄有两种方法:获取所有窗口句柄的集合和获取当前窗口句柄。然后,通过`switchTo().window()`方法切换到目标窗口句柄。在项目实战部分,给出了一个示例,展示了在百度首页、新闻页面和地图页面之间切换并输入文字的操作。最后,文章还探讨了在某些情况下可能出现的问题,并提供了一个简单的本地HTML页面示例来演示窗口切换的正确操作。
46 0
|
2月前
|
Java 测试技术 Python
Selenium帮助你轻松实现浏览器多窗口操作
Selenium帮助你轻松实现浏览器多窗口操作
94 0
|
3月前
|
存储 安全 前端开发
浏览器跨窗口通信:原理与实践
浏览器跨窗口通信:原理与实践
54 0
|
4月前
|
Web App开发 JSON 前端开发
6款开发必备的Chrome谷歌浏览器扩展(部分火狐、edge浏览器商店也可以用)
6款开发必备的Chrome谷歌浏览器扩展(部分火狐、edge浏览器商店也可以用)
42 0
|
9月前
selenium--浏览器窗口截图
selenium--浏览器窗口截图
|
4月前
|
Web App开发 存储 前端开发
Chrome 浏览器的隐身窗口(incognito window)功能解析
Chrome 浏览器的隐身窗口(incognito window)功能解析
115 0
|
10月前
|
存储 JavaScript 前端开发

热门文章

最新文章