[转载]IE浏览器整页截屏程序 – 卡卡西村长 – 博客园.
最近项目中涉及到浏览器整页截屏的功能,有点复杂,研究了一天,终于在IE浏览器下实现,至于其他浏览器,以后再研究。
所谓整页截屏,就是说把整个页面全部截进去,包括通过滚动才能看到的部分。
在网上搜了一下,大家用的都是同一种办法:通过滚动页面,截取每一屏的图片,然后再合并成一张整的图片。
方法是好的,悲催的是,没有一个代码是能正常运行的,相信很多人都有同感!没办法,自己动手,丰衣足食。
我需要用.NET来实现。分析一下,主要有以下几个技术点:
1、如何取得浏览器对象。首先要确定IE版本,我用的是IE8浏览器,对象结构和IE6、IE7有点区别。这个可以通过Win32API中的FindWindow函数来实现。
2、对指定控件截屏。这个可以通过Win32API中的PrintWindow函数来实现,这个函数有一个优点:即使浏览器被其它窗口挡住,也可以正常截屏。但是,如果浏览器窗口最小化了,那就漆黑一片了。。。
3、合并图片。这个用GDI+可以很方便地实现。在内存中创建一个大的画布,然后将图片从上至下依次画上去即可。
开始动手。
首先,创建一个Console应用程序(用Form程序也没关系)。
(1)添加对System.Drawing和System.Windows.Forms的引用。
(2)添加对两个COM组件的引用:SHDocVw、MSHTML,并设置属性“嵌入互操作类型”为False(这个很重要,否则无法接下来的程序无法编译通过)。
(3)将程序入口Main方法标记为[STAThread](这个也很重要,否则接下来的程序会运行失败)。
然后,加入Win32API类,该类对几个重要的API进行了封装,接下来我们会用到这些API。代码如下:
<span class = "kwd" > using </span><span class = "pln" > </span><span class = "typ" >System</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > using </span><span class = "pln" > </span><span class = "typ" >System</span><span class = "pun" >.</span><span class = "typ" >Runtime</span><span class = "pun" >.</span><span class = "typ" >InteropServices</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > namespace </span><span class = "pln" > </span><span class = "typ" >IECapture</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "com" > /// <summary></span><span class="pln"> </span><span class = "com" > /// Win32API封装类。</span><span class="pln"> </span><span class = "com" > /// </summary></span><span class="pln"> </span><span class = "kwd" > internal </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > class </span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "com" > //User32</span><span class="pln"> </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "User32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > </span><span class = "typ" >FindWindow</span><span class = "pun" >(</span><span class = "kwd" > string </span><span class = "pln" > lpClassName</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > string </span><span class = "pln" > lpWindowName</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "user32.dll" </span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >SetLastError</span><span class = "pln" > </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > true </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > </span><span class = "typ" >FindWindowEx</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > parentHandle</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > childAfter</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > string </span><span class = "pln" > className</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > windowTitle</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "user32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > </span><span class = "typ" >GetWindowRect</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hWnd</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > ref </span><span class = "pln" > RECT rect</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "user32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > </span><span class = "typ" >GetWindowDC</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hWnd</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "User32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "kwd" > bool </span><span class = "pln" > </span><span class = "typ" >PrintWindow</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hwnd</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > hdcBlt</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > nFlags</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "com" > //gdi32</span><span class="pln"> </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "gdi32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "kwd" > bool </span><span class = "pln" > </span><span class = "typ" >BitBlt</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hObject</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > nXDest</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > nYDest</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > nWidth</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > nHeight</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > hObjectSource</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > nXSrc</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > nYSrc</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > dwRop</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "gdi32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > </span><span class = "typ" >CreateCompatibleBitmap</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hDC</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > nWidth</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > nHeight</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "gdi32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > </span><span class = "typ" >CreateCompatibleDC</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hDC</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "gdi32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "kwd" > bool </span><span class = "pln" > </span><span class = "typ" >DeleteDC</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hDC</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "gdi32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "kwd" > bool </span><span class = "pln" > </span><span class = "typ" >DeleteObject</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hObject</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >[</span><span class = "typ" >DllImport</span><span class = "pun" >(</span><span class = "str" > "gdi32.dll" </span><span class = "pun" >)]</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > extern </span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > </span><span class = "typ" >SelectObject</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hDC</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > hObject</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > struct </span><span class = "pln" > RECT </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > left</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > top</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > right</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > bottom</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span> |
最后,加入主程序。代码逻辑如下:
(1)获取当前IE浏览器对象。
(2)获取浏览器核心控件的矩形区域,计算整个页面一共有多少屏。
(3)通过滚动窗口的方式,对每一屏的页面进行截屏。
(4)将所有图片合并为一张整的图片。
主程序的源代码如下:
<span class = "kwd" > using </span><span class = "pln" > </span><span class = "typ" >System</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > using </span><span class = "pln" > </span><span class = "typ" >System</span><span class = "pun" >.</span><span class = "typ" >Collections</span><span class = "pun" >.</span><span class = "typ" >Generic</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > using </span><span class = "pln" > </span><span class = "typ" >System</span><span class = "pun" >.</span><span class = "typ" >Linq</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > using </span><span class = "pln" > </span><span class = "typ" >System</span><span class = "pun" >.</span><span class = "typ" >Drawing</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > using </span><span class = "pln" > </span><span class = "typ" >System</span><span class = "pun" >.</span><span class = "typ" >Windows</span><span class = "pun" >.</span><span class = "typ" >Forms</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > namespace </span><span class = "pln" > </span><span class = "typ" >IECapture</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > class </span><span class = "pln" > </span><span class = "typ" >Program</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "com" > //必须指定COM线程模型为单线程</span><span class="pln"> </span><span class = "pun" >[</span><span class = "typ" >STAThread</span><span class = "pun" >]</span><span class = "pln" > </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > </span><span class = "typ" >Main</span><span class = "pun" >(</span><span class = "kwd" > string </span><span class = "pun" >[]</span><span class = "pln" > args</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "com" > //获取浏览器对象</span><span class="pln"> </span><span class = "typ" >SHDocVw</span><span class = "pun" >.</span><span class = "typ" >ShellWindows</span><span class = "pln" > shellWindows </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >SHDocVw</span><span class = "pun" >.</span><span class = "typ" >ShellWindowsClass</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > var </span><span class = "pln" > webBrowser </span><span class = "pun" >=</span><span class = "pln" > shellWindows</span><span class = "pun" >.</span><span class = "typ" >Cast</span><span class = "pun" ><</span><span class = "typ" >SHDocVw</span><span class = "pun" >.</span><span class = "typ" >WebBrowser</span><span class = "pun" >>().</span><span class = "typ" >FirstOrDefault</span><span class = "pun" >(</span><span class = "pln" >c </span><span class = "pun" >=></span><span class = "pln" > c</span><span class = "pun" >.</span><span class = "typ" >Name</span><span class = "pln" > </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "str" > "Windows Internet Explorer" </span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >webBrowser </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "typ" >Console</span><span class = "pun" >.</span><span class = "typ" >WriteLine</span><span class = "pun" >(</span><span class = "str" > "当前未打开任何IE浏览器" </span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Console</span><span class = "pun" >.</span><span class = "typ" >ReadLine</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "com" > //查找浏览器核心控件</span><span class="pln"> </span><span class = "typ" >IntPtr</span><span class = "pln" > childHandle1 </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >FindWindowEx</span><span class = "pun" >(</span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >(</span><span class = "pln" >webBrowser</span><span class = "pun" >.</span><span class = "pln" >HWND</span><span class = "pun" >),</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "str" > "Frame Tab" </span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > childHandle2 </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >FindWindowEx</span><span class = "pun" >(</span><span class = "pln" >childHandle1</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "str" > "TabWindowClass" </span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > childHandle3 </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >FindWindowEx</span><span class = "pun" >(</span><span class = "pln" >childHandle2</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "str" > "Shell DocObject View" </span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > childHandle4 </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >FindWindowEx</span><span class = "pun" >(</span><span class = "pln" >childHandle3</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "str" > "Internet Explorer_Server" </span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >childHandle4 </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "typ" >Console</span><span class = "pun" >.</span><span class = "typ" >WriteLine</span><span class = "pun" >(</span><span class = "str" > "当前未打开任何IE浏览器" </span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Console</span><span class = "pun" >.</span><span class = "typ" >ReadLine</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "com" > //获取浏览器核心控件的矩形区域</span><span class="pln"> </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "pln" >RECT rc </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "pln" >RECT</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >GetWindowRect</span><span class = "pun" >(</span><span class = "pln" >childHandle4</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > ref </span><span class = "pln" > rc</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > pageHeight </span><span class = "pun" >=</span><span class = "pln" > rc</span><span class = "pun" >.</span><span class = "pln" >bottom </span><span class = "pun" >-</span><span class = "pln" > rc</span><span class = "pun" >.</span><span class = "pln" >top</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "com" > //获取HTML文档对象</span><span class="pln"> mshtml</span><span class = "pun" >.</span><span class = "typ" >IHTMLDocument2</span><span class = "pln" > htmlDoc </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >mshtml</span><span class = "pun" >.</span><span class = "typ" >IHTMLDocument2</span><span class = "pun" >)</span><span class = "pln" >webBrowser</span><span class = "pun" >.</span><span class = "typ" >Document</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "com" > //计算总共有多少页,以及最后一页的高度</span><span class="pln"> </span><span class = "kwd" > int </span><span class = "pln" > pageCount </span><span class = "pun" >=</span><span class = "pln" > htmlDoc</span><span class = "pun" >.</span><span class = "pln" >body</span><span class = "pun" >.</span><span class = "pln" >offsetHeight </span><span class = "pun" >/</span><span class = "pln" > pageHeight</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > lastPageHeight </span><span class = "pun" >=</span><span class = "pln" > htmlDoc</span><span class = "pun" >.</span><span class = "pln" >body</span><span class = "pun" >.</span><span class = "pln" >offsetHeight </span><span class = "pun" >%</span><span class = "pln" > pageHeight</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >lastPageHeight </span><span class = "pun" >></span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >)</span><span class = "pln" > pageCount</span><span class = "pun" >++;</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > scrollBarWidth </span><span class = "pun" >=</span><span class = "pln" > pageCount </span><span class = "pun" >></span><span class = "pln" > </span><span class = "lit" >1</span><span class = "pln" > </span><span class = "pun" >?</span><span class = "pln" > </span><span class = "typ" >SystemInformation</span><span class = "pun" >.</span><span class = "typ" >VerticalScrollBarWidth</span><span class = "pln" > </span><span class = "pun" >:</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "com" > //图片列表,用于放置每一屏的截图</span><span class="pln"> </span><span class = "typ" >List</span><span class = "pun" ><</span><span class = "typ" >Image</span><span class = "pun" >></span><span class = "pln" > pageImages </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >List</span><span class = "pun" ><</span><span class = "typ" >Image</span><span class = "pun" >>();</span><span class = "pln" > </span><span class = "com" > //一页一页地滚动截图</span><span class="pln"> htmlDoc</span><span class = "pun" >.</span><span class = "pln" >parentWindow</span><span class = "pun" >.</span><span class = "pln" >scrollTo</span><span class = "pun" >(</span><span class = "lit" >0</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > for </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "kwd" > int </span><span class = "pln" > pageIndex </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >;</span><span class = "pln" > pageIndex </span><span class = "pun" ><</span><span class = "pln" > pageCount</span><span class = "pun" >;</span><span class = "pln" > pageIndex</span><span class = "pun" >++)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > using </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >Image</span><span class = "pln" > image </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >CaptureWindow</span><span class = "pun" >(</span><span class = "pln" >childHandle4</span><span class = "pun" >))</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "com" > //去掉边框,以及垂直滚动条的宽度</span><span class="pln"> </span><span class = "typ" >Rectangle</span><span class = "pln" > innerRect </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Rectangle</span><span class = "pun" >(</span><span class = "lit" >2</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "lit" >2</span><span class = "pun" >,</span><span class = "pln" > image</span><span class = "pun" >.</span><span class = "typ" >Width</span><span class = "pln" > </span><span class = "pun" >-</span><span class = "pln" > scrollBarWidth </span><span class = "pun" >-</span><span class = "pln" > </span><span class = "lit" >4</span><span class = "pun" >,</span><span class = "pln" > image</span><span class = "pun" >.</span><span class = "typ" >Height</span><span class = "pln" > </span><span class = "pun" >-</span><span class = "pln" > </span><span class = "lit" >4</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >pageCount </span><span class = "pun" >></span><span class = "pln" > </span><span class = "lit" >1</span><span class = "pln" > </span><span class = "pun" >&&</span><span class = "pln" > pageIndex </span><span class = "pun" >==</span><span class = "pln" > pageCount </span><span class = "pun" >-</span><span class = "pln" > </span><span class = "lit" >1</span><span class = "pln" > </span><span class = "pun" >&&</span><span class = "pln" > lastPageHeight </span><span class = "pun" >></span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >)</span><span class = "pln" > innerRect </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Rectangle</span><span class = "pun" >(</span><span class = "lit" >2</span><span class = "pun" >,</span><span class = "pln" > pageHeight </span><span class = "pun" >-</span><span class = "pln" > lastPageHeight </span><span class = "pun" >+</span><span class = "pln" > </span><span class = "lit" >2</span><span class = "pun" >,</span><span class = "pln" > image</span><span class = "pun" >.</span><span class = "typ" >Width</span><span class = "pln" > </span><span class = "pun" >-</span><span class = "pln" > scrollBarWidth </span><span class = "pun" >-</span><span class = "pln" > </span><span class = "lit" >4</span><span class = "pun" >,</span><span class = "pln" > lastPageHeight </span><span class = "pun" >-</span><span class = "pln" > </span><span class = "lit" >4</span><span class = "pun" >);</span><span class = "pln" > pageImages</span><span class = "pun" >.</span><span class = "typ" >Add</span><span class = "pun" >(</span><span class = "typ" >GetImageByRect</span><span class = "pun" >(</span><span class = "pln" >image</span><span class = "pun" >,</span><span class = "pln" > innerRect</span><span class = "pun" >));</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > htmlDoc</span><span class = "pun" >.</span><span class = "pln" >parentWindow</span><span class = "pun" >.</span><span class = "pln" >scrollBy</span><span class = "pun" >(</span><span class = "lit" >0</span><span class = "pun" >,</span><span class = "pln" > pageHeight</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "com" > //拼接所有图片</span><span class="pln"> </span><span class = "typ" >Image</span><span class = "pln" > fullImage </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >MergeImages</span><span class = "pun" >(</span><span class = "pln" >pageImages</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >fullImage </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "typ" >Console</span><span class = "pun" >.</span><span class = "typ" >WriteLine</span><span class = "pun" >(</span><span class = "str" > "截屏失败,未获得任何图片" </span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Console</span><span class = "pun" >.</span><span class = "typ" >ReadLine</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "com" > //将截屏图片保存到指定目录</span><span class="pln"> </span><span class = "kwd" > try </span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > string </span><span class = "pln" > fileName </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "pun" >@</span><span class = "str" > "c:\IE整屏截图.png" </span><span class = "pun" >;</span><span class = "pln" > fullImage</span><span class = "pun" >.</span><span class = "typ" >Save</span><span class = "pun" >(</span><span class = "pln" >fileName</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Console</span><span class = "pun" >.</span><span class = "typ" >WriteLine</span><span class = "pun" >(</span><span class = "str" > "截屏成功,图片位置:" </span><span class = "pln" > </span><span class = "pun" >+</span><span class = "pln" > fileName</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > finally </span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > fullImage</span><span class = "pun" >.</span><span class = "typ" >Dispose</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "typ" >Console</span><span class = "pun" >.</span><span class = "typ" >ReadLine</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "com" > /// <summary></span><span class="pln"> </span><span class = "com" > /// 合并图片。</span><span class="pln"> </span><span class = "com" > /// </summary></span><span class="pln"> </span><span class = "com" > /// <param name="imageList">图片列表。</param></span><span class="pln"> </span><span class = "com" > /// <returns>合并后的图片。</returns></span><span class="pln"> </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "typ" >Image</span><span class = "pln" > </span><span class = "typ" >MergeImages</span><span class = "pun" >(</span><span class = "typ" >List</span><span class = "pun" ><</span><span class = "typ" >Image</span><span class = "pun" >></span><span class = "pln" > imageList</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >imageList </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pln" > </span><span class = "pun" >||</span><span class = "pln" > imageList</span><span class = "pun" >.</span><span class = "typ" >Count</span><span class = "pln" > </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >imageList</span><span class = "pun" >.</span><span class = "typ" >Count</span><span class = "pln" > </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "lit" >1</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > imageList</span><span class = "pun" >[</span><span class = "lit" >0</span><span class = "pun" >];</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > pageWidth </span><span class = "pun" >=</span><span class = "pln" > imageList</span><span class = "pun" >[</span><span class = "lit" >0</span><span class = "pun" >].</span><span class = "typ" >Width</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > totalPageHeight </span><span class = "pun" >=</span><span class = "pln" > imageList</span><span class = "pun" >.</span><span class = "typ" >Sum</span><span class = "pun" >(</span><span class = "pln" >c </span><span class = "pun" >=></span><span class = "pln" > c</span><span class = "pun" >.</span><span class = "typ" >Height</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Bitmap</span><span class = "pln" > fullImage </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Bitmap</span><span class = "pun" >(</span><span class = "pln" >pageWidth</span><span class = "pun" >,</span><span class = "pln" > totalPageHeight</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > using </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >Graphics</span><span class = "pln" > g </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Graphics</span><span class = "pun" >.</span><span class = "typ" >FromImage</span><span class = "pun" >(</span><span class = "pln" >fullImage</span><span class = "pun" >))</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > y </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > for </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "kwd" > int </span><span class = "pln" > i </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >;</span><span class = "pln" > i </span><span class = "pun" ><</span><span class = "pln" > imageList</span><span class = "pun" >.</span><span class = "typ" >Count</span><span class = "pun" >;</span><span class = "pln" > i</span><span class = "pun" >++)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > g</span><span class = "pun" >.</span><span class = "typ" >DrawImageUnscaled</span><span class = "pun" >(</span><span class = "pln" >imageList</span><span class = "pun" >[</span><span class = "pln" >i</span><span class = "pun" >],</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >,</span><span class = "pln" > y</span><span class = "pun" >,</span><span class = "pln" > imageList</span><span class = "pun" >[</span><span class = "pln" >i</span><span class = "pun" >].</span><span class = "typ" >Width</span><span class = "pun" >,</span><span class = "pln" > imageList</span><span class = "pun" >[</span><span class = "pln" >i</span><span class = "pun" >].</span><span class = "typ" >Height</span><span class = "pun" >);</span><span class = "pln" > y </span><span class = "pun" >+=</span><span class = "pln" > imageList</span><span class = "pun" >[</span><span class = "pln" >i</span><span class = "pun" >].</span><span class = "typ" >Height</span><span class = "pun" >;</span><span class = "pln" > imageList</span><span class = "pun" >[</span><span class = "pln" >i</span><span class = "pun" >].</span><span class = "typ" >Dispose</span><span class = "pun" >();</span><span class = "com" > //释放图片资源</span><span class="pln"> </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > fullImage</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "com" > /// <summary></span><span class="pln"> </span><span class = "com" > /// 获取图片的指定区域。</span><span class="pln"> </span><span class = "com" > /// </summary></span><span class="pln"> </span><span class = "com" > /// <param name="image">原始图片。</param></span><span class="pln"> </span><span class = "com" > /// <param name="rect">目标区域。</param></span><span class="pln"> </span><span class = "com" > /// <returns></returns></span><span class="pln"> </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "typ" >Image</span><span class = "pln" > </span><span class = "typ" >GetImageByRect</span><span class = "pun" >(</span><span class = "typ" >Image</span><span class = "pln" > image</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >Rectangle</span><span class = "pln" > rect</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >image </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pln" > </span><span class = "pun" >||</span><span class = "pln" > rect</span><span class = "pun" >.</span><span class = "typ" >IsEmpty</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > image</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "typ" >Bitmap</span><span class = "pln" > bitmap </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Bitmap</span><span class = "pun" >(</span><span class = "pln" >rect</span><span class = "pun" >.</span><span class = "typ" >Width</span><span class = "pun" >,</span><span class = "pln" > rect</span><span class = "pun" >.</span><span class = "typ" >Height</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > using </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >Graphics</span><span class = "pln" > g </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Graphics</span><span class = "pun" >.</span><span class = "typ" >FromImage</span><span class = "pun" >(</span><span class = "pln" >bitmap</span><span class = "pun" >))</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > g</span><span class = "pun" >.</span><span class = "typ" >DrawImage</span><span class = "pun" >(</span><span class = "pln" >image</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >,</span><span class = "pln" > rect</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "typ" >GraphicsUnit</span><span class = "pun" >.</span><span class = "typ" >Pixel</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > bitmap</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "com" > /// <summary></span><span class="pln"> </span><span class = "com" > /// 为指定窗口或控件截屏。</span><span class="pln"> </span><span class = "com" > /// </summary></span><span class="pln"> </span><span class = "com" > /// <param name="hWnd">句柄。</param></span><span class="pln"> </span><span class = "com" > /// <returns>截屏图片。</returns></span><span class="pln"> </span><span class = "kwd" > static </span><span class = "pln" > </span><span class = "typ" >Image</span><span class = "pln" > </span><span class = "typ" >CaptureWindow</span><span class = "pun" >(</span><span class = "typ" >IntPtr</span><span class = "pln" > hWnd</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > hscrdc </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >GetWindowDC</span><span class = "pun" >(</span><span class = "pln" >hWnd</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >hscrdc </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pun" >.</span><span class = "typ" >Zero</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > </span><span class = "kwd" > null </span><span class = "pun" >;</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "pln" >RECT windowRect </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "pln" >RECT</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >GetWindowRect</span><span class = "pun" >(</span><span class = "pln" >hWnd</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "kwd" > ref </span><span class = "pln" > windowRect</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > width </span><span class = "pun" >=</span><span class = "pln" > windowRect</span><span class = "pun" >.</span><span class = "pln" >right </span><span class = "pun" >-</span><span class = "pln" > windowRect</span><span class = "pun" >.</span><span class = "pln" >left</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > int </span><span class = "pln" > height </span><span class = "pun" >=</span><span class = "pln" > windowRect</span><span class = "pun" >.</span><span class = "pln" >bottom </span><span class = "pun" >-</span><span class = "pln" > windowRect</span><span class = "pun" >.</span><span class = "pln" >top</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > hbitmap </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >CreateCompatibleBitmap</span><span class = "pun" >(</span><span class = "pln" >hscrdc</span><span class = "pun" >,</span><span class = "pln" > width</span><span class = "pun" >,</span><span class = "pln" > height</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >IntPtr</span><span class = "pln" > hmemdc </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >CreateCompatibleDC</span><span class = "pun" >(</span><span class = "pln" >hscrdc</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >SelectObject</span><span class = "pun" >(</span><span class = "pln" >hmemdc</span><span class = "pun" >,</span><span class = "pln" > hbitmap</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >PrintWindow</span><span class = "pun" >(</span><span class = "pln" >hWnd</span><span class = "pun" >,</span><span class = "pln" > hmemdc</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "lit" >0</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Image</span><span class = "pln" > bmp </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >Image</span><span class = "pun" >.</span><span class = "typ" >FromHbitmap</span><span class = "pun" >(</span><span class = "pln" >hbitmap</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >DeleteDC</span><span class = "pun" >(</span><span class = "pln" >hscrdc</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Win32API</span><span class = "pun" >.</span><span class = "typ" >DeleteDC</span><span class = "pun" >(</span><span class = "pln" >hmemdc</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > return </span><span class = "pln" > bmp</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span> |
【总结】
要想写一个好的整页截屏程序,还是很困难的。就拿本文的程序来说,就存在以下几点不足之处:
(1)仅在IE8浏览器上测试通过,无法在FireFox、Chrome上运行。即使同是IE家族的IE6、IE7、IE9,我也不敢保证能正常运行,各位同学可以测试一下,并尝试修改,欢迎交流。
(2)如果有浮动DIV随着页面一起滚动,在每一屏上都会被截屏。
(3)未考虑水平滚动条的影响。
(4)未考虑在多线程环境下的应用。