浏览器扩展系列————透明浏览器窗口的实现
首先先看一下效果圖:
??? 本實(shí)現(xiàn)是基于WPF,VS版本2008 SP1。
??? 先說(shuō)一下在Winform中的實(shí)現(xiàn)方法:很簡(jiǎn)單通過(guò)設(shè)置窗體的opacity來(lái)實(shí)現(xiàn),或者還可以設(shè)置TransparentKey來(lái)實(shí)現(xiàn)某種顏色透明。但是在WPF中則如何實(shí)現(xiàn)呢?
通過(guò)設(shè)置窗體的opacity,那么得到結(jié)果就是webbrowser整體消失了。因?yàn)檫@里面涉及到WPF中“空域”的問(wèn)題,相關(guān)的文章如下:
http://blogs.msdn.com/changov/archive/2009/01/19/webbrowser-control-on-transparent-wpf-window.aspx
??? 由此看來(lái)通過(guò)直接設(shè)置透明度的方法是不行了,那么回到原來(lái)的問(wèn)題,“將瀏覽器窗體背景成透明”,其實(shí)這里的透明只是一個(gè)視覺(jué)上的感覺(jué),就是瀏覽器中網(wǎng)頁(yè)的背景和整個(gè)窗體的背景想融合就可以。看到這里,各位看官可能已經(jīng)想到了,將瀏覽器中頁(yè)面的背景繪制成被瀏覽器控件所覆蓋出的背景就可以了。確實(shí),我的實(shí)現(xiàn)也是依照這種思路走的。
??? 這里主要用到了兩個(gè)技術(shù):
l?Mshtml操作網(wǎng)頁(yè)中元素,通過(guò)給body標(biāo)簽添加行為來(lái)實(shí)現(xiàn)背景的繪制。
?
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類用來(lái)給應(yīng)用程序截圖:
?
?
Codeinternal?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;
????????}
在截圖的時(shí)候這里使用了一個(gè)技巧就是,先將控件隱藏,然后截圖,最后恢復(fù)控件的顯示。?
最后說(shuō)一下本實(shí)現(xiàn)的一些缺陷:
具體項(xiàng)目下載如下:
/Files/chinese-zmm/TransportWebBrowserDemo.rar?
?
轉(zhuǎn)載于:https://www.cnblogs.com/chinese-zmm/archive/2009/04/26/1444065.html
總結(jié)
以上是生活随笔為你收集整理的浏览器扩展系列————透明浏览器窗口的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Ajax 开发中遇到的乱码问题
- 下一篇: 背靠背指标