[转载]IE浏览器整页截屏程序

[转载]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)未考虑在多线程环境下的应用。

赞(0) 打赏
分享到: 更多 (0)

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

支付宝扫一扫打赏

微信扫一扫打赏

登录

注册