转自:http://www.cnblogs.com/IceAir/archive/2011/04/11/2012744.html

对IE进行编程一直觉得是相当可怕的事情,里面的接口、函数、事件之多,解释之乱,需要了解的方方面面知识之博,让我仿佛看到了微软就是造物主,因为它已成功制造了这样的混沌,弄就了宇宙的初始状态……

近来做个项目,要截取网页,试了获取mht,开始倒是成功了,但不知装了什么软件后,就再也无法保存成mht了,查了一堆资料,修复了一轮,又可以部份保存成功,如此不稳定肯定不能应用,放弃!不得不赞的是,网文快捕的保存网页的插件的确是精品,成功率很高,不知在后面作者做了多少工作,可惜作者没有作为接口提供。于是决定还是截网页为图片,同时获取其中文字保存用于查询的方式,经过几日无数查找资料尝试,在终于崩溃之前,玉帝可怜我,终于让我成功,一直以来从网上众人文章中获益良多,赶快贴出来给不知多少像我这样可怜的人。

首先,声名使用到的文件、用于获取IE WebBrowse实例的函数名、获取窗口图像的函数名:

uses ComObj,shDocvw,MSHtml,OleCtrls,jpeg,ActiveX;TObjectFromLResult = function(LRESULT: lResult; const IID: TIID;WPARAM: wParam; out pObject): HRESULT; stdcall;//获取窗口图像的,非常好用啊,就算窗口被挡着、隐藏都能获取到
function PrintWindow(SourceWindow: hwnd; Destination: hdc; nFlags: cardinal): bool; stdcall; external 'user32.dll' name 'PrintWindow';

获取IE实例及截图核心代码:

//获取IE实例,wHandle为IE的句柄,这段代码网上抄来,向作者致谢!
//wHandle可通过WindowFromPoint(GetCursorPos(pt))获得,获取的办法网上一搜一大堆了。
function GetIEFromHWND(wHandle: HWND; var IE: IWebbrowser2): HRESULT;
varhInst: HWND;lRes: Cardinal;MSG: Integer;pDoc: IHTMLDocument2;ObjectFromLresult: TObjectFromLresult;
beginhInst := LoadLibrary('Oleacc.dll');@ObjectFromLresult := GetProcAddress(hInst, 'ObjectFromLresult');if @ObjectFromLresult <> nil thenbegintryMSG := RegisterWindowMessage('WM_HTML_GETOBJECT');SendMessageTimeOut(WHandle, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes);Result := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);if Result = S_OK then(pDoc.parentWindow as IServiceprovider).QueryService(IWebbrowserApp,IWebbrowser2, IE);finallyFreeLibrary(hInst);pDoc := nil;end;end;
end;{指定IE窗口句柄,滚动获取整个网页图片
此函数执行完后能把IE原来滚动条位置复原,听起来这事很简单,找资料却是找到傻了云!如果网页有D3D这种东东的话,网上说的getAttribute('scrollTop', 0)什么的就用不了,弄得很辛苦的。
}
procedure SaveWebPic(hIEHandle: Integer; webJpg: TJPEGImage);
varrect: TRect;webBmp: TBitMap;i, j, webTop, webLeft, tLeft, tTop: integer;ht, vt: array of Integer;ie: IWebbrowser2;iDoc: IHTMLDocument2;vElement: IHTMLElement2;procedure CaptureWeb(destBmp: TBitmap; destLeft, destTop, width, height: Integer);vartemBmp: TBitmap;begintemBmp := TBitMap.Create();temBmp.Height := height+2;temBmp.Width := width+2;PrintWindow(hIEHandle, temBmp.Canvas.Handle, 0);BitBlt(destBmp.Canvas.Handle, destLeft, destTop, destLeft+width, destTop+height, temBmp.Canvas.Handle, 2, 2, SRCCOPY);temBmp.Free;end;
beginif not Assigned(webJpg) thenExit;if GetIEFromHWND(hIEHandle, ie) <> S_OK thenExit;iDoc := ie.Document as IHTMLDocument2;webBmp := TBitMap.Create();webBmp.PixelFormat := pf24bit;try//temCanvas.Handle := GetDC(hIEHandle);iDoc.body.setAttribute('scroll', 'yes', 0);//保存原来滚动条位置vElement := (iDoc as IHTMLDocument3).documentElement as IHTMLElement2;if not Assigned(vElement) thenvElement := iDoc.Body as IHTMLElement2;tTop := vElement.scrollTop;tLeft := vElement.scrollLeft;//获得网页的大小webBmp.Height := vElement.scrollHeight;//iDoc.Body.getAttribute('scrollHeight', 0);webBmp.Width := vElement.scrollWidth;//iDoc.Body.getAttribute('scrollwidth', 0);//获得显示网页的窗口大小
//    windows.GetClientRect(hIEHandle, rect);
//    rect.Bottom := rect.Bottom - GetSystemMetrics(SM_CXHSCROLL) - GetSystemMetrics(SM_CXDLGFRAME);
//    rect.Right := rect.Right - GetSystemMetrics(SM_CXVSCROLL) - GetSystemMetrics(SM_CXDLGFRAME);rect.Right := vElement.clientWidth;rect.Bottom := vElement.clientHeight;//计算纵向和横向每次截取时,截取的高度、宽度//网页的截取办法是去零传凑整,如窗口的高度是H,而网页的高度是WH,可先//截取WH-H部份,剩下通过循环按H截取SetLength(vt, webBmp.Height div rect.Bottom + 1);SetLength(ht, webBmp.Width div rect.Right + 1);vt[0] := webBmp.Height - (webBmp.Height div rect.Bottom) * rect.Bottom;ht[0] := webBmp.Width - (webBmp.Width div rect.Right) * rect.Right;for i:=1 to Length(vt)-1 dovt[i] := rect.Bottom;for i:=1 to Length(ht)-1 doht[i] := rect.Right;webLeft := 0;for i:=0 to Length(ht)-1 do beginwebTop := 0;                   iDoc.Get_ParentWindow.Scroll(webLeft, webTop);for j:=0 to Length(vt)-1 do beginCaptureWeb(webBmp, webLeft, webTop, ht[i], vt[j]);webTop := webTop + vt[j];iDoc.Get_ParentWindow.Scroll(webLeft, webTop);end;webLeft := webLeft + ht[i];end;webJpg.Assign(webBmp);webJpg.SaveToFile('z:\demo.jpg');finallywebBmp.Free;SetLength(vt, 0);SetLength(ht, 0);iDoc.Get_ParentWindow.Scroll(tLeft, tTop);end;
end;

保存网页为图片——滚动截取IE(WebBrowse)相关推荐

  1. 网页特效——图片翻页和图片滚动的实现方法

    1. 图片翻页特效: 效果:多张图片逐个翻页显示,也可用鼠标点击图片区域下方的页码手动翻页.每张图片上都可添加链接引向不同位置的帖子. 演示:在专刊盛世奥运之奢华盘点上半部分中间"华美谢幕& ...

  2. Android高级图片滚动控件,编写3D版的图片轮播器

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17482089 大家好,好久不见了,最近由于工作特别繁忙,已经有一个多月的时间没写博 ...

  3. selenium+python实现1688网站验证码图片的截取

    selenium+python实现1688网站验证码图片的截取 1. 背景 在1688网站爬取数据时,如果访问过于频繁,无论用户是否已经登录,就会弹出如下所示的验证码登录框. 一般的验证码是类似于如下 ...

  4. JS+CSS控制左右切换鼠标可控的无缝图片滚动代码

    代码简介: 以前见过这种效果,但是是基于FLASH技术,现在是纯用JS实现的,代码有点多,不过效果还不错,实际上它也是一个图片滚动,只不过它完全是用鼠标点击控制的,也就是说鼠标不点击的时候它是静止的, ...

  5. jquery实现多行文字图片滚动效果

    基于jquery的实现多行文字图片滚动的效果代码,如果我们在论坛公告等等这些实例了,下面我来给各位朋友介绍介绍. 1 <div id="scrollDiv"> 2 &l ...

  6. dw按钮图片滚动js_使用 React Hooks 实现仿石墨的图片预览插件(巨详细)

    点击上方"前端教程",选择"星标" 每天前端开发干货第一时间送达! 作者:DARRELL https://juejin.im/post/5e9bf299f265 ...

  7. jQuery 图片滚动效果

    2019独角兽企业重金招聘Python工程师标准>>> 使用了网上的一个JS插件,配置起来相当灵活好用,效果如下: 下面整理下使用的过程: 1.在插件网站http://www.gma ...

  8. 原生JS实现图片滚动

    2019独角兽企业重金招聘Python工程师标准>>> 原生JS实现图片滚动 一.原理 黑色盒子是最终显示滚动图像的区域,绿色盒子为其子容器,其宽度要大于黑色外层盒子,这样才能通过设 ...

  9. 导入图片后截取_微服务项目第36天:导入数据到索引库

    今天是刘小爱自学Java的第166天. 感谢你的观看,谢谢你. 学习计划安排,导入需要的数据到索引库: 对于all字段的拼接. spu中附带的skus集合. sku中对应的price. specs规格 ...

  10. php图片左右滚动代码怎么写,css图片滚动代码怎么写?轮播图横向滚动展示

    在日常工作中网页上的轮播图展示必不可少,那么对于刚入门的小白而言本篇文章关于css图片滚动代码的介绍更是浅显易懂.希望本篇文章对大家有所帮助. css图片滚动代码示例具体如下: css图片滚动代码示例 ...

最新文章

  1. libcurl使用多线程下载大文件源码示例!
  2. 这个新型AI电子器件没有硅!北航32岁教授共同一作,能模拟大脑神经元,还登上了Science...
  3. linux 国内 NTP时间服务器地址
  4. typescript 方法后面加感叹号_使用 TypeScript 模板字面类型
  5. mciSendString用法
  6. 为什么居住的地方离上班的地方很远
  7. 生命游戏(Game of Life)描述
  8. 我好像明白了如何画序列图了
  9. java 指针 地址压缩_JVM优化之压缩普通对象指针(CompressedOops)
  10. 神经网络中的感受野(Receptive Field)
  11. 使用WUCDCreator将SCSI、RAID、SATA、SAS驱动程序集成到光盘中
  12. 如何在OTN网站下载Grid方法(Oracle RAC)
  13. linux安装ADS软件,Ubuntu 10.10下安装ADS 2009 Update1
  14. 从零开始设计RISC-V处理器——指令系统
  15. 金蝶云星空API调用实践
  16. OneNet平台创建应用
  17. OptaPlanner快速开始
  18. python批量添加姓名生成奖状批量处理图片教师学生奖状
  19. Shader 漫反射
  20. 丽荣葵花——从吴忠走向全国

热门文章

  1. C#,数值计算,希尔伯特矩阵(Hilbert Matrix)的算法与源代码
  2. mysql 3306端口入侵_3306端口入侵流程
  3. 通过在群晖上安装虚拟机,实现群晖与115网盘的双向同步
  4. 全国计算机等级考试wps视频,全国计算机等级考试一级WPS-Office
  5. DirectX11--HR宏关于dxerr库的替代方案
  6. 如何在linux上运行asp网站,linux上搭建asp网站
  7. 医院计算机管理办法试行,医院信息工作制度七、计算机中心机房管理制度
  8. 二级vb计算机考试试题,全国计算机vb二级考试真题
  9. 基于FPGA的交通灯设计
  10. 利用matlab实现h 控制,利用matlab实现H-infinity鲁棒控制.doc