您的位置:首页 > 其它

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

2016-02-08 18:51 387 查看
转自:http://www.cnblogs.com/IceAir/archive/2011/04/11/2012744.html

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

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

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

[delphi] view plain copy

print?

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实例及截图核心代码:

[delphi] view plain copy

print?

//获取IE实例,wHandle为IE的句柄,这段代码网上抄来,向作者致谢!

//wHandle可通过WindowFromPoint(GetCursorPos(pt))获得,获取的办法网上一搜一大堆了。

function GetIEFromHWND(wHandle: HWND; var IE: IWebbrowser2): HRESULT;

var

hInst: HWND;

lRes: Cardinal;

MSG: Integer;

pDoc: IHTMLDocument2;

ObjectFromLresult: TObjectFromLresult;

begin

hInst := LoadLibrary('Oleacc.dll');

@ObjectFromLresult := GetProcAddress(hInst, 'ObjectFromLresult');

if @ObjectFromLresult <> nil then

begin

try

MSG := 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);

finally

FreeLibrary(hInst);

pDoc := nil;

end;

end;

end;

{指定IE窗口句柄,滚动获取整个网页图片

此函数执行完后能把IE原来滚动条位置复原,听起来这事很简单,找资料却是找到傻了云!如果网页有D3D这种东东的话,网上说的getAttribute('scrollTop', 0)什么的就用不了,弄得很辛苦的。

}

procedure SaveWebPic(hIEHandle: Integer; webJpg: TJPEGImage);

var

rect: 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);

var

temBmp: TBitmap;

begin

temBmp := 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;

begin

if not Assigned(webJpg) then

Exit;

if GetIEFromHWND(hIEHandle, ie) <> S_OK then

Exit;

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) then

vElement := 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 do

vt[i] := rect.Bottom;

for i:=1 to Length(ht)-1 do

ht[i] := rect.Right;

webLeft := 0;

for i:=0 to Length(ht)-1 do begin

webTop := 0;

iDoc.Get_ParentWindow.Scroll(webLeft, webTop);

for j:=0 to Length(vt)-1 do begin

CaptureWeb(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');

finally

webBmp.Free;

SetLength(vt, 0);

SetLength(ht, 0);

iDoc.Get_ParentWindow.Scroll(tLeft, tTop);

end;

end;
http://blog.csdn.net/tht2009/article/details/39736839
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: